热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

【转】MFC非模态对话框教程

【转载】简介非模式对话框常常感到困惑的新手程序员。基本上是一个非模式对话框是一个使我们能够互动,与其他的Windows,甚至当非模式对话框仍然是在屏幕

 

 【转载】

 

简介

非模式对话框常常感到困惑的新手程序员。基本上是一个非模式对话框是一个使我们能够互动,与其他的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()得到一个指针到桌面上,并通过表示,由于父窗口为非模式对话框,在您的调用Create()

 

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;
}

 

问题OnOK ( )和OnCancel ( )

在模态对话框,每个人都包括女王的厨师,有OK/cancel按钮。我认为,想必在许多其他更了解市民的意见,您要做好,以避免OK和取消对一非模式对话框。但如果因为某种不可避免的原因,您最希望能有他们对您的非模式对话框,那么您将需要超过预约两种功能函数。

这里是我的非模式版本的OnCancel()功能函数。正如你可以看到,我只是调用的DestroyWindow()和我没有困扰,调用基类。事实上, don't call the base class at all 。基类函数将拜会EndDialog()这与DoModal()

 

void CModeLess::OnCancel()
{
DestroyWindow();
}

 

好吧,现在我的非模式版本的OnOK() 。我有调用的DestroyWindow() 作为,在OnCancel() ,但也有一些额外的代码,也正如你所看到的。我调用UpdateData ,因为这是什么OnOK()是否在一个模态对话框。如果DDV宏是成功的验证,然后UpdateData(true)返回我们摧毁的窗口,否则DDV消息框是自动显示给用户和我们拒绝销毁对话框。因此,我们是模拟的行为,一模态对话框的OK按钮在这里。

 

void CModeLess::OnOK()
{
if(UpdateData(true))
{
DestroyWindow();
}
}

 

传递回数据

在模态对话框,我们仍然可以使用数据变量时, DoModal()返回,因为对话框的对象并没有被摧毁,但只有基这个的对话框窗口已被摧毁。这是也有可能与非模式对话框,用漂亮的技巧,如下所示。

 

void CModeLess::OnOK()
{
if(UpdateData(true))
{
((CMainFrame*)m_parent)->m_x=m_sss;
DestroyWindow();
}
}

 

在这里,我已经指派的值对话框的数据变量m_sss到父类的成员变量, m_x 。在这里, m_parent 是一个指针,向父窗口。此处您想知道我得到这个m_parent 从,滚动起来,看看如何我已构造的,我非模式对话框对象。我会重复,单行刷新您的内存,也帮助您避免滚动,从而节省您的一些能源。

 

CModeLess *m_pmodeless = new CModeLess(this);

 

你可以看到,我已通过this向构造。在我而言,这是一个指针,以我的CFrameWnd派生类,其中应用程序向导已命名为CMainFrame我。现在看看我的CModeLess类的构造。

 

CModeLess::CModeLess(CWnd* pParent /*=NULL*/)
: CDialog(CModeLess::IDD, pParent)
{
//{{AFX_DATA_INIT(CModeLess)
m_sss = 0;
//}}AFX_DATA_INIT
m_parent=pParent; //This is where I point m_parent to my main frame window
}

 

这一切,慢慢是有道理的,嗯?

跟踪非模式对话框计数

让我们说你要只有一个实例,该非模式对话框活在同一时间。在这种情况下,每一次用户启动一些行动,结果,在使该非模式对话框,你必须检查,看看是否该非模式对话框是已经在运作中。也就是说, m_pmodeless是非模式对话框的成员,你的类类。在类的构造一套m_pmodeless ,以NULL 。现在您每一次检查,看看是否m_pmodelessNULL ,如果这是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;
}

 

http://www.cnblogs.com/WeedQian/archive/2009/12/28/1634484.html

 

 

-------------------------------------------------------------------------

 


推荐阅读
  • GetWindowLong函数
    今天在看一个代码里头写了GetWindowLong(hwnd,0),我当时就有点费解,靠,上网搜索函数原型说明,死活找不到第 ... [详细]
  • 本文详细介绍了GetModuleFileName函数的用法,该函数可以用于获取当前模块所在的路径,方便进行文件操作和读取配置信息。文章通过示例代码和详细的解释,帮助读者理解和使用该函数。同时,还提供了相关的API函数声明和说明。 ... [详细]
  • Iamtryingtomakeaclassthatwillreadatextfileofnamesintoanarray,thenreturnthatarra ... [详细]
  • 本文介绍了OC学习笔记中的@property和@synthesize,包括属性的定义和合成的使用方法。通过示例代码详细讲解了@property和@synthesize的作用和用法。 ... [详细]
  • 本文介绍了在MFC下利用C++和MFC的特性动态创建窗口的方法,包括继承现有的MFC类并加以改造、插入工具栏和状态栏对象的声明等。同时还提到了窗口销毁的处理方法。本文详细介绍了实现方法并给出了相关注意事项。 ... [详细]
  • 本文介绍了pack布局管理器在Perl/Tk中的使用方法及注意事项。通过调用pack()方法,可以控制部件在显示窗口中的位置和大小。同时,本文还提到了在使用pack布局管理器时,应注意将部件分组以便在水平和垂直方向上进行堆放。此外,还介绍了使用Frame部件或Toplevel部件来组织部件在窗口内的方法。最后,本文强调了在使用pack布局管理器时,应避免在中间切换到grid布局管理器,以免造成混乱。 ... [详细]
  • Jquery 跨域问题
    为什么80%的码农都做不了架构师?JQuery1.2后getJSON方法支持跨域读取json数据,原理是利用一个叫做jsonp的概念。当然 ... [详细]
  • Commit1ced2a7433ea8937a1b260ea65d708f32ca7c95eintroduceda+Clonetraitboundtom ... [详细]
  • android listview OnItemClickListener失效原因
    最近在做listview时发现OnItemClickListener失效的问题,经过查找发现是因为button的原因。不仅listitem中存在button会影响OnItemClickListener事件的失效,还会导致单击后listview每个item的背景改变,使得item中的所有有关焦点的事件都失效。本文给出了一个范例来说明这种情况,并提供了解决方法。 ... [详细]
  • Java容器中的compareto方法排序原理解析
    本文从源码解析Java容器中的compareto方法的排序原理,讲解了在使用数组存储数据时的限制以及存储效率的问题。同时提到了Redis的五大数据结构和list、set等知识点,回忆了作者大学时代的Java学习经历。文章以作者做的思维导图作为目录,展示了整个讲解过程。 ... [详细]
  • 本文主要解析了Open judge C16H问题中涉及到的Magical Balls的快速幂和逆元算法,并给出了问题的解析和解决方法。详细介绍了问题的背景和规则,并给出了相应的算法解析和实现步骤。通过本文的解析,读者可以更好地理解和解决Open judge C16H问题中的Magical Balls部分。 ... [详细]
  • JavaSE笔试题-接口、抽象类、多态等问题解答
    本文解答了JavaSE笔试题中关于接口、抽象类、多态等问题。包括Math类的取整数方法、接口是否可继承、抽象类是否可实现接口、抽象类是否可继承具体类、抽象类中是否可以有静态main方法等问题。同时介绍了面向对象的特征,以及Java中实现多态的机制。 ... [详细]
  • JDK源码学习之HashTable(附带面试题)的学习笔记
    本文介绍了JDK源码学习之HashTable(附带面试题)的学习笔记,包括HashTable的定义、数据类型、与HashMap的关系和区别。文章提供了干货,并附带了其他相关主题的学习笔记。 ... [详细]
  • 本文介绍了贝叶斯垃圾邮件分类的机器学习代码,代码来源于https://www.cnblogs.com/huangyc/p/10327209.html,并对代码进行了简介。朴素贝叶斯分类器训练函数包括求p(Ci)和基于词汇表的p(w|Ci)。 ... [详细]
  • 本文介绍了2015年九月八日的js学习总结及相关知识点,包括参考书《javaScript Dom编程的艺术》、js简史、Dom、DHTML、解释型程序设计和编译型程序设计等内容。同时还提到了最佳实践是将标签放到HTML文档的最后,并且对语句和注释的使用进行了说明。 ... [详细]
author-avatar
DREAM2502930781
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有