使用对象方法作为 WinApi WndProc 回调
Use object method as WinApi WndProc callback
我正在尝试创建一个在父窗口中显示控制台窗口的小类。(您可以想象聊天或调试信息显示在那里)
现在,由于不同的 instan 确实具有不同的私有变量(例如消息数组或父窗口),我需要使用非静态方法作为 Windows 事件的回调。
我已经想到了一些方法,我将实际的类实例传递给静态回调函数,然后对其调用正确的方法,但在 winAPI 中,一切都是使用 TranslateMessage
完成的,DispatchMessage
让我没有机会使用自己的参数。
我在这里找到了一些代码:类方法作为winAPI回调,但我不明白它,我认为它不完全是我所需要的。如果是,那么请给我进一步解释所提供的代码。
我得到的错误:
错误:类型为"LRESULT (
WindowConsole::
)(HWND__, UINT, WPARAM, LPARAM)"的参数与"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 结构的其他字段只是最明显的字段之一)。
您链接到的另一个问题仅适用于部分问题。
WindowProc 方法确实需要是静态的。然后在调用 CreateWindowEx 之后立即调用 SetWindowLongPtr,GWLP_USERDATA 作为第二个参数,这个作为第三个参数。这会将 HWND 与类实例相关联。然后在静态 WindowProc 方法中调用 GetWindowLongPtr(再次使用 GWLP_USERDATA)以获取接收 UI 事件的 WindowConsole 实例。
这里详细解释了这一切:
http://msdn.microsoft.com/en-us/library/windows/desktop/ff381400(v=vs.85).aspx
我使用一个简单的解决方案。winproc 是一个模板函数。消息接收器位于 setwindowptr 内。
如果接收方有一个带有消息名称的函数,例如,onpaint ,则wm_paint包含在消息切换中。
http://www.thradams.com/codeblog/wndproc.htm
- WinAPI挂钩鼠标
- 将执行、作业和WinAPI相乘
- 如何在桌面C++上使用 WinApi 画线
- WINAPI 注册应用程序重新启动时不清除打开的套接字
- Winapi:屏幕截图未显示在窗口中
- WinAPI 在单击第一个对话框上的按钮控件并销毁第一个对话框后创建第二个对话框
- Qt with WinAPI MouseProc
- 如何在"SUBSYSTEM:WINDOWS"下显示并输出到Windows(C++ WinApi)上的
- WinAPI 无法创建按钮
- 将 Win32/WinAPI 应用程序移植到 wxWidgets
- WinAPI 检查窗口是否具有常规标题栏
- 如何使用带有矢量的 winapi 读取进程内存从另一个进程读取缓冲区?
- 将Qt集成到现有的VS项目中以取代WinAPI
- __stdcall - WINAPI vs STDMETHODCALLTYPE vs APIENTRY
- 如何将'this'指针传递给C++ WinAPI 线程?
- Winapi-WM_CLOSE的替代方案
- WndProc调用机制(WinAPI)
- cpp WinAPI WndProc封装在类中
- C2440 無法在 C++ WinApi 中將 LRESULT 轉換為 WNDPROC
- 使用对象方法作为 WinApi WndProc 回调