当使用WM_PARENTNOTIFY将子CButton控件添加到CDialog时检测

问题描述 投票:3回答:1

正在使用:

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

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

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

我已经读过一种处理WM_PARENTNOTIFY的方法,但是我不能使用主事件函数通过任何方式触发它:OnParentNotify(或某些来源的WindowProc)。

我至少对OnParentNotify执行了以下操作:

  1. 添加了消息导出:

ON_WM_PARENTNOTIFY()

  1. 在成员函数DerivedDialog::OnInitDialog()中,在WS_EX_NOPARENTNOTIFY行的代码之后,可能从所有控件句柄中删除了CDialog::OnInitDialog()样式:
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);
}
  1. 已声明和定义的函数只是为了查看它是否被调用:
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)。

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

c++ button mfc modal-dialog message
1个回答
0
投票

来自MSDN documentation

系统在创建并发送WM_PARENTNOTIFY消息时,销毁窗口,但不销毁从对话框创建的控件模板。系统通过指定创建控件时为WS_EX_NOPARENTNOTIFY样式。一个应用程序除非创建自己的默认行为,否则无法覆盖此默认行为对话框的控件。

据此,从对话框模板创建的所有按钮将不会收到WM_PARENTNOTIFY。 (您的DerivedDialog::OnInitDialog()中的代码无效)。

[C0如果可以动态创建按钮(或子控件),则可以使用。

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

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

  3. OnInitDialog

    编辑:

(受@Adrian评论启发)

一种替代解决方案可能是重写按钮的派生类的m_sampleButton.Create(L"Sample", WS_CHILD|WS_VISIBLE, CRect(10, 10, 100, 100), this, 10); 函数,并将用户定义的消息发布到父窗口。

按钮类:

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);
}
© www.soinside.com 2019 - 2024. All rights reserved.