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

模态对话框和⾮模态对话框Windows对话框分为两类:模态对话框和⾮模态对话框。
模态对话框,当它弹出后,本应⽤程序其他窗⼝将不再接受⽤户输⼊,只有该对话框响应⽤户输⼊,在对它进⾏相应操作退出后,其他窗⼝才能继续与⽤户交互。
(⽐如:word中的“另存为”)⾮模态对话框,它弹出后,本程序其他窗⼝仍能响应⽤户输⼊。
⾮模态对话框⼀般⽤来显⽰提⽰信息等。
(⽐如:word中的“查找与替换)创建模态对话框弹出对话框⽐较关键的⼀个函数,CDialog::DoModal()函数的原型为:virtual INT_PTR DoModal(); 返回值:整数值,指定了传递给CDialog::EndDialog(该函数⽤于关闭对话框)的nResult参数值。
如果函数不能创建对话框,则返回-1;如果出现其它错误,则返回IDABORT。
调⽤了它对话框就会弹出,返回值是退出对话框时所点的按钮的ID,⽐如,我们点了“退出”按钮,那么DoModal返回值为IDCANCEL。
就是对话框类的DoModal()函数。
注:CAdditionDlg 为新建对话框的类。
CAdditionDlg dlg; // 定义对话框类CAdditionDlg的对象dlg INT_PTR nResponse = dlg.DoModal(); // 弹出对话框dlg,并将DoModal函数的返回值(退出时点击按钮的ID)赋值给nResponseif (nResponse == IDOK) // 判断返回值是否为OK按钮{MessageBox(“ ”,””,MB_OK);}else if (nResponse == IDCANCEL) // 判断返回值是否为Cancel按钮{MessageBox(“ ”,””,MB_OK);}步骤:1. 在资源视图添加Dialog的对话框,再给对话框添加类CAdditionDlg。
2. 定义对话框类的对象CAdditionDlg m_dlg。
VS2010之MFC入门到精通教程(155全部)

VS2010/MFC编程入门教程之目录第一部分:VS2010/MFC开发环境第二部分:VS2010-MFC应用程序框架第三部分:对话框第四部分:常用控件第五部分:菜单、工具栏与状态栏第六部分:文档、视图和框架第七部分:MFC常用类第八部分:字体和文本输出第九部分:图形图像第十部分:Ribbon界面开发VS2010/MFC编程入门之前言鸡啄米的C++系列给大家讲了C++的编程入门知识,大家对C++语言在语法和设计思想上应该有了一定的了解了。
但是教程中讲的例子只是一个个简单的例程,并没有可视化窗口。
鸡啄米在这套VS2010/MFC编程入门教程中将会给大家讲解怎样使用VS2010进行可视化编程,也就是基于窗口的程序。
C++编程入门系列主要偏重于理论方面的知识,目的是让大家打好底子,练好内功,在使用VC++编程时不至于丈二和尚摸不着头脑。
本套教程也会涉及到VC++的原理性的东西,同样更重视实用性,让大家学完本套教程以后,基本的界面程序都能很容易编写出来。
VC++简介VC++全称是Visual C++,是由微软提供的C++开发工具,它与C++的根本区别就在于,C++是语言,而VC++是用C++语言编写程序的工具平台。
VC++不仅是一个编译器更是一个集成开发环境,包括编辑器、调试器和编译器等,一般它包含在Visual Studio中。
Visual Studio包含了VB、VC++、C#等编译环境。
当然我们在使用VC++ 6.0的时候为了轻便,总是只单独安装VC++ 6.0。
但自微软2002年发布Visual 以来,微软建立了在.NET框架上的代码托管机制,一个项目可以支持多种语言开发的组件,VC++同样被扩展为支持代码托管机制的开发环境,所以.NET Framework是必须的,也就不再有V C++的独立安装程序,不过可以在安装Visual Studio时只选择VC++进行安装。
VC++版本的选择:VS2010因为VC++ 6.0以后的版本不再有独立的安装程序,所以鸡啄米在教程中将不会称VC ++ 6.0以后的版本为VC++ 7.0等等,而是用VC++所属的Visual Studio的版本名称代替,比如VS2003。
C#show和showdialog区别

C#show和showdialog区别在C#中窗⼝的显⽰有两种⽅式:模态显⽰(showdialog)和⾮模态显⽰(show)。
区别:模态与⾮模态窗体的主要区别是窗体显⽰的时候是否可以操作其他窗体。
模态窗体不允许操作其他窗体,⾮模态窗体可以操作其他窗体。
模态显⽰后,弹出窗⼝阻⽌调⽤窗⼝的所有消息响应。
只有在弹出窗⼝结束后调⽤窗⼝才能继续。
在模态窗⼝“关闭”后,可以读取模态窗⼝中信息,包括窗⼝的返回状态,窗⼝⼦控件的值。
在调⽤Form.ShowDialog⽅法后,直到关闭对话框后,才执⾏此⽅法后⾯的代码窗体显⽰为模式窗体时,单击“关闭”按钮会隐藏窗体,并将DialogResult属性设置为DialogResult.Cancel与⽆模式窗体不同,当⽤户单击对话框的关闭窗体按钮或设置DialogResult属性的值时,不调⽤窗体的Close⽅法实际上是把窗体的Visible属性赋值为false,隐藏窗体了这样隐藏的窗体是可以重新显⽰,⽽不⽤创建该对话框的新实例因为未关闭窗体,所以在应⽤程序不再需要该窗体时,请调⽤该窗体的Dispose⽅法所以模态窗⼝在关闭时,不会调⽤close⽅法,也不调⽤dispose⽅法,窗⼝仍然存在,占有资源,所以可以继续获得窗⼝相关信息,在窗⼝不再使⽤时,需要⼿动释testDialog.ShowDialog(); // 模态窗⼝关闭后,可以再次显⽰出来testDialog.Dispose(); // 当模态窗⼝不再使⽤时,应该调⽤dispose⽅法释放资源⾮模态显⽰后,可以在弹出窗⼝和调⽤窗⼝之间随意切换。
调⽤窗⼝调⽤show⽅法后,下⾯的代码可以⽴即执⾏。
在⾮模态窗⼝关闭后,窗⼝的所有资源被释放,窗⼝不存在,⽆法获取窗⼝的任何信息。
怎么判断⼀个窗体是模式窗体呢?利⽤Form.Modal属性,如果该窗体是模式显⽰,则为true,否则为false根据通过Show和ShowDialog⽽显⽰出来的窗体的Modal属性分别对应false和true特别注意:由于在窗体创建之前是⽆法得知显⽰⽅式的,所以在窗体构造函数中,Modal属性总是对应false,所以我们只能在Load事件中或者之后利⽤Modal属性值怎么确定窗体间的所有者关系?Form类的Owner属性:窗体的所有者当⼀个窗体归另⼀窗体所有时,它便随着所有者窗体最⼩化和关闭。
MFC 模态对话框的实现原理

1. 模态对话框在涉及GUI程序开发的过程中,常常有模态对话框以及非模态对话框的概念模态对话框:在子界面活动期间,父窗口是无法进行消息响应。
独占用户输入非模态对话框:各窗口之间不影响主要区别:非模态对话框与APP共用消息循环,不会独占用户。
模态对话框独占用户输入,其他界面无法响应在用户层的主要逻辑如下:1 TestDlgdlg;23 if (dlg.DoModal() == IDOK)4 {5 //处理完毕后的操作6 }7 .......//后续处理在具体实现中,有如下几个步骤:1. 让父窗口失效EnableWindow(parentWindow, FALSE)2. 建立模态对话框自己的消息循环(RunModalLoop)3. 直至接收关闭消息,消息循环终止,并销毁窗口。
01 INT_PTR CDialog::DoModal()02 {03 //对话框资源加载04 ......0506 //在创建模态窗口之前先让父窗口失效,不响应键盘、鼠标产生的消息07 HWND hWndParent = PreModal();08 AfxUnhookWindowCreate();09 BOOL bEnableParent = FALSE;1011 if (hWndParent&&hWndParent != ::GetDesktopWindow() && ::IsWindowEnabled(hWndParent))12 {13 ::EnableWindow(hWndParent, FALSE);14 bEnableParent = TRUE;15 .......16 }1718 //创建模态窗口,并进行消息循环,若窗口不关闭,则循环不退出 19 AfxHookWindowCreate(this);20 VERIFY(RunModalLoop(dwFlags) == m_nModalResult);2122 //窗口关闭,销毁窗口23 DestroyWindow();24 PostModal();2526 //释放资源,并让父窗口有效27 pMainWnd->EnableWindow(TRUE);2829 //返回30 return m_nModalResult;31 }2. 模态窗口中的消息循环01 int CWnd::RunModalLoop(DWORD dwFlags)02 {03 //要检查窗口状态是否是模态窗口04 //若状态一直为模态,则一直进行消息循环05 for (;;)06 {07 ASSERT(ContinueModal());0809 // phase1: check to see if we can do idle work10 while (bIdle&&11 !::PeekMessage(pMsg, NULL, NULL, NULL, PM_NOREMOVE)) 12 {13 ASSERT(ContinueModal());1415 // show the dialog when the message queue goes idle 16 if (bShowIdle)17 {18 ShowWindow(SW_SHOWNORMAL);19 UpdateWindow();20 bShowIdle = FALSE;21 }2223 // call OnIdle while in bIdle state24 if (!(dwFlags& MLF_NOIDLEMSG) &&hWndParent != NULL &&lIdleCount == 0)25 {26 // send WM_ENTERIDLE to the parent27 ::SendMessage(hWndParent, WM_ENTERIDLE, MSGF_DIALOGBOX, (LPARAM)m_hWnd);28 }29 if ((dwFlags& MLF_NOKICKIDLE) ||30 !SendMessage(WM_KICKIDLE, MSGF_DIALOGBOX, lIdleCount++))31 {32 // stop idle processing next time33 bIdle = FALSE;34 }35 }3637 //在有消息的情况下取消息处理38 do39 {40 ASSERT(ContinueModal());4142 // pump message, but quit on WM_QUIT43 if (!AfxPumpMessage())44 {45 AfxPostQuitMessage(0);46 return -1;47 }4849 // show the window when certain special messages rec'd 50 if (bShowIdle&&51 (pMsg->message == 0x118 || pMsg->message == WM_SYSKEYDOWN))52 {53 ShowWindow(SW_SHOWNORMAL);54 UpdateWindow();55 bShowIdle = FALSE;56 }5758 if (!ContinueModal())59 goto ExitModal;6061 // reset "no idle" state after pumping "normal" message 62 if (AfxIsIdleMessage(pMsg))63 {64 bIdle = TRUE;65 lIdleCount = 0;66 }6768 } while (::PeekMessage(pMsg, NULL, NULL, NULL, PM_NOREMOVE));69 }7071 ExitModal:72 m_nFlags&= ~(WF_MODALLOOP|WF_CONTINUEMODAL);73 return m_nModalResult;74 } GetMessage 与PeekMessage 的区别:GetMessage:用于从消息队列读取消息。
VC++ 课件 第05章 对话框和常用控件

5.2控件的创建和使用方法
5.2.1控件的创建方法 控件的创建方式有以下两种: 一种是在对话框模板中用编辑器指定控件,也就是说,将控件的父窗口指 定为对话框,这样做的好处是明显的,因为当应用程序启动该对话框时, Windows系统就会为对话框创建控件;而当对话框消失时,控件也随之清 除。 另一种方式是将控件看作是任一窗口的子窗口,并通过调用相应的Create 函数来创建。 [例Ex_SDIHello] 在上例Ex_SDIHello的基础上用子窗口方式创建控件。 (1)打开CMyDlg的头文件MyDlg.h,添加一个按钮类CButton指针变量: class CMyDlg : public CDialog { // Construction public: CMyDlg(CWnd* pParent = NULL); // standard constructor CButton *m_btnWnd; … }
5.1对话框的使用
在程序中使用对话框 (1)利用项目工作区的ClassView标签项,将Ex_SDIHello.cpp源文件打开; (2)在Ex_SDIHello.cpp源文件的前面加上包含类CMyDlg的头文件: #include "MyDlg.h" (3)在InitInstance函数体中的“return TRUE;”语句之前添加下列代码: CMyDlg dlg; dlg.DoModal(); DoModal是模态对话框最常用的函数,它负责对话框的显示和终止。 (4)编译并运行。在程序的一开始就出现用户自己设计的对话框,单击 [Button1]按钮将弹出“欢迎进入对话框的设计!”的消息对话框来。
5.1对话框的使用
5.1.2使用对话框编辑器
打开对话框编辑器
将项目工作区窗口切换到ResourceView页面,双击Dialog目录下任意一个对 话框ID。或者,选择“Insert”“Resource”菜单命令(或按快捷键Ctrl+R), 选择Dialog项,单击New。
VC非模态对话框创建和销毁 模态对话和非模态话框识别

0x0001 // window is enabled for tooltips 0x0002 // window is temporarily hidden 0x0004 // window should stay disabled 0x0008 // currently in modal loop 0x0010 // modal loop should continue running 0x0100 // some descendant is an OLE control 0x0400 // window is enabled for tracking tooltips
如果拥有该窗口的类是一个框架类则命令和通知消息也被传递到视图和文档类并为该类寻找一个消息处理函数mfc应用程序创建窗口的过程1precreatewindow该函数是一个重载函数在窗口被创建前可以在该重载函数中改变创建参数可以设置窗口风格等等2presubclasswindow这也是一个重载函数允许首先子分类一个窗口3ongetminmaxinfo该函数为消息响应函数响应的是wmgetminmaxinfo消息允许设置窗口的最大或者最小尺寸4onnccreate该函数也是一个消息响应函数响应wmnccreate消息发送消息以告诉窗口的客户区即将被创建5onnccalcsize该函数也是消息响应函数响应wmnccalcsize消息作用是允许改变窗口客户区大小6oncreate该函数也是一个消息响应函数响应wmcreate消息发送消息告诉一个窗口已经被创建7onsize该函数也是一个消息响应函数响应wmsize消息发送该消息以告诉该窗口大小已经发生变化8onmove消息响应函数响应wmmove消息发送此消息说明窗口在移动9onchildnotify该函数为重载函数作为部分消息映射被调用告诉父窗口即将被告知一个窗口刚刚被创建mfc应用程序关闭窗口的顺序非模态窗口1onclose消息响应函数响应窗口的wmclose消息当关闭按钮被单击的时候发送此消息2ondestroy消息响应函数响应窗口的wmdestroy消息当一个窗口将被销毁时发送此消息3onncdestroy消息响应函数响应窗口的wmncdestroy消息当一个窗口被销毁后发送此消息4postncdestroy重载函数作为处理onncdestroy函数的最后动作被cwnd调用mfc应用程序中打开模式对话框的函数调用顺序1domodal重载函数重载domodal成员函数2presubclasswindow重载函数允许首先子分类一个窗口3oncreate消息响应函数响应wmcreate消息发送此消息以告诉一个窗口已经被创建4onsize消息响应函数响应wmsize消息发送此消息以告诉窗口大小发生变化5onmove消息响应函数响应wmmove消息发送此消息以告诉窗口正在移动6onsetfont消息响应函数响应wmsetfont消息发送此消息以允许改变对话框中控件的字体7oninitdialog消息响应函数响应wminitdialog消息发送此消息以允许初始化对话框中的控件或
模态窗口

对话框一般分为两种类型:模态类型(modal)与非模态类型(modeless)。
所谓模态对话框,就是指除非采取有效的关闭手段,用户的鼠标焦点或者输入光标将一直停留在其上的对话框。
非模态对话框则不会强制此种特性,用户可以在当前对话框以及其他窗口间进行切换。
本文介绍如何使用JavaScript语言来创建这两种类型的对话框、控制其大小和位置、改变其外观以及在对话框间的数据传递。
(引用)一、创建模态和非模态对话框创建模态对话框:(会缓存最近一次页面的值,通过一些设置可绕过系统的判断)vReturnValue = window.showModalDialog(sURL [, vFreeArgument] [, sOrnaments]);创建非模态对话框:(不会)vReturnValue = window.showModelessDialog(sURL [, vFreeArgument] [, sOrnaments]);· VReturnValue:对于showModalDialog(),它表示被打开的对话框窗口设置的returnValue 属性值。
对于showModelessDialog(),它表示新窗口对象。
· VFreeArgument:这个参数可用于传递某种类型的数据到打开的对话框,数据可以是一个数值、字符串、数组或者一个对象类型。
在新窗口中引用这个数值时,可通过新创建window 对象的dialogArguments 属性。
· SOrnaments:用这个参数指定新窗口的外观。
可选择的窗口属性有很多种,当有多种控制需求时,将相关内容用一个字符串连接起来,其间用分号隔开。
以下是可选择的属性种类:o dialogHeight: sHeighto dialogLeft: sXposo dialogTop: sYposo dialogWidth: sWidtho center: ( yes | no | 1 | 0 | on | off )o dialogHide: ( yes | no | 1 | 0 | on | off )o edge: ( sunken | raised )o help: ( yes | no | 1 | 0 | on | off )o resizable: ( yes | no | 1 | 0 | on | off )o scroll: ( yes | no | 1 | 0 | on | off )o status: ( yes | no | 1 | 0 | on | off )二、控制对话框大小和位置三、改变对话框外观四、从Noname1.html页面传递数据到Noname2.html页面传递对象类型数据<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"><HTML><HEAD><TITLE>模态窗口和非模态窗口</TITLE><script language="javascript">var sColor="yyyy";var sName="xmddl369";function showModalWindow(){window.showModalDialog('Noname2.html',window,'dialogWidth:400px;dialogHeight:400p x');}function showModellessWindow(){window.showModelessDialog('Noname2.html',window,'dialogWidth:400px;dialogHeight:40 0px;edge:sunken');}function update(){oColor.innerText = sColor;}document.write("sColor="+sColor+"<br>");document.write("sName="+sName+"<br>");</script></HEAD><BODY><form><input type="button" name="button" value="打开一个模态窗口" onclick="showModalWindow ()"><input type="button" name="button" value="打开一个非模态窗口" onclick="showModelless Window()"><BR><P>输入你最喜欢的颜色: <SPAN ID="oColor" STYLE="color:red;font-size:24">Yellow</SPA N></P></form></BODY></HTML>-------------------<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"><HTML><HEAD><TITLE> New Document </TITLE><script language="javascript">function getInfoAndUpdate() {var callerWindowObj = dialogArguments; //得到文档的引用callerWindowObj.sColor = document.all("oEnterColor").value;callerWindowObj.update();}function cancel() {var callerWindowObj = dialogArguments;callerWindowObj.sColor = "Yellow";callerWindowObj.update();}</script></HEAD><BODY><form>输入你最喜欢的颜色:<INPUT type="text" name="oEnterColor" ID="oEnterColor"><BR><B R><INPUT VALUE="Apply" TYPE=button onclick="getInfoAndUpdate();"><INPUT VALUE="Ok" TYPE=button onclick="getInfoAndUpdate();window.close();"><INPUT VALUE="Cancel" TYPE=button onclick="cancel();window.close();"></form></BODY></HTML>传递数组引用类型数据<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"><HTML><HEAD><TITLE>模态窗口和非模态窗口</TITLE><script language="javascript">var fruit=new Array();fruit[0]="苹果";fruit[1]="桔子";fruit[2]="梨";fruit[3]="香蕉";function showModalWindow(){window.showModalDialog('Noname2.html',fruit,'dialogWidth:400px;dialogHeight:400px'); }function showModellessWindow(){window.showModelessDialog('Noname2.html',fruit,'dialogWidth:400px;dialogHeight:400px; edge:sunken');}</script></HEAD><BODY><form><input type="button" name="button" value="打开一个模态窗口" onclick="showModalWindow ()"><input type="button" name="button" value="打开一个非模态窗口" onclick="showModelless Window()"><BR></form></BODY></HTML>------------------<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"><HTML><HEAD><TITLE> New Document </TITLE><SCRIPT LANGUAGE="JScript">function deWrite(){var myobject=document.getElementById("ifruit");var myfruit=dialogArguments;for(count=0;count<myfruit.length;count++){var oOption = document.createElement("OPTION");oOption.text=myfruit[count];oOption.value=/count;myobject.add(oOption);}}</SCRIPT></HEAD><BODY><form><input type="button" name="button" value="click me" onclick="deWrite()"><br>增加水果:<SELECT ID="ifruit" NAME="ifruit"></SELECT></form></BODY></HTML>传递值类型数据<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"><HTML><HEAD><TITLE>模态窗口和非模态窗口</TITLE><script language="javascript">function showModalWindow(){window.showModalDialog('Noname2.html',"xmddl",'dialogWidth:400px;dialogHeight:400p x');}function showModellessWindow(){window.showModelessDialog('Noname2.html',"xmddl369",'dialogWidth:400px;dialogHeight: 400px;edge:sunken');}</script></HEAD><BODY><form><input type="button" name="button" value="打开一个模态窗口" onclick="showModalWindow ()"><input type="button" name="button" value="打开一个非模态窗口" onclick="showModelless Window()"><BR></form></BODY></HTML>------------------<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"><HTML><HEAD><TITLE> New Document </TITLE><SCRIPT LANGUAGE="JScript">function deWrite(){var names=dialogArguments;//document.write(names);}</SCRIPT></HEAD><BODY><form><input type="button" name="button" value="click me" onclick="deWrite()"></form></BODY></HTML>其中window.Open(url,,)的一点体会<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"><HTML><HEAD><TITLE> New Document </TITLE><script language="javascript">function showOpenWindow(){window.open('','xmddl','height=600px,width=800px,toolbar=no,menub ar=no,resizable=yes, scrollbars=yes, location=no, status=no');}</script></HEAD><BODY><form><input type="button" name="button" value="click me" onclick="showOpenWindow()"></form></BODY></HTML>//在Url的地方可以跟上一个.do的请求,基于struts架构时可以链接到某一个具体的页面,体现了窗口作为显示的作用//在模态窗口打开新窗口在模态窗口的head部分添加如下代码<base targat='_self'>。
模态对话框ModalDialogBox

简化操作步骤
通过模态对话框,将登录或注册表单直接展示在当前页面, 用户无需跳转页面即可完成操作,提高用户体验。
引导用户关注
模态对话框的弹出效果能够吸引用户的注意力,引导用户 关注登录或注册流程,提高转化率。
灵活定制界面
模态对话框允许开发者自定义界面样式和内容,可以根据实际需 求调整登录或注册表单的布局和元素,提高用户体验和可用性。
浏览器兼容性处理
针对不同浏览器及其版本,采用相应的CSS前缀、JavaScript兼容性方案等,确保模态对话框在 各浏览器中的正常显示和功能。
移动端适配
使用移动端开发框架或组件库,如React Native、Weex等,实现模态对话框在移动端设备上的 良好体验。
04
模态对话框在Web应用中实 践
登录注册流程优化
交互设计技巧
引导用户关注
通过动画效果、颜色变化等 手段引导用户关注模态对话
框中的重要信息。
提供撤销操作
在对话框中提供撤销操作选 项,以便用户在做出选择后 能够撤销操作,减少误操作
的风险。
考虑无障碍访问
确保模态对话框符合无障碍 访问标准,以便所有用户都 能轻松使用。例如,为对话 框添加适当的aria标签和键盘 导航支持等。
感谢您的观看
THANKS
03
模态对话框实现技术
前端开发技术栈
HTML/CSS/JavaScript
构建模态对话框的基本结构和样式,实现交互功能。
React/Vue/Angular等前端框架
提供组件化开发方式,方便快速构建模态对话框组件。
UI组件库
如Ant Design、Element UI等,提供现成的模态对话框组件,可快速集成到项目中。