gpt4 book ai didi

c++ - 使用 WM_PARENTNOTIFY 检测子 CButton 控件何时添加到 CDialog

转载 作者:行者123 更新时间:2023-12-02 01:27:19 25 4
gpt4 key购买 nike

合作:

  • Visual Studio 2017;
  • MFC、C++。

我正在尝试修改 MFC 项目,以便 CDialog 派生类检测何时向其中添加子控件(CButton 派生类)。最好获取这些 CButton 的句柄 (HWND) 以进一步处理它们,就像我可以使用以下代码从父对话框窗口获取:

HWND handleParent = ::GetTopWindow(this->GetSafeHwnd());

我已经阅读了一种方法,即处理 WM_PARENTNOTIFY,但我无法使用主事件函数以任何方式触发它:OnParentNotify (或来自某些来源的 WindowProc)。

我已经完成了以下操作,至少对于 OnParentNotify:

  1. 添加了消息导出:

ON_WM_PARENTNOTIFY()

  • 在成员函数 DerivedDialog::OnInitDialog() 中,在 CDialog::OnInitDialog() 行之后,从所有可能的控件句柄中删除了 WS_EX_NOPARENTNOTIFY 样式代码:
  • CDialog::OnInitDialog();

    HWND hwnd = ::GetTopWindow(this->GetSafeHwnd());
    while (hwnd)
    {
    LONG lExStyle;
    lExStyle = GetWindowLong(hwnd, GWL_EXSTYLE);

    if (lExStyle & WS_EX_NOPARENTNOTIFY)
    {
    lExStyle &= ~WS_EX_NOPARENTNOTIFY;
    SetWindowLong(hwnd, GWL_EXSTYLE, lExStyle);
    }

    hwnd = ::GetNextWindow(hwnd, GW_HWNDNEXT);
    }
  • 声明并定义函数只是为了看看它是否被调用:
  • OnParentNotify(UINT message, LPARAM lParam)
    {

    CDialog::OnParentNotify(message, lParam)
    {
    switch (LOWORD(message))
    {
    case WM_CREATE:
    {
    int a = 3;
    int b = 2;
    }
    break;
    case WM_PARENTNOTIFY:
    {
    int c = 1;
    int d = 0;
    }
    }
    }

    不幸的是,只调用了一次WM_CREATE(不认为它是相关的或正确的,因为我有2个必须添加到对话框中的按钮..所以我期望2个WM_CREATES,如果它是案件 ??)。

    我真的不知道如何触发该消息被调用。任何提示都会非常有帮助!

    最佳答案

    来自MSDN documentation :

    The system also sends WM_PARENTNOTIFY messages when it creates and destroys a window, but not for controls created from a dialog box template. The system prevents these messages by specifying the WS_EX_NOPARENTNOTIFY style when creating the controls. An application cannot override this default behavior unless it creates its own controls for the dialog box.

    据此,所有从对话框模板创建的按钮都不会收到WM_PARENTNOTIFY。 (您在 DerivedDialog::OnInitDialog() 中的代码没有影响)。

    如果您动态创建按钮(或子控件),WM_PARENTNOTIFY 就会起作用。

    示例(添加到您现有的代码中):

    1. 在对话框标题中添加 CButton m_sampleButton 成员。
    2. 将创建添加到OnInitDialog代码

      m_sampleButton.Create(L"Sample", WS_CHILD|WS_VISIBLE, CRect(10, 10, 100, 100), this, 10);

    编辑:(受到@Adrian评论的启发)

    另一种解决方案可能是重写按钮派生类的 PreSubclassWindow 函数,并将用户定义的消息发布到父窗口。

    按钮类:

    #define CUSTOM_CREATE_NOTIFY WM_USER+1001 // (add to header file)

    void CCustomButton::PreSubclassWindow()
    {
    CButton::PreSubclassWindow();

    GetParent()->PostMessage(CUSTOM_CREATE_NOTIFY, (WPARAM)m_hWnd);
    }

    对话框类:

    // add to message map
    ON_MESSAGE(CUSTOM_CREATE_NOTIFY, OnCustomNotify)

    LRESULT CMFCApplication2Dlg::OnCustomNotify(WPARAM wParam, LPARAM)
    {
    // wparam is the HWND to the button.

    return 0;
    }

    关于c++ - 使用 WM_PARENTNOTIFY 检测子 CButton 控件何时添加到 CDialog,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58265730/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com