关键词不能为空

当前您在: 主页 > 英语 >

模态与非模态对话框的区别与操作

作者:高考题库网
来源:https://www.bjmy2z.cn/gaokao
2021-02-13 18:04
tags:

-

2021年2月13日发(作者:优点的英文)


模态对话框和非模态对话框的区别




假设对话框类名为


:CTestDlg


1,


如果是模态对话框


:



CTestDlg ctd;//


创建该对话框对像



le();



2,


如果是非模态的


:



CTestDlg *p_ctd= new CTestDlg();//


创建对话框的对像指针



p_ctd->Create(IDD_READING,this);//

< br>指针调用


Create()


函数


,ID


号为对话框



.

< p>
p_ctd->ShowWindow(SW_SHOWNA);//()


中的参数可以用来改变对话框的显示模式


(


具体参见

< p>
MSDN



ShowWindow()

< p>
函数


)



模态对话框 创建后一定要在用户单击完对话框上的



确定




取消


< /p>




关闭




就是对它进行了响应并关闭后


,


程序才能继续执行


.



而非模态的则是创建完后程序可以继续执行


,


对话框可以成为后 台对话框


.


所以


也可以用函数来关闭< /p>



p_ctd->DestroyWindow();


模态对话框就是指那种“显示出来就不可以点选位于其下面的对话框”的对话


框;反之的就是非模态对话框。



两者的区别:





.


非模态对话框的模板必须具有< /p>


Visible


风格


(Visible= True)



否则对话框将


不可见,< /p>


而模态对话框则无需设置该项风格。


在实际编程中更加保险的办法 是调



CWnd::ShowWindow(SW_SHOW)


来显示对话框,而不管对话框是否具有


Visible


风格。





.


非模态对话框对象是用


new


操作符来动态创建的,


而不是以成员变量 的形式


嵌入到别的对象中或以局部变量的形式构建的。


通常应在 对话框的拥有者窗口类


内声明一个指向对话框类的指针成员变量,通过该指针可访问对话 框对象。





.


通过调用


CDialog::Create


函数来启动对话框,


而不是


CDialog::DoModal



这是两者之间区别的关键所在。由于


Create


函数不会启动 新的消息循环,对话


框与应用程序共用同一个消息循环,这样对话框就不会垄断用户输入 。


Create


在显示了对话框后就立即返回,



DoModal


是在对话框被关闭后才返回的。


由于



Create


返回后,不能确定对话框是否已关闭,这样也就无法确定对话框对象


的生存期,


因此只好在堆栈中构建对话框对象,


而不能以局部变量的形式来构建< /p>


之。





.


必须调用


CWnd::DestroyWindow


而不是


CDial og::EndDialog


来关闭非模态


对话框。调用


CWnd::DestroyWindow


是直接删除窗口的一般方法 。由于缺省的


CDialog::OnOK


< br>CDialog::OnCancel


函数均调用


End Dialog


,故程序员必须编


写自己的


OnOK



OnCancel


函数并 且在函数中调用


DestroyWindow


来关闭对话


框。





.


因为是用


new


操作符构建非模态对话框对象,


因此必须在对话框关闭 后,



delete


操作符删除对话框 对象。在屏幕上一个窗口被删除后,框架会调用


CWnd::PostNcDestro y


,这是一个虚拟函数,程序可以在该函数中完成删除窗口


对象 的工作,具体代码如下



void CModelessDialog::PostNcDestroy


{delete this; //


删除对象


}


这样,


在删除屏幕上的对话框后,


对话框对象将被自动删除。< /p>


拥有者就不必显式


地调用


delete< /p>


来删除对话框对象了。





.


必须有一个标志表明非模态对话 框是否打开的。


这样做的原因是用户有可能


在打开一个模态对话 框的情况下,


又一次选择打开命令。


程序根据标志来决定是


打开一个新的对话框,


还是仅仅把原来打开的对话框激活。


通常可以用拥有者窗


口中的指向对话框对象的指针作为这种标志,


当对话框关闭时,


给该指针赋


NULL


值,以表明对话框对象已不存在了。



例如:



创建模态对话框



CTestDlg dlg;


l();


创建非模态对话框



CTestDlg * dlg = new CTestDlg;


dlg->Create(IDD_TEST_DLG);


dlg->ShowWindow(SW_SHOW);


使用 非模态对话框与使用模态对话框相似,但是也有一些重要的区别:


首先,非模态对话框通常包含一个标题列和一个系统菜单按钮。当您在


Develo per Studio


中建立对话框时,这些是内定选项。用于非模态对话框的对


话框模板中的


STYLE


叙述形如:




STYLE WS_POPUP | WS_CAPTION | WS_SYSMENU | WS_VISIBLE


标题 列和系统菜单允许使用者,


使用鼠标或者键盘将非模态对话框移动到另一个


显示区域。


对于模态对话框,


您通常无须提供标题列 和系统菜单,


因为使用者不


能在其下面的窗口中做任何其它的事 情。



第二项重要的区别是:注意,在我们的范例


STYLE


叙述中包含有


WS_VISIBLE



式。



Developer


Studio


中,




Dialog


Propert ies



对话框的


< br>More


Styles



页面 卷标中选择此选项。如果省略了


WS_VISIBLE


,那么您 必须在


CreateDialog


呼叫之后呼叫


ShowWindow





hDlgModeless = CreateDialog ( . . . ) ;


ShowWindow (hDlgModeless, SW_SHOW)


如果您既没有包含


WS_VISIBLE


样式,又没有呼叫


ShowWindow


,那么非模态对话< /p>


框将不会被显示。


如果忽略这个事实,


那 么习惯于模态对话框的程序写作者在第


一次试图建立非模态对话框时,经常会出现问题。



第三项区别:


与模态对话框和消息框 的消息不同,


非模态对话框的消息要经过程


序式的消息队列。< /p>


要将这些消息传送给对话框窗口消息处理程序,


则必须改变消


息队列。方法如下:当您使用


CreateDialog

< p>
建立非模态对话框时,应该将从呼


叫中传回的对话框句柄储存在一个整体变 量(如


hDlgModeless


)中,并将消息


循环改变为:



while (GetMessage (&msg, NULL, 0, 0))


{


if


(hDlgModeless


==


0


||


!IsDialogMessage


(hDlgModeless,


&msg))


{


TranslateMessage (&msg)


DispatchMessage (&msg)


}


}


如果消息是 发送给非模态对话框的,


那么


IsDialogMessage


将它发送给对话框中


窗口消息处理程序,并传回


TRUE


(非


0


);否则,它 将传回


FALSE



0


)。只有


hDlgModeless



0


或者消息不是该对话框的消息时,才必须呼叫


Tra nslateMessage



DispatchMessag e


函数。如果您将键盘快捷键用于您的程


序窗口,那么消息循环 将如下所示:



while (GetMessage (&msg, NULL, 0, 0))


{


if (hDlgModeless == 0 || !IsDialogMessage (hDlgModeless, &msg))


{


if (!TranslateAccelerator (hwnd, hAccel, &msg))


{


TranslateMessage (&msg)


DispatchMessage (&msg)


}


}


}


由于整体变量被初始化为


0


,所以


hDlgModeless


将为


0


,直到建立对话框为止,


从而保证不会使用无效的窗口句柄来呼叫


IsDialogMessage



在清除非 模态对话


框时,您也必须注意这一点,正如最后一点所说明的。



hDlgModeless


变量也可以由程序的其它部分使用, 以便对非模态对话框是否存


在加以验证。例如,程序中的其它窗口可以在


hDlgModeless


不等于


0

< br>时给对话


框发送消息。



最后一 项重要的区别:


使用


DestroyWindow


而不是


EndDialog


来结束非模态对话


框。当您呼叫


DestroyWindow


后 ,将


hDlgModeless


整体变量设定为


0




使用者习惯于从系统菜 单中选择「


Close


」来结束非模态对话框。尽管启用了



Close



选 项,


Windows


内的对话框窗口消息处理程序并不处理


WM_CLOSE


消息。


您必须自己在对话 框程序中处理它:




case WM_CLOSE :


DestroyWindow (hDlg)


hDlgModeless = NULL


break


注意这两个窗口句柄之间的区别:


Dest royWindow



hDlg


参数是 传递给对话框


程序的参数;


hDlgModeless


是从


CreateDialog


传回的整体变量 ,程序在消息循


环内检验它。



您也可 以允许使用者使用按键来关闭非模态对话框,处理方式与处理


WM_CLOSE


消息一样。对话框必须传回给建立它的窗口之任何数据都可以储存在整体变量

中。


如果不喜欢使用整体变量,


那么您也可以用

< p>
CreateDialogParam


来建立非模


态对话框,并按前面介绍的方法让它储存一个结构指针。





vc


模态和非模态对话框关闭过程


2009-09-16


11:52


非模态对话框相对于模态对


话框,他 的创建和销毁过程和模态对话框有一定的区别



< p>
先看一下


MSDN


的原文:




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.



MS


的指示:非 模态对话框需要重载函数


OnCanel


,并且在这个函数中调 用


DestroyWindow


。并且不能调用基类的


OnCancel


,因为基类的


OnCance l


调用了


EndDialog


这个函数 ,这个函数是针对模态对话框的。



还有一个必须重载的函数就 是


PostNcDestroy


,这也是一个虚函数,通常的非 模


态对话框是用类的指针,通过


new


创建的,这就需要在


PostNcDestroy


函数中


delete


掉这个指针。




了解了理论过后,


下面我们就可以用 代码实现一下非模态对话框的创建和销毁过



:


//


建立



//


主框架中:



CTestDlg *pDlg=new CTestDlg;


pDlg->Create(IDD_TESTDLG,this);


pDlg->ShowWindow(SW_SHOW);




//


对话框中:



void CTestDlg::OnCancel()


{


DestroyWindow();


}



void CTestDlg::PostNcDestroy()


{


CDialog::PostNcDestroy();


delete this;


}



如果要在点击按钮 的情况下,销毁非模态对话框,只需要把按钮的事件映射到


OnCancel

< p>
函数即可。




以下是一点资料供参考,非模态对话框的销毁顺序:




MFC


应用程序中处理消息的顺序




Proc()


该函数 负责接收消息,


找到消息所属的


CWnd


对象,


然后


调用


AfxCallWn dProc


-


-


-


-


-


-


-


-



本文更新与2021-02-13 18:04,由作者提供,不代表本网站立场,转载请注明出处:https://www.bjmy2z.cn/gaokao/651812.html

模态与非模态对话框的区别与操作的相关文章