热点推荐

查看: 1005|回复: 2
收起左侧

[资料] 模态对话框与非模态对话的几种销毁方法与区别

[复制链接]
  • TA的每日心情
    振奋
    4 小时前
  • 签到天数: 347 天

    连续签到: 6 天

    [LV.8]以坛为家I

    92

    主题

    408

    帖子

    2280

    积分

    Rank: 9

    积分
    2280

    热心会员突出贡献切换助手验证会员最佳新人

    发表于 2016-12-21 13:25:03 | 显示全部楼层 |阅读模式

    51Halcon诚邀您的加入,专注于机器视觉开发与应用技术,我们一直都在努力!

    您需要 登录 才可以下载或查看,没有帐号?会员注册

    x
    最近在做win32调对话框,挺郁闷,找了好多文章研究,才发现非常简单。

    先说下模式对话框调用的原则。
    模式对话框下,用CDialog::OnOK()或CDialog::OnCancel()以及CDialog::OnClose()关闭对话框。
    一定要注意之前的CDialog::(当然,你可以重载你自己对话框的这个虚函数,但是,后面必须调用基类的CDialog::
    具体我们再参照深入浅出的风格,来个解刨。


    CDialog::Close()默认调用CDialog::OnCancel(),
    CDialog::OnCancel()调用CDialog::EndDialog(IDCANCEL);
    CDialog::EndDialog调用CDialog::DestroyWindows(),
    CDialog::DestroyWindows调用CDialog::OnDestroy();

    CDialog::OnOK()默认先CDialog::UpdateData()
    再调用CDialog::EndDialog(IDOK).
    CDialog::EndDialog调用CDialog::DestroyWindows(),
    CDialog::DestroyWindows调用CDialog::OnDestroy()   



    看来上面你可能就知道了如下的过程
    CDialog::Close()==>CDialog::OnCancel()==>CDialog::EndDialog(IDCANCEL)
    CDialog::OnOK()==>CDialog::EndDialog(IDOK)

    CDialog::DestroyWindows()==>CDialog::OnDestroy()

    CDialog::EndDialog(IDOK) ==   CDialog::UpdateData() + CDialog::DestroyWindows()==>CDialog::OnDestroy()


    CDialog::EndDialog(IDOK)跟CDialog::EndDialog(IDCANCEL)的区别就是,少了一个CDialog::UpdateData(),也就是CDialog::EndDialog(IDOK),在关闭对话框后,会把对话框上控件关联的变量的值更新为用户最后输入的值。而CDialog::EndDialog(IDCANCEL)就不会更新这个值。
    希望自己把模式对话框的关闭讲清楚了。

    下面说说非模态对话框
    调用原则是:  一定要用DestroyWindow()来结束非模态对话框...因为调用CDialog::Create() 时是在堆上 new的对象...需要DestroyWindow来delete 对象..不然会存在资源泄漏的风险...

    在无模式对话框,重载你自己的OnOK(),就是CMyDialog::OnOK()调用CDialog::DestroyWindows()。
    注意:不是默认的CDialog::OnOK()来关闭对话框。
    重载CMyDialog::OnCancel()调用CDialog::DestroyWindows()。
    注意:不是调用默认的CDialog::OnCancel(),来关闭对话框。

    听起来很简单,但是下面提到一个很具体的编程问题。
    一般,我们用非模态对话框都是全局的,也就是通过new来创建,是在heap上的,而不是在stack上的。
    这样我们当然还要通过delete 来销毁对象,不然可是有内存泄漏的。那么我们什么时候delete这个对象呢?


    在msdn上面我们可以看到微软提供的方法是,
    我们要重载PostNcDestroy(),即我们要实现CMyDialog::PostNcDestroy(),内容如下
    1. CMyDialog::PostNcDestroy()  
    2. {   
    3.     CDialog::PostNcDestroy();  
    4.     delete this;   
    5. }  
    复制代码
    这样的话,我们的类就会Auto-Cleanup了。
    1. HWND hMain = CreateDialog(hInstance, (LPCTSTR)IDD_DIALOG1, hWnd,(DLGPROC)DlgProc);  
    2. ShowWindow(hMain, SW_SHOW);  
    3. SetTimer(hMain, 10, 5000, NULL);  
    复制代码
    仿造about处理消息改一下就好了。
    1. INT_PTR CALLBACK DlgProc(HWND hDlg, UINT message, WPARAM wParam,LPARAM lParam)  
    2. {  
    3.     switch(message)  
    4.     {  
    5.         case WM_COMMAND:  
    6.             if (wParam == IDOK)  
    7.             {  
    8.                 DestroyWindow(hDlg);  
    9.                 SendMessageW(hWnd,WM_ONOK, NULL, NULL);  
    10.                 break;  
    11.             }  
    12.             else if(wParam ==IDCANCEL)  
    13.             {  
    14.                 DestroyWindow(hDlg);  
    15.             }  
    16.        case WM_TIMER:  
    17.            if (wParam == 10)  
    18.            {  
    19.                SendMessageW(hWnd,WM_ONOK, NULL, NULL);  
    20.                DestroyWindow(hDlg);  
    21.                break;  
    22.            }  
    23.       return (INT_PTR)FALSE;  
    24. }  
    复制代码



  • TA的每日心情
    害羞
    2018-1-2 10:51
  • 签到天数: 2 天

    连续签到: 1 天

    [LV.1]初来乍到

    0

    主题

    17

    帖子

    526

    积分

    Rank: 5Rank: 5Rank: 5

    积分
    526

    切换助手验证会员

    发表于 2016-12-28 23:16:25 | 显示全部楼层
    其实也可以用C++11的shared_ptr智能指针自动释放

    发帖求助前要善用论坛搜索功能,那里可能会有你要找的答案;

    如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子分类或者标题前面加上【已解决】

    回报帮助你解决问题的坛友,右下角【免费评分】赠与对方视觉币和热心值,伸手党遭人唾弃,做一个热心并受欢迎的人!

    您需要登录后才可以回帖 会员登录 | 会员注册

    本版积分规则

    经营性网站备案信息 经营性网站
    备案信息

    中国互联网举报中心 中国互联网
    举报中心

    中国文明网传播文明 中国文明网
    传播文明

    诚信网站

    深圳市市场监督管理局企业主体身份公示 工商网监
    电子标识