【问题标题】:Passing messages from subclass to original WndProc将消息从子类传递到原始 WndProc
【发布时间】:2008-10-21 21:19:56
【问题描述】:

我一直在阅读关于子类化的MSDN 文档,并且我已经成功地处理了子类中的事件

我的问题是将消息传递回原始 WndProc。

例如,如果我有一个窗口,带有一个子类 groupbox 控件和一个按钮作为该 groupbox 的子项,我想在原始窗口过程中处理按钮事件,而不是子类 groupbox 过程。

本质上,我想要一个空的子类过程:

LRESULT FAR PASCAL SubClassFunc(HWND hwnd,
                        UINT uMsg,
                WPARAM wParam,
                LPARAM lParam)
{
    return CallWindowProc(oldProc, hwnd, uMsg, wParam, lParam);
}

oldProc 在哪里:

FARPROC oldProc = (FARPROC)SetClassLong(group_box, GCL_WDPROC, (DWORD)SubCLassFunc);

以及窗口、组框和按钮在哪里:

HWND window = CreateWindowEx(
    WS_EX_WINDOWEDGE, 
    appname,
    TEXT("Subclass Test"),
    WS_VISIBLE |WS_OVERLAPPEDWINDOW,
    CW_USEDEFAULT,
    CW_USEDEFAULT,
    300,
    400,
    NULL,
    NULL,
    hInstance,
    0);

HWND group_box = CreateWindowEx(
    0,
    TEXT("BUTTON"),
    TEXT("Group Box"),
    WS_CHILD | WS_VISIBLE | BS_GROUPBOX,
    8,
    8,
    275,
    350,
    window,
    NULL,
    hInstance,
    0);

HWND push_button = CreateWindowEx(
    0,
    TEXT("BUTTON"),
    TEXT("Push Button"),
    WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON | BS_VCENTER,
    50,
    100,
    100,
    25,
    group_box,
    (HMENU)PUSH_BUTTON,
    hInstance,
    0);

我可以在 SubClassFunc 中处理按钮事件,但我想做的是将它们传递回窗口 WndProc。似乎 CallWindowProc 没有这样做,或者我可能完全错误地了解 CallWindowProc 的工作方式。

【问题讨论】:

    标签: c user-interface winapi


    【解决方案1】:

    按钮通知被发送到按钮的父级,即组框。因为您已经对分组框进行了子类化,所以您的 SubClassFunc 会收到这些消息,然后使用 CallWindowProc 将它们传递给分组框的原始窗口过程。

    如果您希望按钮通知转到父窗口(即代码中的window),您可以将按钮的父窗口设置为window 而不是group_box,或者在内部使用PostMessage SubClassFunc 将消息(WM_COMMANDWM_NOTIFY 视情况而定)发布到 window

    另外,我看到您正在使用SetClassLong 来设置窗口过程。它的作用是替换整个BUTTON 类的窗口过程,但仅适用于随后创建的窗口。在调用SetClassLong 之前创建的任何BUTTON 窗口都不会被子类化。您可能需要考虑使用 SetWindowLong 来代替单个窗口而不是整个类。

    编辑:组框的原始窗口过程不会向其父级发送WM_COMMAND 消息。 Charles Petzold 的 Programming Windows 书中对此进行了解释:

    具有BS_GROUPBOX 样式的组框是按钮类中的一个奇怪的东西。它既不处理鼠标或键盘输入,也不向其父级发送WM_COMMAND 消息。

    您应该会发现按钮通知不会传递到window,即使您没有子类化组框。

    我希望这会有所帮助!

    【讨论】:

      【解决方案2】:

      我怀疑如果您将子类全部删除,按钮事件仍将无法达到您期望的原始窗口过程。

      由于您有一个子类过程,只是调用 CallWindowProc,因此窗口实际上不是子类。

      我的建议是使用 Spy++ 工具来查看哪个窗口正在获取按钮事件消息。

      Win32 编程的一个更困难的方面是确定哪个窗口获取哪个消息,而 Spy++ 在找出这些信息时非常宝贵。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2011-02-21
        • 2012-08-29
        • 1970-01-01
        • 2014-02-07
        • 1970-01-01
        • 2016-07-06
        • 2018-08-12
        • 1970-01-01
        相关资源
        最近更新 更多