c++ - 如何从 WndProc 的参数中检索消息发送对象?

标签 c++ winapi

所以我正在编写自己的小型 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_COMMANDWM_NOTIFY这样的消息,它们被发送到控件的父窗口,返回到控件发送给他们。这是可能的,因为这些消息可以识别发件人(每条消息都以独特的方式,因此请查看文档)。

有许多方法可以将 C++ 对象指针与窗口相关联:

  • 动态生成的 trampoline 函数作为 window-proc。
    最有效但也最棘手。可能需要使用 VirtualAlloc

  • 窗口属性。
    SetPropGetProp 函数。

  • 窗口对象的话。
    SetWindowLongPtr。需要确保已分配空间。

  • 静态 map 。
    例如。单例 std::unordered_map,映射句柄 → 对象。

  • Windows 标准子类化使用的任何内容。
    IE。使用 SetWindowSubclass

关于c++ - 如何从 WndProc 的参数中检索消息发送对象?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38005718/

相关文章:

c++ - 可以在QML中的 map 上绘制带有孔的MapPolygon吗?

c++ - ACE 宏定义错误

windows - 渲染透明窗口

c++ - FindWindow() 通过不完整的名称

c++ - 多维 vector

c++ - Windows GTest EXPECT_STREQ : error: no matching function for call to 'CmpHelperSTREQ'

c++ - 将 SetPixel 坐标转换为控制台上的像素

c - 我应该从 Windows 代码中删除 TCHAR 吗?

perl - 如何从 Win32::OLE 中的 HWND 获取 COM 对象?

C++11 gcc : explicit qualification in declaration? 标准引用?