如何构造 C++ Windows API 程序,例如 C# WinForms

发布于 2024-12-10 19:28:10 字数 724 浏览 0 评论 0原文

我是一名经验丰富的 GUI C# 程序员,并且对仅用于 CLI 的 C/C++ 有一些经验。

我正在使用 C++ 自学本机 Windows API。我能够创建带有按钮和输入字段等的窗口;单击按钮和键入文本等时执行操作。

但是,到目前为止我所做的一切都在单个 c 或 cpp 文件中,而不使用类。

在 C# 中,我将创建扩展 Form: 的类,

public class MyForm : Form { }

然后像这样打开它:

MyForm myForm = new MyForm();
myForm.ShowDialog();

or:

new MyForm().ShowDialog();

or:

Application.Run(new MyForm());

但是使用我的平面文件 c/cpp 方法,我只有一个 WinMain 来注册我的窗口类,创建窗口,消息循环就消失了。当我学习非常基础的知识时,这对于小程序来说并不可怕,但显然我希望把事情安排得更好一点,就像我在 C# 中所做的那样。

我还没有找到很多关于本机 Windows API 的教程或代码示例来展示这通常是如何完成的。

有人可以发布一些框架代码和/或链接到解释这通常是如何完成的教程吗?

I'm an experienced GUI C# programmer and have some experience with C/C++ for CLI only.

I'm teaching myself native Windows API using C++. I am able to create windows with buttons and input fields, etc; perform actions when buttons are clicked and text is typed, etc.

However, everything I've done so far has been in a single c or cpp file without using classes.

In C#, I would create classes which extend Form:

public class MyForm : Form { }

and then open it like this:

MyForm myForm = new MyForm();
myForm.ShowDialog();

or:

new MyForm().ShowDialog();

or:

Application.Run(new MyForm());

however using my flat-file c/cpp method I just have a WinMain which registers my window class, creates the window, and the message loop just churns away. It's not awful for small programs while I'm learning the very basics, but obviously I would want to have things laid out a little nicer like I do in C#.

I haven't found many tutorials or code samples for native Windows API that show how this is generally done.

Can someone please either post some skeleton code and/or link to a tutorial which explains how this is generally accomplished?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

睫毛上残留的泪 2024-12-17 19:28:10

我使用了自己的 Window 类,如下所示。这是我针对不同问题提出的回复,但您可能会发现这很有用。所以这里是:

#pragma once

#include <windows.h>
#include <process.h>
#include <iostream>

using namespace std;

static const char *g_AppName  = "Test";

class CMyWindow
{
    HWND  _hWnd;
    int _width;
    int _height;
public:
    CMyWindow(const int width,const int height):_hWnd(NULL),_width(width),_height(height)
    {
        _beginthread( &CMyWindow::thread_entry, 0, this);
    }

    ~CMyWindow(void)
    {
        SendMessage(_hWnd, WM_CLOSE, NULL, NULL);
    }


private:
    static void thread_entry(void * p_userdata)
    {
        CMyWindow * p_win = static_cast<CMyWindow*> (p_userdata);
        p_win->create_window();
        p_win->message_loop();
    }

    void create_window()
    {
        WNDCLASSEX wcex;

        wcex.cbSize         = sizeof(WNDCLASSEX);
        wcex.style          = CS_HREDRAW | CS_VREDRAW;
        wcex.lpfnWndProc    = &CMyWindow::WindowProc;
        wcex.cbClsExtra     = 0;
        wcex.cbWndExtra     = 0;
        wcex.hInstance      = GetModuleHandle(NULL);
        wcex.hIcon          = LoadIcon(NULL, IDI_APPLICATION);
        wcex.hCursor        = LoadCursor(NULL, IDC_ARROW);
        wcex.hbrBackground  = (HBRUSH)(COLOR_WINDOW+1);
        wcex.lpszMenuName   = NULL;
        wcex.lpszClassName  = g_AppName;
        wcex.hIconSm        = LoadIcon(NULL, IDI_APPLICATION);

        RegisterClassEx(&wcex);

        _hWnd = CreateWindow(g_AppName, g_AppName, WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, GetModuleHandle(NULL), NULL);

        ShowWindow(_hWnd, SW_SHOWDEFAULT);
        UpdateWindow(_hWnd);
    }

    void message_loop()
    {
        MSG msg = {0};

        while (GetMessage(&msg, NULL, 0, 0))
        {
            if(msg.message == WM_QUIT)
            {
                break;
            }

            TranslateMessage(&msg);
            DispatchMessage(&msg);
        }
    }

    static LRESULT WINAPI WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
    {
        switch(uMsg)
        {
        case WM_DESTROY:
            PostQuitMessage(0);
            return 0;
        case WM_POWERBROADCAST:
            {
                //power management code here
            }

        }

        return DefWindowProc(hWnd, uMsg, wParam, lParam);
    }
};

还要确保包括退出条件。

I have used my own Window class similar to what's shown below. This is a reply I poseted for a different question but you might find this useful. So here it is:

#pragma once

#include <windows.h>
#include <process.h>
#include <iostream>

using namespace std;

static const char *g_AppName  = "Test";

class CMyWindow
{
    HWND  _hWnd;
    int _width;
    int _height;
public:
    CMyWindow(const int width,const int height):_hWnd(NULL),_width(width),_height(height)
    {
        _beginthread( &CMyWindow::thread_entry, 0, this);
    }

    ~CMyWindow(void)
    {
        SendMessage(_hWnd, WM_CLOSE, NULL, NULL);
    }


private:
    static void thread_entry(void * p_userdata)
    {
        CMyWindow * p_win = static_cast<CMyWindow*> (p_userdata);
        p_win->create_window();
        p_win->message_loop();
    }

    void create_window()
    {
        WNDCLASSEX wcex;

        wcex.cbSize         = sizeof(WNDCLASSEX);
        wcex.style          = CS_HREDRAW | CS_VREDRAW;
        wcex.lpfnWndProc    = &CMyWindow::WindowProc;
        wcex.cbClsExtra     = 0;
        wcex.cbWndExtra     = 0;
        wcex.hInstance      = GetModuleHandle(NULL);
        wcex.hIcon          = LoadIcon(NULL, IDI_APPLICATION);
        wcex.hCursor        = LoadCursor(NULL, IDC_ARROW);
        wcex.hbrBackground  = (HBRUSH)(COLOR_WINDOW+1);
        wcex.lpszMenuName   = NULL;
        wcex.lpszClassName  = g_AppName;
        wcex.hIconSm        = LoadIcon(NULL, IDI_APPLICATION);

        RegisterClassEx(&wcex);

        _hWnd = CreateWindow(g_AppName, g_AppName, WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, GetModuleHandle(NULL), NULL);

        ShowWindow(_hWnd, SW_SHOWDEFAULT);
        UpdateWindow(_hWnd);
    }

    void message_loop()
    {
        MSG msg = {0};

        while (GetMessage(&msg, NULL, 0, 0))
        {
            if(msg.message == WM_QUIT)
            {
                break;
            }

            TranslateMessage(&msg);
            DispatchMessage(&msg);
        }
    }

    static LRESULT WINAPI WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
    {
        switch(uMsg)
        {
        case WM_DESTROY:
            PostQuitMessage(0);
            return 0;
        case WM_POWERBROADCAST:
            {
                //power management code here
            }

        }

        return DefWindowProc(hWnd, uMsg, wParam, lParam);
    }
};

Also make sure to include an exit condition.

流年已逝 2024-12-17 19:28:10

Windows API本身是C,而不是C++。

对于 C++,可能需要使用 MFC(不推荐)、托管 .NET(不是本机 C++)或其他几个库之一,例如 QT,以及全新的 Windows 运行时(Windows 8 附带)http://msdn.microsoft.com/en-us/library/windows/apps/hh464942%28v=vs.85%29.aspx)

Windows API itself is C, not C++.

For C++, may want to use MFC (not recommended), or managed .NET (not native C++) or one of several other libraries such as QT, as well as the brand new Windows Runtime (that comes with Windows 8 http://msdn.microsoft.com/en-us/library/windows/apps/hh464942%28v=vs.85%29.aspx)

若水微香 2024-12-17 19:28:10

如果您想研究一个作为 winapi 的简单 C++ 包装器存在的框架,请查看 WTL

If you want to study a framework that exists as a simple C++ wrapper for winapi, check out WTL.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文