注册 登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

小人物的自述

为梦想而奋斗,没有梦想就没有希望!

 
 
 

日志

 
 

非模态对话框的创建  

2009-06-19 10:12:09|  分类: 学习笔记 |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |

简介

非模式对话框常常感到困惑的新手程序员。基本上是一个非模式对话框是一个使我们能够互动,与其他的Windows ,甚至当非模式对话框仍然是在屏幕上。如果您请记住,几个漂亮的小动作,然后编程非模式对话框,将非常简单。

创建非模式对话框

简单的方法创建一个非模式对话框是使用Create()。通过名称的对话框中的模板资源和一个可选的CWnd*这点,向父窗口。如果您不通过一个父窗口指针的主要应用程序窗口将被作为父窗口。Create()将返回true如果调用是成功的。自Create()立即传回,不像DoModal(), you must never declare your modeless dialog as a local variable与范围及寿命只有功能函数的地方,这是申明。如果你不这样做,非模式对话框会被销毁时刻,你退出功能函数,使你申明它。

另一种解决办法是要申明您的非模式对话框作为一个堆的成员对象你的主要框架窗口或您的CWinApp派生类。用此方法的优势是,你实际上有控件权的非模式对话框,由于你有一个指针。

由于方式不同,非模式对话框需要有WS_VISIBLE风格设置如果你不想让他们看见后,立即进行创作。否则,你就会有明确要求ShowWindow()与SW_SHOW。
       事实上,我建议您这样做,而不是去所有的地方,改变默认的风格。
CModeLess *m_pmodeless = new CModeLess(this);
m_pmodeless->Create(CModeLess::IDD);
m_pmodeless->ShowWindow(SW_SHOW);

父问题

惯常的做法是使父窗口的主窗口对您的应用程序,这是典型的主框架窗口。现在的一个问题是与这是因为非模式对话框,将继续留在上方的这父窗口。它可以让您的互动与主框架窗口,或许它还包含一个CView得出的视图。但它可能是恼人的和不可取的有非模式对话框留在顶端。该解决方案在这里是创建非模式对话框作为一个子的桌面上。使用GetDesktopWindow()得到一个指针到桌面上。
m_pmodeless->Create(CModeLess::IDD,GetDesktopWindow());

销毁非模式对话框

既然我们已分配内存就堆,我们必须将它删除时,非模式对话框是摧毁,否则我们很快会遇到很大的麻烦与内存泄漏。当对话框是摧毁了最后一则留言,我们收到处理类是WM_NCDESTROY消息。该OnNcDestroy功能函数是引用,这在原来调用虚拟函数PostNcDestroy。这正是我们可以delete我们的非模式对话框。 First Call调查的基类的功能函数,以便它是否自己的清理。
void CModeLess::PostNcDestroy() { CDialog::PostNcDestroy(); delete this;}

问题与成员对象

如果非模式对话框是一个成员对象的父窗口的类,我们有一个轻微的问题在这里。成员变量仍持有指针引用,但它引用的记忆已被删除。要替代这个问题:一种方法是后一用户定义的消息给父窗口和处理它在父类,通过设置非模式对话框成员变量,以NULL。另一种方法是使用GetParent()得到父窗口,如有的话,然后在它的实际父类。现在我们已进入到父类的成员变量保存指针向非模式对话框。设置为NULL。后者的方法是描绘后来我讨论如何限制非模式对话框,以一个实例。
前者的方法是,如下所示:
void CModeLess::PostNcDestroy() { CDialog::PostNcDestroy(); GetParent()->PostMessage(WM_MODELESS_CLOSED,0,0); delete this;}
LRESULT CMainFrame::OnMyMethod(WPARAM wParam, LPARAM lParam){ m_pmodeless = NULL; return 0;}

跟踪非模式对话框计数

让我们说你要只有一个实例,该非模式对话框活在同一时间。在这种情况下,每一次用户启动一些行动,结果,在使该非模式对话框,你必须检查,看看是否该非模式对话框是已经在运作中。也就是说,m_pmodeless是非模式对话框的成员,你的类类。在类的构造一套m_pmodeless,以NULL。现在您每一次检查,看看是否m_pmodeless是NULL,如果这是NULL,创建一个新的非模式对话框,否则,显示MessageBox认为,对话框是已经活跃或使用SetForegroundWindow()把非模式对话框到前景。
if(m_pmodeless)
{
m_pmodeless->SetForegroundWindow();
}
else
{
m_pmodeless = new CModeLess(this);
m_pmodeless->Create(CModeLess::IDD);
m_pmodeless->ShowWindow(SW_SHOW);
}

但是,当对话框被摧毁,我们必须告知父类指针,它现在是无用的。我们做什么,指针NULL,在PostNcDestroy。事实上,这是十分重要的,你这样做,否则下一次用户试图启动非模式对话框,您的程序会崩溃,因为它认为m_pmodeless仍然是指向一个有效的对话框窗口,并试图调用SetForegroundWindow() 它。这里是我PostNcDestroy:
void CModeLess::PostNcDestroy()
{
CDialog::PostNcDestroy();
((CMainFrame*)m_parent)->m_pmodeless = NULL;
delete this;
}

 

自己做的实例:
 CModeLess *ModalessDlg;
 ModalessDlg=new CDialogModaless;
 ModalessDlg->Create(IDD_ModelessDialog,this);
 ModalessDlg->m_UserAnswer=m_UserAnswer;//自己定义的m_UserAnswer成员变量,并赋值
 ModalessDlg->SetAnswer();//自己定义的成员函数,用于经成员变量的值显示到模态对话框中的空间中,使用的方法是SetDlgItemText(IDD_NAME,m_UserAnswer);
 ModalessDlg->ShowWindow(SW_SHOW);

  评论这张
 
阅读(1015)| 评论(0)
推荐

历史上的今天

在LOFTER的更多文章

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2017