基于对话框的程序关闭不了解答
2008-08-22 14:09
169 查看
对话框默认用的两个按钮的ID分别是IDOK和IDCANCEL,这两个都是在winuser.h 中预定义的系统标准控件ID。
对于标准ID,你不重载时MFC会自动调用父类的相应处理函数。
比如IDOK映射到CDialog::OnOK()函数,IDCANCEL映射到CDialog::OnCancel()。
在这两个函数的源码如下:
void CDialog::OnOK()
{
if (!UpdateData(TRUE))
{
TRACE(traceAppMsg, 0, "UpdateData failed during dialog termination./n");
// the UpdateData routine will set focus to correct item
return;
}
EndDialog(IDOK);
}
void CDialog::OnCancel()
{
EndDialog(IDCANCEL);
}
可以看出点击这两个按钮,都会调用EndDialog()来关闭对话框,只是返回值不同。
EndDialog()函数调用了DestroyWindow()函数,DestroyWindow()函数又发送了WM_DESTROY消息,该消息的处理函数是OnDestroy(),对话框的生存期最后一个函数是PostNcDestroy()函数。
点那个叉叉呢,首先向对话框发送WM_CLOSE消息,由OnClose()函数处理,它调用DestroyWindow(),其后是和上面一样的路由。
可以看出点叉叉的时候绕过了OnOK()和OnCancel()。
小结一下:
1. 点“确定”、“取消”时的关闭路由为
OnOK()或OnCancel() ---> EndDialog() ---> DestroyWindow() ---> OnDestroy() ---> PostNcDestroy()
2. 点“关闭”标题栏按钮的关闭路由为
OnClose()---> DestroyWindow() ---> OnDestroy() ---> PostNcDestroy()
回答楼主的问题:
请注意,上面提到的这些函数统统都是可以重载的,在重载时加入了你自己的代码后,应该调用父类CDialog同名的函数才能正确路由下去,否则就关不了对话框了。
举个例子,重载了关闭的小叉叉
void CAboutDlg::OnClose()
{
// TODO: 在此添加消息处理程序代码和/或调用默认值
DoSomthing(0; // 执行自己的判断等等
// CDialog::OnClose(); // 把向导生成的父类调用给注释了,这时就关不了对话框了。
}
补充回答,
点叉叉会发送WM_CLOSE消息,如果需要重载的话,应该在对话框的属性窗口中,选择WM_CLOSE消息来添加消息处理函数。
VS的IDE会自动添加如下三段:
1. xxx.h文件,类声明中加入OnClose()函数声明
afx_msg void OnClose();
2. xxx.cpp文件,加入消息映射宏
ON_WM_CLOSE() // 对于Windows标准消息,都是这种简短的格式。
3. xxx.cpp文件,加入函数体
void CMyDlg::OnClose()
{
CDialog::OnClose();
}
上述3处如果都正常的话,叉叉就映射到OnClose()了。
你说的映射到OnCancel()个人觉得有两种可能,
第一、缺ON_WM_CLOSE()宏,却多个一个ON_BN_CLICKED(IDCLOSE, &CMyDlg::OnCancel)宏
第二、在OnClose()中调用了OnCancel()
对于标准ID,你不重载时MFC会自动调用父类的相应处理函数。
比如IDOK映射到CDialog::OnOK()函数,IDCANCEL映射到CDialog::OnCancel()。
在这两个函数的源码如下:
void CDialog::OnOK()
{
if (!UpdateData(TRUE))
{
TRACE(traceAppMsg, 0, "UpdateData failed during dialog termination./n");
// the UpdateData routine will set focus to correct item
return;
}
EndDialog(IDOK);
}
void CDialog::OnCancel()
{
EndDialog(IDCANCEL);
}
可以看出点击这两个按钮,都会调用EndDialog()来关闭对话框,只是返回值不同。
EndDialog()函数调用了DestroyWindow()函数,DestroyWindow()函数又发送了WM_DESTROY消息,该消息的处理函数是OnDestroy(),对话框的生存期最后一个函数是PostNcDestroy()函数。
点那个叉叉呢,首先向对话框发送WM_CLOSE消息,由OnClose()函数处理,它调用DestroyWindow(),其后是和上面一样的路由。
可以看出点叉叉的时候绕过了OnOK()和OnCancel()。
小结一下:
1. 点“确定”、“取消”时的关闭路由为
OnOK()或OnCancel() ---> EndDialog() ---> DestroyWindow() ---> OnDestroy() ---> PostNcDestroy()
2. 点“关闭”标题栏按钮的关闭路由为
OnClose()---> DestroyWindow() ---> OnDestroy() ---> PostNcDestroy()
回答楼主的问题:
请注意,上面提到的这些函数统统都是可以重载的,在重载时加入了你自己的代码后,应该调用父类CDialog同名的函数才能正确路由下去,否则就关不了对话框了。
举个例子,重载了关闭的小叉叉
void CAboutDlg::OnClose()
{
// TODO: 在此添加消息处理程序代码和/或调用默认值
DoSomthing(0; // 执行自己的判断等等
// CDialog::OnClose(); // 把向导生成的父类调用给注释了,这时就关不了对话框了。
}
补充回答,
点叉叉会发送WM_CLOSE消息,如果需要重载的话,应该在对话框的属性窗口中,选择WM_CLOSE消息来添加消息处理函数。
VS的IDE会自动添加如下三段:
1. xxx.h文件,类声明中加入OnClose()函数声明
afx_msg void OnClose();
2. xxx.cpp文件,加入消息映射宏
ON_WM_CLOSE() // 对于Windows标准消息,都是这种简短的格式。
3. xxx.cpp文件,加入函数体
void CMyDlg::OnClose()
{
CDialog::OnClose();
}
上述3处如果都正常的话,叉叉就映射到OnClose()了。
你说的映射到OnCancel()个人觉得有两种可能,
第一、缺ON_WM_CLOSE()宏,却多个一个ON_BN_CLICKED(IDCLOSE, &CMyDlg::OnCancel)宏
第二、在OnClose()中调用了OnCancel()
相关文章推荐
- 在基于对话框程序中按下Esc键不会关闭程序按下回车键不会关闭程序
- 屏蔽基于对话框的MFC程序中按下ESC关闭窗口的功能
- VC基于对话框的程序中,按ESC键窗口不关闭
- 基于对话框的MFC程序启动时完全隐藏的简单方法
- 基于MFC对话框程序中添加菜单栏 (CMenu)
- 如何取消WIN2008下应用报错后弹出的对话框 程序已停止 要求关闭程序
- 基于对话框的MFC程序加入菜单资源
- jBox 2.3基于jquery的最新多功能对话框插件 常见使用问题解答
- 取消window下应用报错后弹出的对话框程序已停止要求关闭程序对话框
- 给基于对话框的MFC程序添加状态栏并实时显示时间
- MFC中基于对话框程序快捷键的实现
- MFC基于对话框程序 转自http://www.uudo.net/
- 在基于对话框程序中使用WM_KICKIDLE消息
- 对话框程序禁用系统的关闭按钮X
- MFC中基于对话框程序快捷键的实现
- 【转载、修改、增强】MFC基于对话框程序如何最小化到托盘?
- 基于半关闭的文件传输程序(Visual Studio 2015)
- MFC对话框程序 屏蔽ESC和ENTER键关闭对话框的方法
- MFC对话框程序 屏蔽ESC和ENTER键关闭对话框的方法
- 基于对话框程序,自定义工具栏(支持真彩色图标,可添加文字)