《C++笔记》 Part11 MFC在对话框中嵌入子对话框,同时利用类似Qt的信号槽来发送消息传递参数

《C++笔记》 Part11 MFC在对话框中嵌入子对话框,同时利用类似Qt的信号槽来发送消息传递参数

一、对话框中显示对话框的方法:
1、首先创建要在对话框里显示的那个对话框,命名为:IDD_Dialog。
设置这个对话框的属性:
1)、“Style”选择“Child”;中文版“样式”选择“下层”。
2)、“Border”为“None”;中文版“边框”选择“无”。

2、为了显示时能够准确定位,我们可以在主对话框中要显示对话框的地方放入一个Picture控件,命名为:IDC_Dialog_Rect,Visible属性去掉。

3、创建需要嵌入的对话框对话框

//CDlgParent.cpp ——OnInitDialog()  
CRect rect;  
GetDlgItem(IDC_Dialog_Rect)-> GetWindowRect(&rect);  //定位到Pic控件框中
ScreenToClient(&rect);   //千万注意别用成ClientToScreen(&rect);  

4、创建并显示对话框
方式一:

//CDlgParent.h  
CDialog m_InnerDlg;  
//CDlgParent.cpp——OnInitDialog()  
m_InnerDlg.Create(IDD_INNER, this);  
m_InnerDlg.MoveWindow(rect);  
m_InnerDlg.ShowWindow( SW_SHOW );  

方式二:

//CDlgParent.h  
CDialog *m_pInnerDlg;  
//CDlgParent.cpp——OnInitDialog()  
m_pInnerDlg = new CDialog();  
m_pInnerDlg->Create(IDD_INNER, this);  
m_pInnerDlg->MoveWindow(rect.left, rect.top, rect.Width(), rect.Height());  
m_pInnerDlg->ShowWindow( SW_SHOW );  


1)如果对话框无法显示,在OnInitDialog()函数的创建并显示对话框 之前加上

GetDlgItem(IDC_Dialog_Rect)->ShowWindow(SW_HIDE);

将PictureControl隐藏掉;
2)创建并显示对话框部分的代码需要放在AfxSetResourceHandle(cur_hinstance);之后。

二、利用类似Qt的信号槽来发送消息传递参数

在上面新建的子对话框对应的类中按以下操作步骤进行:
说明:WM_USER

为了防止用户定义的消息ID与系统的消息ID冲突,MS(Microsoft)定义了一个宏WM_USER,小于WM_USER的ID被系统使用,大于WM_USER的ID被用户使用。

(一)先在头文件中定义自己消息的ID,如

#define WM_MY_FIRST_MESSAGE (WM_USER + 0x001)

:自定义消息WM_XXXX的定义由自己命名。
(二)再声明自己的消息处理函数:afx_msg void OnMyFirstMessage();
(三)在CPP文件中添加消息映射宏:
方式1自动发送消息
在BEGIN_MESSAGE_MAP 和END_MESSAGE_MAP代码块中添加消息映射宏ON_MESSAGE,(建议添加到//}}后面)如下:

BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)
//{{AFX_MSG_MAP(CAboutDlg)
// No message handlers
//}}AFX_MSG_MAP
ON_MESSAGE(WM_MY_FIRST_MESSAGE, OnMyFirstMessage)
END_MESSAGE_MAP()

方式2通过触发方式来发送消息,示例由IDC_Btn触发

BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)
//{{AFX_MSG_MAP(CAboutDlg)
// No message handlers
//}}AFX_MSG_MAP
ON_MESSAGE(IDC_Btn, &CAboutDlg::OnMyFirstMessage)
END_MESSAGE_MAP()

(四)最后定义消息处理函数:
对应上面方式1自动发送消息

OnMyFirstMessage()
{
// TODO: 在此添加控件通知处理程序代码
...
//备注:自定义消息的发送可以通过SendMessage命令
::SendMessage(this->GetParent()->m_hWnd,WM_CUSTOME_CFG_CHGED,0,0);  //在需要消息触发(如单击控件)处发送该消息到制定窗口,此处将该消息发送给了本窗口的父窗口,因此,消息的处理函数声明、宏定义、消息实现应写在父窗口对应的father.h与father.cpp文件中;消息ID的声明在Child.h文件中
}

对应上面方式2通过触发方式来发送消息
OnMyFirstMessage()
{
// TODO: 在此添加控件通知处理程序代码

GetParent()->SendMessage(WM_MY_FIRST_MESSAGE,(WPARAM)&m_ParaStruct,NULL);
}

1)m_ParaStruct为自定义结构体,当然也可以穿单个值(WPARAM为UINT_PTR,可以传值也可以传结构体)。
2)m_ParaStruct最好为一个将子窗体所有参数放在里面的结构体,个人测试时发现一个窗口只能触发一个SendMessage(),哪怕多个按钮响应,也是由该消息函数发送。
3)结构体示例:将其实例化即可。

typedef struct PARAM
{
int A;
bool B;
float C;
}Param;

(五)主窗口中接收消息:
对应上面方式1,2:

//先在主窗口parentDlg.h中添加子窗口头问题
//定义函数
afx_msg LRESULT OnUpdateMessage(WPARAM wParam, LPARAM lParam);//收消息

//再在主窗口parentDlg.cpp中添加
1、

BEGIN_MESSAGE_MAP(ParentDlg,CDialogEx)
    ON_MESSAGE(WM_MY_FIRST_MESSAGE,OnUpdateMessage)
END_MESSAGE_MAP()

2、OnUpdateMessage()函数实现

LRESULT ParentDlg::OnUpdateMessage(WPARAM wParam, LPARAM lParam)
{
//
Param * m_param = (Param*)wParam;//子窗口中的参数由结构体通过wParam传过来
…//代码实现,可以在此处加上子窗口点击按键后需要触发的函数
}

(六)参考链接:
1、MFC 在父对话框中内嵌子对话框
2、WM_USER与WM_APP的区别
3、WM_USER以及自定义消息WM_XXXX的定义 声明 实现
4、MFC一一添加WM_USER自定义消息
5、MFC一一SendMessage与PostMessage

猜你喜欢

转载自blog.csdn.net/sinat_24206709/article/details/80229199