如何使用ON_NOTIFY从无子模式的对话框中捕获WM_NOTIFY消息? [英] How to use ON_NOTIFY to capture the WM_NOTIFY message from a child mode-less dialog?

查看:285
本文介绍了如何使用ON_NOTIFY从无子模式的对话框中捕获WM_NOTIFY消息?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个MFC SDI应用程序,尝试从CView窗口中的无模式对话框捕获通知时遇到问题.以下是我在测试应用程序DlgTest中拥有的东西.

在DlgTestView.h

I have a MFC SDI application and have problems trying to capture notifications from a mode-less dialog in the CView window. Below is what I have in a test app, DlgTest.

In DlgTestView.h

class CDlgTestView : public CView
{
//  ...
    afx_msg void OnTestDlgNotify(NMHDR* pNMHDR, LRESULT* pResult);
    virtual BOOL OnNotify(WPARAM wParam, LPARAM lParam, LRESULT* pResult);
};



在DlgTestView.cpp



In DlgTestView.cpp

BEGIN_MESSAGE_MAP(CDlgTestView, CView)
//  ...
    ON_NOTIFY(NM_CLICK, IDD_TEST_DLG, OnTestDlgNotify)
END_MESSAGE_MAP()
//...
//...
// CDlgTestView message handlers
void CDlgTestView::OnInitialUpdate()
{
    CView::OnInitialUpdate();
    TestDlg.Create( TestDlg.IDD, this );
    TestDlg.SetNotifyWnd( this );   // Q1: why is this necessary ?
}
void CDlgTestView::OnViewDialogtest()
{
    TestDlg.ShowWindow( SW_NORMAL );
}
void CDlgTestView::OnTestDlgNotify(NMHDR* pNMHDR, LRESULT* pResult)
{
    // Q2: this function is never called
    UINT code = pNMHDR->code;
}
BOOL CDlgTestView::OnNotify(WPARAM wParam, LPARAM lParam, LRESULT* pResult)
{
    // this function is called as expecetd
    return CView::OnNotify(wParam, lParam, pResult);
}



在TestDlg.h



In TestDlg.h

class CTestDlg : public CDialog
{
//...
    void SetNotifyWnd( CWnd* pWnd ){ pNotify = pWnd; };
// Dialog Data
    enum { IDD = IDD_TEST_DLG };
protected:
    CWnd*   pNotify;
    virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV support
    DECLARE_MESSAGE_MAP()
    virtual void OnOK();
};



在TestDlg.cpp



In TestDlg.cpp

// CTestDlg message handlers
void CTestDlg::OnOK()
{
    NMHDR nmh;
    nmh.code = NM_CLICK;
    nmh.hwndFrom = m_hWnd;
    nmh.idFrom = GetDlgCtrlID();    // Q3: why GetDlgCtrlID() == 0 ?
    BOOL r = pNotify->SendNotifyMessage( WM_NOTIFY, 0, (LPARAM)&nmh );
// Q4: why SendMessage returns 0 ?
//  BOOL r = pNotify->SendMessage( WM_NOTIFY, 0, (LPARAM)&nmh );
// Q5: why GetParent() does not work below?
//  BOOL r = GetParent()->SendNotifyMessage( WM_NOTIFY, 0, (LPARAM)&nmh );
}



使用DlgTestView作为父窗口,在CDlgTestView :: OnInitialUpdate()上创建无模式的TestDlg.所以我的第一个问题(在上面的代码中由Q1和Q5表示)是为什么使用GetParent()发送消息失败?

我的主要问题(Q2)是为什么从不调用使用ON_NOTIFY宏在消息映射中定义的OnTestDlgNotify?另一方面,被重写的OnNotify函数按预期工作.我想使用ON_NOTIFY来处理WM_NOTIFY消息,而不是OnNotify函数.

Q3:为什么GetDlgCtrlID()返回0,而不是正确的ID IDD_TEST_DLG?

Q4:为什么doeas SendMessage不起作用(返回0),而SendNotifyMessage起作用(返回1)?

请帮忙.谢谢.



The mode-less TestDlg is created at CDlgTestView::OnInitialUpdate(), using the DlgTestView as the parent window. So my first question (indicated by Q1 and Q5 in the codes above) is why sending message using GetParent() fails?

My main question (Q2) is why the OnTestDlgNotify as defined in the message map using the ON_NOTIFY macro is never called? On the other hand, the overridden OnNotify function works as expected. I would like to use ON_NOTIFY to handle the WM_NOTIFY message instead of the OnNotify function.

Q3: why GetDlgCtrlID() returns 0, instead of the correct ID, IDD_TEST_DLG?

Q4: why doeas SendMessage not work (returns 0), while SendNotifyMessage works (returns 1)?

Please help. Thanks.

推荐答案

我知道这已经超过一年了.尽管我会帮助您了解您在这里做错了什么.第一个错误是您使用MFC而不是学习本机win32 GUI来完成工作.这样做的原因是习惯于设计和理解Windows消息泵的工作方式以及其他类似Windowsclass的区域以及如何将其用于注册窗口.在深入了解整个MFC混乱之前,您需要学习设计GUI的这种方式,这需要记住更多的结构.

要在此处按顺序回答这些特定问题.

1.)Windows消息泵中有一条消息正在发送,特别是在窗口中接收更改的"WM_NOTIFY".如果您不收听此类消息,则通知窗口的更改不会通知您.

2.)好像您为OnTesDlgNotify设置了处理程序,但未添加所需的代码来处理传入的消息.

您应该为pNMHDR->代码添加一个开关并进行过滤并以这种方式进行处理.

//代码是您的WM_ *格式代码.从这里可以找到很多代码.
开关(pNMHDR->代码)
{
情况1:
休息;
情况2:
休息;
默认值:break;
}
返回TRUE;

3.)您缺少尝试从中接收控件ID的控件的窗口句柄.阅读这篇热门文章,以了解其格式. GetDlgCtrlID函数.

4.)与问题三有关.您尚未分配向其发送通知的控件ID,因此它返回0.如果您在所有这些混乱之前都学习了本机win32 GUI编程,那么将避免所有这些问题.

恭喜,Firehawk.
I realize this is older than a year. Though I would help you understand what your doing wrong here. First mistake is your using MFC to do your work instead of learning native win32 GUIs. The reason fir this is to get used to designing and understanding how the windows message pump works and what other areas like windowsclass and how it is used to register a window. You need to learn this way of designing GUIs before you get into the whole MFC mess, which has more structures to remember.

To answer these specific questions here in order.

1.) There is a message that is send in the windows message pump, specifically "WM_NOTIFY" that receives changes in a window. If you don''t listen for this kind message you won''t be notified of changes to the window on notifications.

2.) It looks like you made the handler for the OnTesDlgNotify but did not add the required code to handle the incoming messages.

You should add a switch for pNMHDR->code and filter and handle this way.

// code is your WM_* format code. From here is a lot of code your missing.
switch(pNMHDR->code)
{
case 1:
break;
case 2:
break;
Default: break;
}
return TRUE;

3.) Your missing the window handle for the control your trying to receive it''s ID from. Read this smash article to understand the format. GetDlgCtrlID function.

4.) Relates to question three. You have not assigned a control ID to send a notification to so it returns a 0. All of these questions would be avoided if you learned native win32 GUI programming before all of this mess.

Respectfully, Firehawk.


这篇关于如何使用ON_NOTIFY从无子模式的对话框中捕获WM_NOTIFY消息?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆