所以我正在编写自己的小型 GUI 框架,将 Windows API 包装在有用的类中。我目前正在尝试让用户以面向对象的方式处理 WndProc 的消息,但我遇到了一些障碍。
我有一个 Button
类,它继承自一个抽象的 Control
类,它几乎是 Button 的 HWND 句柄的包装器。
还有一个 Window
类,它包含(您知道什么)窗口句柄。此类还有一个 Control
容器,并负责创建它自己的(静态)WndProc 方法。
我想做的是在包含窗口的 WndProc 中有一个大的 switch 语句,它根据函数的 wParam 和 lParam 参数调用适当的发送控件的处理函数。我见过大多数人做类似事情的方式是这样的:
#define MY_BUTTON 101 //Define button's ID
Button::Button()
{
hwndButton= CreateWindow(
"BUTTON", text,
WS_VISIBLE | WS_CHILD,
position.x, position.y,
size.x, size.y,
parent_handle,
(HMENU)MY_BUTTON,
GetModuleHandle(NULL),
NULL);
}
Button* button = new Button();
//Later on, in the Window class...
LRESULT CALLBACK Window::WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
switch((LOWORD)wParam)
{
case MY_BUTTON:
button->HandleMessage(&msg);
break;
}
}
但是,我不希望用户为他们创建的每个对象实例分配一个唯一的整数。 相反,因为我有一个控件容器,所以我宁愿做这样的事情:
//In the Window Class...
Button* button = new Button();
AddControl(button);
static LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
switch(&msg)
{
ObtainControlFromParams(wParam, lParam)->HandleMessage(&msg);
//ObtainControlFromParams should return a pointer to a Control,
//and it should look into the window's Control collection.
}
}
尽管这听起来很棒,但我找不到实现 ObtainControlFromParams 函数的方法。
我想到的区分每个控件实例的方法是有一个字符串,我称之为控件的“名称”,它对于每个对象实例化应该是唯一的。这会让我有两个选择(我能想到的)
- 将字符串转换为散列,将其存储在其他地方(例如包含窗口中)并将其用作按钮的 HMENU。然后我可以使用哈希集将每个字符串哈希链接到它的所有者对象,并以这种方式调用相应的方法。
- 使用 lParam 方法(据我所知)存储按钮的 HWND 句柄,然后用它做一些事情。
如果我想要获得的东西不是很清楚,我深表歉意,这对我来说是一个复杂的概念。
非常感谢任何帮助!
最佳答案
通常的方法是反射(reflect)像WM_COMMAND
和WM_NOTIFY
这样的消息,它们被发送到控件的父窗口,返回到控件发送给他们。这是可能的,因为这些消息可以识别发件人(每条消息都以独特的方式,因此请查看文档)。
有许多方法可以将 C++ 对象指针与窗口相关联:
动态生成的 trampoline 函数作为 window-proc。
最有效但也最棘手。可能需要使用VirtualAlloc
。窗口属性。
SetProp
和GetProp
函数。窗口对象的话。
SetWindowLongPtr
。需要确保已分配空间。静态 map 。
例如。单例std::unordered_map
,映射句柄 → 对象。Windows 标准子类化使用的任何内容。
IE。使用SetWindowSubclass
。
关于c++ - 如何从 WndProc 的参数中检索消息发送对象?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38005718/