非模态对话框关闭按钮(“X”)调用OnCancel的疑问

二进制脑袋 2021-04-07 04:48:39
VS2015,MDI应用。要使用一个非模态对话框,发现该对话框的IDCANCEL按钮、ESC按键、窗口右上角的“X”按钮,实际都调用OnCancel虚函数。确认了一下,按窗口右上角的“X”按钮,会触发WM_CLOSE消息,调用OnClose方法,微软的官方文档说OnClose的缺省方法调用DestroyWindow。但我查遍了VC 2015附带的mfc源码,没有找到CDialog或者CDialogEx响应WM_CLOSE消息调用OnCancel的代码实现。哪位对这个比较熟悉,找到非模态对话框的窗口右上角关闭按钮“X”是调用OnCancel证据?官方文档或者mfc源码文件说明都可以。
...全文
312 5 打赏 收藏 举报
写回复
5 条回复
切换为时间正序
请发表友善的回复…
发表回复
二进制脑袋 2021-04-09
在《Programming Windows with MFC, Second Edition》,关于非模态对话框,有这么一句话:You should always override OnCancel because an IDCANCEL notification is sent when the user presses the Esc key or clicks the dialog box's close button, regardless of whether the dialog box contains a Cancel button. 算是证实吧,但还是没看到是谁在对话框关闭按钮按下后,投递WM_COMMAND消息的。
  • 打赏
  • 举报
回复
二进制脑袋 2021-04-09
明确了: 1、对话框按IDCANCEL按钮,直接通过ON_COMMAND(IDCANCEL, &CDialog::OnCancel)的消息映射,触发OnCancel的调用; 2、按ESC按键,在CDialog::PreTranslateMessage中,调用CWnd::PreTranslateInput,进而调用CWnd::IsDialogMessage,接下来调用Windows API ::IsDialogMessage,在::IsDialogMessage处理中,直接调用OnCancel; 3、按对话框右上角“X”按钮,如我在上一条回复中所述,缺省的OnClose会调用CWnd::Default,会被(谁?)投递一条WM_COMMAND消息,ID为IDCANCEL,从而触发OnCancel被调用。究竟是谁投递WM_COMMAND的,目前在MFC源码中还没有找到!
  • 打赏
  • 举报
回复
二进制脑袋 2021-04-08
由于VS2015调试不能跟踪MFC源码,转到VS2008调试发现。对话框右上角的“X”按钮,会触发WM_CLOSE消息,响应WM_CLOSE消息,方法为OnClose,如果调用CDialog::OnClose(),则会实际调用CWnd::OnCancelMode(),CWnd::OnCancelMode()和CWnd::OnClose()一样,都会调用CWnd::Default()。进而会调用对话框的OnCancel()方法。究竟调用Default()之后,怎么调用OnCancel的,VS2008中间跟踪断掉了,不得而知。
  • 打赏
  • 举报
回复
Eleven 2021-04-08
When you implement a modeless dialog box, always override the OnCancel member function and call DestroyWindow from within it. Don't call the base class CDialog::OnCancel, because it calls EndDialog, which will make the dialog box invisible but will not destroy it. You should also override PostNcDestroy for modeless dialog boxes in order to delete this, since modeless dialog boxes are usually allocated with new. Modal dialog boxes are usually constructed on the frame and do not need PostNcDestroy cleanup.
  • 打赏
  • 举报
回复
zgl7903 2021-04-07
那个叉 可以 修改风格 (去掉 WS_SYSMENU) 风格, 或者注册类的时候 style加 CS_NOCLOSE 或者消息的话 可以处理 WM_SYSCOMMAND SC_CLOSE
  • 打赏
  • 举报
回复
相关推荐
发帖
界面

1.5w+

社区成员

VC/MFC 界面
社区管理员
  • 界面
加入社区
帖子事件
创建了帖子
2021-04-07 04:48
社区公告
暂无公告