c++ - 使用对象方法作为 WinApi WndProc 回调

标签 c++ oop class winapi

<分区>

我正在尝试制作一个在父窗口中显示控制台窗口的小类。 (你可以想象那里显示的聊天或调试信息)
现在,由于不同的实例确实有不同的私有(private)变量(例如消息数组或父窗口),我需要使用非静态方法作为 Windows 事件的回调。
我想到了一些方法,将实际的类实例传递给静态回调函数,然后对其调用适当的方法,但在 winAPI 中,一切都是使用 TranslateMessageDispatchMessage 让我没有机会使用自己的参数。
我在这里找到了一些代码:Class method as winAPI callback ,但我不明白,我认为这不是我所需要的。如果是,请给我进一步解释所提供的代码。
我得到的错误:

error: argument of type 'LRESULT (WindowConsole::)(HWND__, UINT, WPARAM, LPARAM)' does not match 'LRESULT (*)(HWND__, UINT, WPARAM, LPARAM)'

我不知道括号里的那颗星是什么意思,但这是不匹配的。
和代码:

class WindowConsole {
   char messages[255][255];
   HWND mainWindow;
   public:
     int width;
     int height;
     inline HWND create(HWND parent);
     inline bool update();
     inline LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM);
};

HWND WindowConsole::create(HWND parent) {
    HINSTANCE inst =  GetModuleHandle (0);
    WNDCLASSEX wincl;

    /* The Window structure */
    wincl.hInstance = inst;
    wincl.lpszClassName = "ConsoleClass";
    wincl.lpfnWndProc = this->WndProc;      /* This function is called by windows */
    /* more WNDCLASSEX crap...*/

    mainWindow = CreateWindow (
          /*PARAMS*/
    );
    ShowWindow(mainWindow,1);
    return mainWindow;

}
bool WindowConsole::update() {
   return true;
}
LRESULT CALLBACK WindowConsole::WndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) {
    switch (message)                  /* handle the messages */
    {
           /*EVENT crap*/
    }

    return 0;
}

最佳答案

通常是这个订单上的东西:

#include <windows.h>

class BaseWindow {

     static LRESULT CALLBACK internal_WndProc(HWND hWnd, int msg, WORD wParam, LONG lParam) {
        BaseWindow *c = (BaseWindow *)GetWindowLong(hWnd,GWLP_USERDATA);

        if (c == NULL)
            return DefWindowProc(hWnd, msg, wParam, lParam);

        return c->WindowProc(hWnd, msg, wParam, lParam);
    }

public:
    virtual int WindowProc(HWND hWnd, int msg, WPARAM wParam, LPARAM lParam) = 0;

    BaseWindow(HINSTANCE instance) {
        WNDCLASS window_class = {0};
        HWND window;
        HMENU my_menu;

        window_class.lpfnWndProc = (WNDPROC)internal_WndProc;
        /* fill in window_class here */
        RegisterClass(&window_class);

        window = CreateWindow(
            "My Application", "Stupidity", 
            WS_OVERLAPPEDWINDOW, 
            CW_USEDEFAULT, CW_USEDEFAULT, 
            CW_USEDEFAULT, CW_USEDEFAULT, 
            NULL, my_menu, instance, NULL);

        // save the address of the class as the Window's USERDATA.
        SetWindowLong(window, GWLP_USERDATA, (long)this);
    }
};

这样,您就可以从 BaseWindow 派生一个类。在您的派生类中,您提供了一个“WindowProc”来覆盖 BaseWindow 中的(纯虚拟)。这里的技巧相当简单:因为你不能直接传递参数,你将类的地址存储在窗口的 GWLP_USERDATA 中,然后在窗口过程中(尝试)检索它并使用它来调用派生类的虚拟窗口过程。

顺便说一句,请注意这是草图,而不是完成的作品(可以这么说)。尽管它应该按原样编译,但结果实际上不会起作用,除非您填写了相当数量的不在此处的部分(例如,WNDCLASS 结构的其他字段只是最明显的字段之一)。

关于c++ - 使用对象方法作为 WinApi WndProc 回调,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14661865/

相关文章:

c++ - 从模板实例化/类型推导中查找错误消息的实际来源

C++ Win32 API 控制消息

python - 在类 __init__ 中使用 Argparse

c++ - 在 VB.Net 中使用 C++ dll 时出现异常

c++ - 工资单项目中的 fstream 问题

c++ - 来自另一个类的对象的类 vector

java - 使用 toString() 方法是一个抽象的例子

c++ - 跨动态链接库的模板静态类

javascript - 用父实例调用父类中的子方法类

java - 通过 JNI 传递、返回和转换为列表的 vector 列表