MFC模态和非模态对话框编程

合集下载

VS2010MFC编程入门之十二(对话框:非模态对话框的创建及显示)

VS2010MFC编程入门之十二(对话框:非模态对话框的创建及显示)

上一节鸡啄米讲了模态对话框及其弹出过程,本节接着讲另一种对话框--非模态对话框的创建及显示。

鸡啄米已经说过,非模态对话框显示后,程序其他窗口仍能正常运行,可以响应用户输入,还可以相互切换。

鸡啄米会将上一讲中创建的Tip模态对话框改为非模态对话框,让大家看下效果。

非模态对话框的对话框资源和对话框类实际上,模态对话框和非模态对话框在创建对话框资源和生成对话框类上是没有区别的,所以上一讲中创建的IDD_TIP_DIALOG对话框资源和CTipDlg类都不需要修改。

创建及显示非模态对话框的步骤需要修改的是,对话框类实例的创建和显示,也就是之前在CAdditionDlg::OnBnClick edAddButton()函数体中添加的对话框显示代码。

下面是具体步骤:1.在AdditionDlg.h中包含CTipDlg头文件并定义CTipDlg类型的指针成员变量。

详细操作方法是,在AdditionDlg.cpp中删除之前添加的#include "TipDlg.h",而在AdditionDlg.h中添加#include "TipDlg.h",这是因为我们需要在AdditionDlg.h中定义CTipDlg类型的指针变量,所以要先包含它的头文件;然后在AdditionDlg.h中为CAdditionDlg类添加private成员变量CTipDlg *m_pTipDlg;。

2.在CAdditionDlg类的构造函数中初始化成员变量m_pTipDlg。

如果cpp文件中函数太多,我们可以在Class View上半个视图中找到CAdditionDlg类,再在下半个视图中找到其构造函数双击,中间客户区域即可马上切到构造函数的实现处。

在构造函数体中添加m_ pTipDlg = NULL;,这是个好习惯,鸡啄米在C++编程入门系列的指针的赋值和指针运算中说到过,在任何指针变量使用前都初始化,可以避免因误访问重要内存地址而破坏此地址的数据。

MFC 模态对话框的实现原理

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:用于从消息队列读取消息。

mfc模态和非模态对话框编程

mfc模态和非模态对话框编程

MFC模态和非模态对话框编程1. CDialog是从CWnd派生的。

对话框有两种类型:模态和非模态。

★模态和非模态区别:当我们显示一个模态对话框时,应用程序会暂停,即点击其他菜单或者别的不会执行,会出现警告的那种声音。

直到关闭模态对话框,应用程序才会继续执行其他任务。

2. 在创建好一个新的对话框时,系统会已定义好2个方法。

● 构造函数:调用父类的构造函数,传入自己的IDD● DoDataExchange:完成对话框数据的交换和校验3. 模态对话框的显示和关闭CDialog::DoModal和CDialog::EndDialog程序示例:void CMyboleView::OnDiadlog(){// TODO: Add your command handler code hereCTestDlg dlg;dlg.DoModal();}4. 非模态对话框的创建CDialog::CreateBOOL Create( LPCTSTR lpszTemplateName, CWnd* pParentWnd = NULL );BOOL Create( UINT nIDTemplate, CWnd* pParentWnd = NULL );默认参数为NULL,就是父窗口是框架类。

程序示例:void CMyboleView::OnDiadlog(){// TODO: Add your command handler code hereCTestDlg dlg;dlg.Create(IDD_DIALOG1,this);dlg.ShowWindow(SW_SHOW);}PS:注意要用ShowWindow显示对话框。

问题:程序执行后,对话框还是没显示出来。

为什么?这里的CTestDlg dlg;我们是定义成局部变量的。

但是当这个函数执行完了,就会销毁dlg 的。

那为什么模态可以呢?这就是刚才我们说的创建模态对话框时,程序会暂停在那的原因导致的。

第六章 MFC与对话框编程

第六章  MFC与对话框编程
对分组框、静态文本框仅设置其标题(caption)属性 对编辑框(文本框)仅设置其ID属性 对一组单选按钮,每个单选按钮都设置其标题(caption)属性, 但仅设置该组第一个单选按钮的ID属性,仅选中该组第一 个单选按钮的Group属性和Tabstop属性 对复选框,设置其ID属性和标题(caption)属性 对组合框,设置其ID属性、初始化列表项和类型属性 对列表框,设置其ID属性、初始化列表项 对按钮,设置其ID属性和标题(caption)属性
一个创建模式对话框的实例(11 )
运行对话框
void CRegisterView::OnEditRegister() { CRegisterDialog dlg(this); if (dlg.DoModal()==IDOK) { CString str; GetWindowText(str); str+="姓名:"+dlg.m_strName+"\r\n"; str+="性别:";str+=dlg.m_nSex?"女":"男";str+="\r\n"; str+="婚否:";str+=dlg.m_bMarried?"已婚":"未婚";str+="\r\n"; str+="就业:";str+=dlg.m_nWork?"下岗":"在职";str+="\r\n"; str+="工作单位:"; str+=dlg.m_strUnit; str+="\r\n"; str+="单位性质:"; str+=dlg.m_strKind; str+= "\r\n"; str+="工资收入:"; str+=+dlg.m_strIncome; str+= "\r\n"; SetWindowText(str); } 在RegisterView.cpp文件的开头加入 #include "RegisterDialog.h" }

MFC编程常用API总结 - Copy

MFC编程常用API总结 - Copy

MFC编程常用一、对话框[ 1 ]CDialogEx::UpdateDate()函数原型:Bool UpdateData(Bool bSaveAndValidate = true);其中参数表示传输方向;true表示从控件传给变量,false表示从变量传给控件,默认是true。

[ 2 ]设置Tab顺序在资源视图中打开”Format”->”Tab Order”,或者快捷键Ctrl+D。

[ 3 ]模态对话框与非模态对话框a)模态对话框:当其弹出后,本应用程序其它窗口将不再接受用户输入,只有其响应结束退出后,其它窗口才能继续交互。

b)非模态对话框:当其弹出后,其它窗口可以与用户交互。

[ 4 ]属性页对话框a)CPropertyPage类继承与CDialog类,用于处理某个单个的属性页。

因此每个属性页都创建了一个继承CPropertyPage的子类。

构造函数:CPropertyPage();explicit CPropertyPage(UINT nIDTemplate, //属性页的对话框资源IDUINT nIDCaption=0, //属性页对话框选项卡的标题ID,若为0表示选项卡的标题就是属性页对话框的标题DWORD dwSize=sizeof(PROPSHEETPAGE))explicit CPropertyPage(LPCTSTR lpszTemplateName,//属性页对话框资源的名称字符串,非NULLUINT nIDCaption=0,DWORD dwSize=sizeof(PROPSHEETPAGE))函数void CancelToClose()功能:将属性页上的“OK”按钮改为“Close”按钮,并禁用“Cancel”按钮。

函数SetModified()功能:激活或禁用“Apply”按钮。

void SetModified(BOOL bChanged = true);可重载的消息处理函数OnApply:处理属性页的“Apply”按钮被单击的消息。

MFC之模态与非模态对话框的创建与销毁

MFC之模态与非模态对话框的创建与销毁

的话,则把消息返回到WindowProc()函数,由它将消息发送给DefWindowProc()函数;
5、OnCommand() 该函数查看这是不是一个控件通知(lParam参数不为NULL,如果lParam参数为空的话,说明该消息不是控件通知),如果它是,OnCommand()函数会试图将消
======================================================================
MFC非模态窗口的创建过程:
1、PreCreateWindow() 该函数是一个重载函数,在窗口被创建前,可以在该重载函数中改变创建参数 (可以设置窗口风格等);
5、PostNcDestroy() 重载函数,作为处理OnNcDestroy()函数的最后动作被CWnd调用。
##############################################################################
附:MFC应用程序中处理消息的顺序
6、OnSetFont() 消息响应函数,响应WM_SETFONT消息,发送此消息,以允许改变对话框中控件的字体;
7、OnInitDialog() 源自 消息响应函数,响应WM_INITDIALOG消息,发送此消息以允许初始化对话框中的控件,或者是创建新控件;
8、OnShowWindow() 消息响应函数,响应WM_SHOWWINDOW消息,该函数被ShowWindow()函数调用;
8、OnMove() 消息响应函数,响应WM_MOVE消息,发送此消息说明窗口在移动;
9、OnChildNotify() 该函数为重载函数,作为部分消息映射被调用,告诉父窗口即将被告知一个窗口刚刚被创建。

MFC对话框几个对话框程序例子建立对话框与相应程序相关联

MFC对话框几个对话框程序例子建立对话框与相应程序相关联

MFC对话框和对话框类几个对话框程序例子建立对话框与相应的程序相关联如何建立对话框与相应的程序相关联:在MFC中,对资源的操作都是建立相关的类来完成的;所以我门先NEW 一个对话框资源然后建立他的类与相应的应用程序相关联就可以;步骤:1 NEW 一个对话框资源2 在资源上选择 Classwarrzd上创建一个新的类(或在资源上双击左键)3 起名字!(注意文件名将会去掉C 例如我门的名字叫 CDaiDlg那么文件名是 DaiDlg);对话框的俩种类型:1 模态对话框(特性:当建立模态对话框时,将不允许用户点击对话框以外的控件后应用程序本身,也就是说当模态对话框建立时应用程序停止运行而只运行对话框,所以模态对话框是可以使用局部变量的定义方法的!)模态对话框是比较方便的一种对话框~建立函数:int CDialog::DoMadol() //注意他是CDialog类成员也就是说想使用先建立一个 CDialog 对象吧如果我门想要在View类中建立一个 CDialog对象不要忘了要在View的Cpp 文件中包含 CDialog.h2 非模态对话框(特性与模态的相反)使用成员函数 BOOL CDialog::Create( UINT nIDTemplate, CWnd* pParentWnd = NULL );nIDTemplate 为对话框的ID号pParentWnd 拥有这个对话框的对象指针,如果是NULL 为默认的主应用窗口也就是 Frame应用窗口注意如果我门在使用Create创建非模态对话框时要调用一个函数来显示这个对话框CWnd::ShowWindow(SW_SHOW);不仅这样非模态对话框时不能是局部变量!完整代码: CDialog dlg;dlg.Create(ID,this);dlg.ShowWindow(SW_SHOW):对ShowWindow的发现: ShowWindow是CWnd的成员函数是改变窗口的显示属性(包括Hide Show等)ShowWindow这一函数是改变属性同样在创建一个窗口时(窗口包括很多,CButton也是一个窗口!)可以直接给他赋予属性 WS_VISIBLE (可见的)等属性也可以解决改变窗口之后更新窗口的问题显示出新窗口的问题~!对于俩种对话框的销毁;模态对话框中OnOK的成员函数中有对模态对话框的 EndDialog();来销毁而非模态的对话框时 OnOK不能销毁对话框而我门需要对OnOK函数进行覆盖调用DestryWindow;做一个对话框的小程序,在对话框上动态增加一个按钮:在这要强调一下动态的增加某种资源是需要把资源对象声明成类的成员这样才可以(不然被析构了建立了也就没有效果了)而资源对象是对象资源是资源只有吧资源和对象联系起来这个的东西才有实际的意义,我门才能对他进行操作,而把资源和对象联系起来有俩个函数 LoadMenu 和CreateMenu (当然有些类是不存在 Load函数的例:Button类) Load函数是将一个已经被我门在资源视图中创建好的东西与对象联系而Create函数是直接创立一个新的东西(而直接创立时我门还需要给他一些这样东西的属性所以使用Create函数时总是件另人讨厌的事情~)更重要的事情是:一个对象只能与一个资源相联系如果你想把这个已与资源联系的对象与另一个资源联系起来那必须先调用DestoryWindow()这个资源然后在做新的联系;静态文本框的操作:刚刚建立的静态文本框是不可以做消息响应的(一般也不需要这么去做)而我门想要去用静态文本框的消息就要改边文本框的 ID (因为一般不给文本框添加消息响应文本框的的ID都是一样的)并且要把属性->样式(Styles)->通告(Notify)打上对号!!几个有用的函数:获得窗口的文本CWnd::int GetWindowText(CString &str);CWnd::int GetWindowText( LPTSTR lpszStringBuf, int nMaxCount ) const; 参数str是放置文本的对象!lpszStringBuf是一个字符串的指针,nMaxCount 到大的最大字符数同样使用 SetWindowText(CString str)SetWindowText(LPCTSTR lpszString);来设置文本获得对话框上控件的指针(控件包括了Button,静态文本等等!)CWnd::CWnd* GetDlgItem( nID )使用ID号来获取控件的指针!从而进行操作!从编辑框得到数据的几种操作1 使用GetDlgItem( nID )->GetWindowText( )然后把字符转换为我门所要的东西(使用 atoi,itoa 的转换函数)这几个函数所要注意的问题使用函数前一定要确定这个函数是对谁操作!对谁操作要获取谁的指针!!GetWindowText(LPTSTR lpszStringBuf, int nMaxCount )这个函数参数lpszStringBuf所要存储的指针 nMaxCount 是最大得到多少个字符~使用代码例子:char str[10];GetDlgItem( nID )->GetWindowText(str,10 );//注意第一个参数使用的是指针aoti itoa 函数介绍:(介绍前的感想,做ACM时看到程序就要将程序分成一个一个功能函数,然后将功能函数做好,从来没有想过使用他人做好的函数,而现在学习了MFC这套教程,养成的第一个习惯就是寻找自己想要的函数在MSDN中,然后再自己编写算是一种偷懒的行为吧,估计在以后的编程中,也要养成先寻找和想要的类模型差不多的类然后在通过继承派生来得到想要的类模型,这可能就是代码重用的本质吧 ~ MS就是一大堆会偷懒的编程员 ~呵呵)double atof( const char *string );int atoi( const char *string );__int64 _atoi64( const char *string );long atol( const char *string );这四个函数不用多说了,要注意的就是参数的问题,不要看参数名字叫 string 就是一个CString 成员而是 char*(指针) 也就是数组的名字返回型是相应转化的数据类型;(这是一个不错的函数)不过要注意他是需要包含头文件Routine Required Header Compatibilityatof <math.h> and <stdlib.h> ANSI, Win 95, Win NTatoi <stdlib.h> ANSI, Win 95,Win NT_atoi64 <stdlib.h> Win 95, Win NTatol <stdlib.h> ANSI, Win 95, Win NT还可以反过来 itoa, ftoa等等做一个介绍char *_itoa( int value, char *string, int radix );value要转换的数char *string 一个buffer 接受转换后的字符串int radix 十进制啊二进制 ...==(还有这里的 atoi 的 a 是ASCII的 A 这就解释了为什么不是ctoi~)2 使用函数GetDlgItemText( nID,LP... ),SetDlgItemText(nID,LP...)(这函数不仅长的象 GetDlgItem 和 GetWindowText 的混合体功能更是相同...又个偷懒的杰作!)int GetDlgItemText( int nID, LPTSTR lpStr, int nMaxCount ) const;int GetDlgItemText( int nID, CString& rString ) const;void SetDlgItemText( int nID, LPCTSTR lpszString ); 使用也是一样的!比那个能方便点~!3 又一个混合体函数 GetDlgItemInt();; SetDlgItemInt()在2的基础上来atoi都不用了!UINT CWnd:: GetDlgItemInt( int nID, BOOL* lpTrans = NULL, BOOL bSigned = TRUE ) const;nID ID号lpTrans 如果NULL 那么不会给出错误的提示bSigned 是否是有符号的数字(就是是否去转化符号“-”) TRUE就是有符号啦!!void SetDlgItemInt( int nID, UINT nValue, BOOL bSigned = TRUE ); nValue 是你想要在DlgItem输出的数字;4 使用资源来关联变量的方式来控制数据交换(这才是重点,因为他不只提供了对数据错误的提示功能还增加了控件与资源的联系当然我门需要了解框架所带给我门的东西;)在控件上使用ClassWarrzd 选择第2个选项卡!(Member Variables)对相应的 ID 号进行资源与数据的联系:观察一下ClassWarrzd给我门在代码里家了些什么:1 在头文件中加了// Dialog Data//{{AFX_DATA(CTextDlg)enum { IDD = IDD_DIALOG1 };int m_num1;int m_num2;int m_num3;//}}AFX_DATA这是数据交换的宏2 在构造函数里给这几个成员变量初始化://{{AFX_DATA_INIT(CTextDlg)m_num1 = 0;m_num2 = 0;m_num3 = 0;//}}AFX_DATA_INIT3 在void CTextDlg::DoDataExchange(CDataExchange* pDX)函数中增加了数据交换声明{CDialog::DoDataExchange(pDX);//{{AFX_DATA_MAP(CTextDlg)DDX_Text(pDX, IDC_EDIT1, m_num1);DDX_Text(pDX, IDC_EDIT2, m_num2);DDX_Text(pDX, IDC_EDIT3, m_num3);//}}AFX_DATA_MAP}对与 void CTextDlg::DoDataExchange(CDataExchange* pDX) 的使用用来数据交换!!这个函数是被框架调用,用来交换和验证数据的函数!这个函数从来不被直接掉用而是通过调用UpdateData()函数来调用这个函数来交换和验证数据的(这句的意思是DoDataExchange 接口是不对我门开放的我门想要掉用 DoDataExchange这个函数必须用UpdateData()来间接调用)BOOL UpdateData( BOOL bSaveAndValidate = TRUE );介绍:参数问题:bSaveAndValidate=TRUE 时数据开始交换(也就是说我门对该变量的操作是生效的)而当他是 FALSE 时数据不再交换而是初始化这个函数(也就是把这个变量的操作失效不过可以在屏幕上进行显示!)通过改变这个参数的值我门可以控制数据的交换或是数据的显示~这是很重要的;!错误的数字使得我门的操作成为无效;~还要说的一点是当创建的是模态对话框时(DoModal)时系统会自动把这个参数变成 FALSE 也就是说我门初始时是不能改变变量的例子代码: UpdateData();m_num3=m_num1+m_num2;UpdateData(FALSE);//我门也可以让控件关联一个控件变量然后在调用他的成员函数进行操作(教程里有讲不过觉得有些多余,也许在其他类型的程序中可能要有用,注意这种方法ClassWarrzd的使用方法)函数 SendMessage( );(注意是SendMessage 而不是SetMessage)是一个发送消息的函数使用....不详,查查SDK API什么的吧~ 功能很强大static LRESULT SendMessage( HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam )关于SendMessage()函数的说明发送一个响应的消息message,然后用wParam,lParam来接受我门想要的东西(当然这个要取决于我门发的是什么消息现在已知的消息是:WM_SETTEXT,WM_GETTEXT去MSDN 看看)而SendMessage 在API 和 MFC 中都有要注意是谁调用他的原始问题;SendMessage()的变种(向对话框中的子控件发送消息):LRESULT SendDlgItemMessage( int nID, UINT message, WPARAM wParam = 0, LPARAM lParam = 0 ); 用法基本相同对于获取编辑框复选的操作:向编辑框发送一个 EM_GETSEL (同样也是 EM_SETSEL) 要使用SendMessage()来发送//还要注意的是我门已经把复选设置好了有的时候也是看不见效果的,因为我门在操作时点击了按钮或者其他的操作使得焦点没有在我门所设置那个Item上所以我门是看不见结果的我门还要增加一个操作是用函数改变焦点:CWnd* CWnd::SetFocus( );没有参数返回值是以前那个带有焦点的指针;(对与复选最常用的是复选所有的东西,这样我门要把 SendMessage 的wParam =0,lParam =-1)总结:怎么样改变对话框的大小用来增加新的功能?对话框的矩形坐标可以利用一个图形控件和 SetWindowPos 来改变先要知道对话框的矩形坐标通过控件得到(GetWindowRect())矩形坐标 ...这样我门就能知道需要改变什么矩形坐标了void GetWindowRect( LPRECT lpRect ) const; 函数参数 lpRect 用来储存矩形坐标BOOL SetWindowPos( const CWnd* pWndInsertAfter, int x, int y, int cx, int cy, UINT nFlags ); 本来是用来改变Window Z-order 的(什么是 Z-order简单说就是显示窗口的顺序)在 79 710 俩课中使用的SDK 函数不再介绍(因为不明白!!)使用default按钮的特性来增加对话框对回车(0x0d)按键响应的操作我门用一个设置输入焦点随回车变化的例子来说明;因为在重载OnOK函数时 OnOK还是会调用基类的 OnOK函数(OnOK函数会自动关闭对话框)而我门不希望我门在输入回车时关闭对话框所以我门将它转化为注释!然后使用函数获取当前焦点的句并 Wnd* GetFocus( )来选择GetNextWindow(UINT nFlag = GW_HWNDNEXT )然后在使用SetFocus( );完整代码:(在Dialog中的 OnOK 函数中)GetFocus()->GetNextWindow()->SetFocus();这个代码逻辑上是可以的,不过执行起来会发生错误,如果一直回车下去回造成程序崩溃;(哪有那么都 GetNext呀?)我门要使用Tab功能的函数来完成这个功能就不会出错了~CWnd* GetNextDlgTabItem( CWnd* pWndCtl, BOOL bPrevious = FALSE ) const;pWndCtl开始时的窗口bPrevious = FALSE 向下走;如何查看 Tab 顺序:布局(layout)-> Tab顺序(Tab Order)OK按钮不管存在不存在都会执行 OnOK函数他的ID 号是IDOK(不是ID_OK 哦)孙鑫MFC教程笔记(菜单.对话框)2007-08-11 20:03对话框先要对消息的传送进行分析:消息分为三类标准消息,命令消息,通告消息;标准消息:是除WM_COMMAND以外的所有以WM_开头的消息(WM_Char,WM_Move 等)命令消息:WM_COMMAND 包括了来自菜单、加速键或工具栏按钮的消息。

讲座四 VS2010(MFC)编程--几种常见对话框

讲座四 VS2010(MFC)编程--几种常见对话框

VS2010(MFC)编程--几种对话框VS2010/MFC编程:模态对话框及其弹出过程加法计算器对话框程序大家照着做一遍后,相信对基于对话框的程序有些了解了,有个好的开始对于以后的学习大有裨益。

趁热打铁,这一节讲讲什么是模态对话框和非模态对话框,以及模态对话框怎样弹出。

一.模态对话框和非模态对话框Windows对话框分为两类:模态对话框和非模态对话框。

模态对话框是这样的对话框,当它弹出后,本应用程序其他窗口将不再接受用户输入,只有该对话框响应用户输入,在对它进行相应操作退出后,其他窗口才能继续与用户交互。

非模态对话框则是,它弹出后,本程序其他窗口仍能响应用户输入。

非模态对话框一般用来显示提示信息等。

大家对Windows系统很了解,相信这两种对话框应该都遇到过。

之前的加法计算器对话框其实就是模态对话框。

二.模态对话框是怎样弹出的毕竟加法计算器程序大部分都是MFC自动生成的,对话框怎么弹出来的大家可能还不是很清楚。

下面简单说说它是在哪里弹出来的,再重新建一个新的对话框并弹出它,这样大家实践以后就能更灵活的使用模态对话框了。

大家打开Addition.cpp文件,可以看到CAdditionApp类有个InitInstance()函数,在MFC应用程序框架分析中提到过此函数,不过那是单文档应用程序App类中的,函数体不太相同,但都是进行App类实例的初始化工作。

InitInstance()函数的后半部分有一段代码就是定义对话框对象并弹出对话框的,下面给出这段代码并加以注释:C++代码弹出对话框比较关键的一个函数,就是对话框类的DoModal()函数。

CDialog::DoModal()函数的原型为:virtual INT_PTR DoModal();返回值:整数值,指定了传递给CDialog::EndDialog(该函数用于关闭对话框)的nResult 参数值。

如果函数不能创建对话框,则返回-1;如果出现其它错误,则返回IDABORT。

MFC 对话框编程 -- 总结

MFC 对话框编程 -- 总结

MFC 对话框编程 -- 总结一、创建对话框对象1.首先利用资源编辑器创建对话框资源,并针对该对话框资源定义一个对话框类:class CTestDlg : public CDialog2.创建话话框对象模态对话框的创建:如:CTestDlg dlg;dlg.DoModal();非模态对话框创建:如:CTestDlg dlg;dlg.Create(IDD_DIALOG, this);但这样是得不到一个正常显示的非模态对话框的。

因为模态与非模态对话框的实现方式并不相同,这里我们还要注意几点。

非模态对话框创建完成后是隐藏着的,必须调用ShowWindow来进行显示。

对于模态对话框,当执行到DoModal 函数以创建对话框时,程序会暂停执行,直至模态对话框关闭。

所以创建模态对话框可以采用局部对象。

但是,对于非模态对话框,当执行Create函数时并不会暂停执行,当执行到大括号"}后Dlg局部对象被销毁生命周期结束,于是异常出现了。

解决方法有两个:一、在View类中定义一个CTestDlg 成员变量。

二、动态创建一个CTestDlg 变量,并重写CTestDlg 类的 PostNcDestroy函数,在该函数里销毁对象 delete this;无论创建的是模态对话框,还是非模态对话框,当我们单击确定或取消按钮后对话框都会消失。

但这时低层的操作却是不同的。

对于模态对话框,此时对话框对象的确是被销毁了,但对于非模态对话框,这时只是隐藏起来不再显示。

这需要我们自己调用DestoryWindow函数来进行销毁工作。

这时我们必须重写 CTestDlg 的 OnOK 、 OnCancel 两个函数(这两个是基类CDialog的虚函数),在这两个函数内调用DestroyWindow函数,并注意不再调用基类CDialog相应的函数。

正确地创建非模态对话框的代码如下:CTestDlg *pDlg = new CTestDlg;pDlg->Create(IDD_DIALOG, this);pDlg->ShowWindow(SW_SHOW);同时,在CTestDlg 类的 PostNcDestroy函数中销毁对象:delete this;二、动态创建按钮1. 在对话框类CTestDlg 中定义一个 CButton 类对象,作为其成员变量。

mfcdll显示非模态对话框问题(转)

mfcdll显示非模态对话框问题(转)

mfcdll显示非模态对话框问题(转)
在mfc dll的InitInstance()方法中创建对话框实力并且进行显示,但是窗体会一闪而过,
CDLGTEST *dlg;
BOOL CTestApp::InitInstance()
{
dlg=new CDLGTEST;
dlg->Create(IDD_DIA_TEST);
dlg->ShowWindow(SW_SHOWNORMAL);
return CWinApp::InitInstance();
}
后来查阅资料说是得加入消息循环,代码如下:
CDLGTEST *dlg;
BOOL CTestApp::InitInstance()
{
dlg=new CDLGTEST;
dlg->Create(IDD_DIA_TEST);
dlg->ShowWindow(true);
while(::GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return CWinApp::InitInstance();
}
似乎问题还是解决不了,一闪而过的问题没了,但是这样下来被注入的程序(记事本无响应),注入程序也是无响应,有相应的只有IDD_DIA_TEST窗体,好像主线程进入了while后,一直在处理消息问题,后来用线程来处理消息循环,更是得不到消息信息,困扰几天的问题,实在解决不了了,还请师哥师姐们多多指点。

小弟万分感激。

谢谢。

MFC-重写对话框

MFC-重写对话框

MFC-重写对话框1.对话框分分类:模态对话框和非模态对话框两种。

2.模态对话框创建流程:(MFC-单文档)a.添加对话框资源:(Insert->Resource ->Dialog->New),对话框的ID为IDD_DIALOG1;b.为对话框资源创建个新类,名字为:CTextc.添加菜单,名字为:模态对话框,ID为:IDM_DLG ,用类向导在view类中添加函数,代码如下:{CText dlg; //添加头文件:#include "Text.h"dlg.DoModal();}3.非模态对话框创建流程:(MFC-单文档)a.添加对话框资源:(Insert->Resource ->Dialog->New),对话框的ID为IDD_DIALOG1;b.为对话框资源创建个新类,名字为:CTextc.添加菜单,名字为:非模态对话框,ID为:IDM_DLG ,用类向导在view类中添加函数,代码如下:{CText *dlg=new CText;dlg->Create(IDD_DIALOG1,this);dlg->ShowWindow(SW_NORMAL);}d. 销毁窗口:重载OnOK和OnCancel函数,添加代码: this->DestroyWindow();* 注:要截断基类的OnOK和OnCancel函数,不要调用基类的OnOK和OnCancel函数。

e.释放内存:在CText类中增加PostNcDestory消息处理函数,在函数体中添加代码:deletethis;*注:PostNcDestory消息是窗口的最后一个消息,用来处理释放内存等工作;Create函数的第二个参数如果设为GetDesktopWindow(),则非模态对话框窗口就和此程序的窗口平级了,当弹出对话框时,你最小化应用程序窗口时,这个对话框并不最小化。

4.截断消息或屏蔽消息:PreTransMessage模态对话框和非模态对话框在消息处理之前都要先去PreTransMessage消息函数中报道,因此可以通过重载PreTransMessage消息处理函数去屏蔽或者处理一些消息,比如屏蔽回车键(条件为pMsg->wParam==VK_RETURN时,将函数返回真return true;就可以了)。

模态、非模态 MFC 调用一个新的 对话框

模态、非模态  MFC 调用一个新的 对话框

调用一个新的对话框的方法注意:这里是插入窗体。

一、模态对话框1) 首先,新建的一个对话框,假如为test2) 在刚才插入的子窗口添加消息映射函数void C***Dll::PostNcDestroy() ,在次函数里面添加:delete this;3) 在需要调用新建对话框的CPP 文件添加头文件#include "test.h"4) 然后在需要调用新建对话框的按钮的成员函数里写上:AFX_MANAGE_STATE(AfxGetStaticModuleState());test testDlg;testDlg.DoModal();二、非模态对话框1) 首先,插入一个窗体,假如为CFrmDl ;2) 在刚才插入的子窗口添加消息映射函数void C***Dll::PostNcDestroy() ,在次函数里面添加:delete this;3) 在需要调用新建对话框的CPP 文件添加头文件#include "FrmDll.h" ;4) 然后在需要调用新建对话框的按钮的成员函数里写上:AFX_MANAGE_STATE(AfxGetStaticModuleState());CFrmDll *dlg = new CFrmDll; // 在内存中new 出来dlg->Create(IDD_FRMDLLDlg); // 创建对话框,dlg->CenterWindow(); // 窗口居中dlg->ShowWindow(SW_SHOW); // 显示窗口非模态Dll 调用例子:typedef void ( * P_show)();HINSTANCE hinstance =NULL;void CTestDlgDlg::OnButton1(){if (hinstance ==NULL){hinstance = LoadLibrary ("dllPro.dll");}if(hinstance ==NULL){AfxMessageBox("Fail");return;}P_show show = (P_show)::GetProcAddress (hinstance,"showdlg");show();// FreeLibrary(hinstance); // 这个记得放在析构函数里面// hinstance = NULL; // 这个记得放在析构函数里面}。

创建MFC的无模式对话框

创建MFC的无模式对话框

创建MFC的⽆模式对话框MFC的⽆模式对话框与有模式对话框不同的是在创建后其他窗⼝都可以继续接收⽤户输⼊,⽽有模式对话框则类似于弹出警告信息。

因此⽆模式对话框有些类似⼀个弹出窗⼝。

MFC创建⽆模式对话框需要调⽤BOOL CDialog::Create( UINT nIDTemplate, CWnd* pParentWnd = NULL );之后还需要调⽤ BOOL CDialog::ShowWindow( SW_SHOW);进⾏显⽰,否则⽆模式对话框将是不可见的。

相关代码如下:void CYourView::OnOpenDlg(void){CTestDlg *dlg=new CTestDlg;dlg->Create(IDD_TEST_DLG,NULL);dlg->ShowWindows(SW_SHOW);}在上⾯的代码中我们新⽣成了⼀个对话框对象,⽽且在退出函数时并没有销毁该对象。

因为如果此时销毁该对象(对象被销毁时窗⼝同时被销毁),⽽此时对话框还在显⽰就会出现错误。

那么这就提出了⼀个问题:什么时候销毁该对象。

我时常使⽤的⽅法有两个:在对话框退出时销毁⾃⼰:在对话框中重载OnOK与OnCancel在函数中调⽤⽗类的同名函数,然后调⽤· 在对话框退出时销毁⾃⼰:DestroyWindow()强制销毁窗⼝,在对话框中映射WM_DESTROY消息,在消息处理函数中调⽤delete this;强⾏删除⾃⾝对象。

相关代码如下:· void CTestDlg1::OnOK()· {· CDialog::OnOK();· DestroyWindow();· }·· void CTestDlg1::OnCancel()· {· CDialog::OnCancel();· DestroyWindow();· }·· void CTestDlg1::OnDestroy()· {· CDialog::OnDestroy();· AfxMessageBox("call delete this");· delete this;· }这种⽅法的要点是在窗⼝被销毁的时候,删除⾃⾝对象。

MFC模态对话框和非模态对话框

MFC模态对话框和非模态对话框

MFC模态对话框和非模态对话框
.
分类: MFC2011-08-31 15:5425518人阅读评论(17)收藏举报
mfcdialogdelete编程
MFC中对话框有两种形式,一个是模态对话框(model dialog box),一个是非模态对话框(modeless dialog box)。
若和上面一样的方式创建一个非模态对话框:
[cpp] view plaincopy
01. CTestDialog td;
02.td.Create(IDD_DIALOG1); //创建一个非模态对话框
03.td.ShowWindow(SW_SHOWNORMAL); //显示非模态对话框
最后在所在类的析构函数中收回pTD所指向的内存:
(2)采用成员变量创建一个非模态对话框
首先在你所要编写的类的头文件中声明一个指针变量:
[cpp] view plaincopy
01.private:
02. CTestDialog *pTD;
然后再在相应的CPP文件,在你要创建对话框的位置添加如下代码:
那么,在运行时,你会发现此对话框无法显示。这是因为你声明的对话框变量td是局部变量,但这个函数返回时,td也被析构了,所以无法显示此对话框。
创建非模态对话框,必须声明一个指向CTestDialog类的指针变量,且需要显示的调用ShowWindow()才能将对话框显示出来。有两种创建方法:
[cpp] view plaincopy
01.//创建一个模态对话框
02.CTestDialog td;
03.td.DoModal();
其中CTestDialog为我自己所新建和一个对话框资源相关联的对话框类。

第11章 模态和非模态对话框

第11章  模态和非模态对话框

11.4.1 属性表对话框的创建
• 为了支持属性表对话框,MFC提供了 CPropertySheet类和CPropertyPage类。前者代表 对话框的框架,后者代表对话框中的某一页。 CPropertyPage是CDialog类的派生类,而 CPropertySheet是CWnd类的派生类。虽然 CPropertySheet不是CDialog类的派生类,但使用 CPropertySheet对象的方法与使用CDialog对象是 类似的。
11.5.3 文件对话框
• CFileDialog类用于实现文件选择对话框,以支持 文件的打开和保存操作。用MFC AppWizard建立的 文档/视图结构的应用程序中自动加入了文件选择 对话框,在文件菜单中执行“打开”或“另存为” 命令会启动它们。
11.5.4 字体对话框
• CFontDialog类支持字体对话框,用来让用户选择 字体。(具体内容请参照本书)
Байду номын сангаас第11章 对话框的应用
• 对话框是Windows应用程序中最重要的用户界面元 素之一,它是通过对话框上的各种控件来和用户 进行交互的。本章将详细介绍对话框的一般创建 流程,模态和非模态对话框的创建与使用以及属 性表对话框和公用对话框的使用方法。
11.1 对话框的工作方式、种类和创建方 法
• 与前面介绍的菜单、快捷键、图标、光标等界面 元素一样,对话框也是Windows程序的一种资源, 称作对话框模板。本节将详细介绍对话框在程序 中的工作方式、种类以及对话框模板的创建与编 辑。
11.2.2 为对话框类添加成员变量
• 要使对话框能与程序通讯,还需给对话框类增加 数据成员,以保存各控件的初始值,并从控件读 取数据。 • 与控件对应的数据成员有两种类型:变量类型和 控件类型。

MFC教程 对话框和对话框类CDialog

MFC教程 对话框和对话框类CDialog

12. 对话框和对话框类CDialog对话框经常被使用,因为对话框可以从模板创建,而对话框模板是可以使用资源编辑器方便地进行编辑的。

1. 模式和无模式对话框对话框分两种类型,模式对话框和无模式对话框。

1. 模式对话框一个模式对话框是一个有系统菜单、标题栏、边线等的弹出式窗口。

在创建对话框时指定WS_POPUP, WS_SYSMENU, WS_CAPTION和DS_MODALFRAME风格。

即使没有指定WS_VISIBLE风格,模式对话框也会被显示。

创建对话框窗口时,将发送WM_INITDIALOG消息(如果指定对话框的DS_SETFONT风格,还有WM_SETFONT消息)给对话框过程。

对话框过程(Dialog box procedure)不是对话框窗口的窗口过程(Windowprocedure)。

在Win32里,对话框的窗口过程由Windows系统提供,用户在创建对话框窗口时提供一个对话框过程由窗口过程调用。

对话框窗口被创建之后,Windows使得它成为一个激活的窗口,它保持激活直到对话框过程调用::EndDialog函数结束对话框的运行或者Windows激活另一个应用程序为止,在激活时,用户或者应用程序不可以激活它的所属窗口(Owner window)。

从某个窗口创建一个模式对话框时,Windows自动地禁止使用(Disable)这个窗口和它的所有子窗口,直到该模式对话框被关闭和销毁。

虽然对话框过程可以Enable所属窗口,但是这样做就失去了模式对话框的作用,所以不鼓励这样做。

Windows创建模式对话框时,给当前捕获鼠标输入的窗口(如果有的话)发送消息WM_CANCLEMODE。

收到该消息后,应用程序应该终止鼠标捕获(Release the mouse capture)以便于用户能把鼠标移到模式对话框;否则由于Owner窗口被禁止,程序将失去鼠标输入。

为了处理模式对话框的消息,Windows开始对话框自身的消息循环,暂时控制整个应用程序的消息队列。

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

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

模态对话框和非模态对话框的区别假设对话框类名为:CTestDlg1,如果是模态对话框:CTestDlg ctd;//创建该对话框对像ctd.DoModale();2,如果是非模态的:CTestDlg *p_ctd= new CTestDlg();//创建对话框的对像指针p_ctd->Create(IDD_READING,this);//指针调用Create()函数,ID号为对话框的.p_ctd->ShowWindow(SW_SHOWNA);//()中的参数可以用来改变对话框的显示模式(具体参见MSDN中ShowWindow()函数)模态对话框创建后一定要在用户单击完对话框上的"确定"或"取消"或"关闭",也就是对它进行了响应并关闭后,程序才能继续执行.而非模态的则是创建完后程序可以继续执行,对话框可以成为后台对话框.所以也可以用函数来关闭p_ctd->DestroyWindow();模态对话框就是指那种“显示出来就不可以点选位于其下面的对话框”的对话框;反之的就是非模态对话框。

两者的区别:一. 非模态对话框的模板必须具有Visible风格(Visible=True),否则对话框将不可见,而模态对话框则无需设置该项风格。

在实际编程中更加保险的办法是调用CWnd::ShowWindow(SW_SHOW)来显示对话框,而不管对话框是否具有Visible 风格。

二. 非模态对话框对象是用new操作符来动态创建的,而不是以成员变量的形式嵌入到别的对象中或以局部变量的形式构建的。

通常应在对话框的拥有者窗口类内声明一个指向对话框类的指针成员变量,通过该指针可访问对话框对象。

三. 通过调用CDialog::Create函数来启动对话框,而不是CDialog::DoModal,这是两者之间区别的关键所在。

由于Create函数不会启动新的消息循环,对话框与应用程序共用同一个消息循环,这样对话框就不会垄断用户输入。

第三讲、对话框与控件

第三讲、对话框与控件

3、 CFileDialog类

CFileDialog文件选择对话框如图5所示:

文件选择对话框的创建

TRUE:打开对话框 FALSE:存盘对话框
在堆栈上构建一个CFileDialog对象 CFileDialog::DoModal( )来启动对话框 文件对话框的构造函数
lpszDefExt = NULL, LPCTSTR lpszFileName = NULL, DWORD dwFlags = OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT, LPCTSTR lpszFilter = NULL, CWnd* pParentWnd = NULL );
从一个列表框中获得当前选择的文件、目录或驱动器
从一个组合框中获得当前选择的文件、目录或驱动器 返回指定的单选按钮组中被选择的单选按钮的ID 返回一个指向一给定的控件的临时对象的指针
GetDlgItemInt
GetDlgItemText GetNextDlgGroupItem GetNextDlgTabItem
CFileDialog( BOOL bOpenFileDialog, LPCTSTR
4、CFindReplaceDialog类
图6 Find对话框
图 7 Replace对话框

Find(搜索)和(Replace)替换对话框的创建



new操作符在堆中创建CFindReplaceDialog 对象 CFindReplaceDialog::Create函数启动 Find/Replace对话框 Create函数的声明
(6)增加对控件通知消息的处理

如给按钮添加BN_CLICKED 消息。
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

MFC模态和非模态对话框编程
1. CDialog是从CWnd派生的。

对话框有两种类型:模态和非模态。

★模态和非模态区别:
当我们显示一个模态对话框时,应用程序会暂停,即点击其他菜单或者别的不会执行,会出现警告的那种声音。

直到关闭模态对话框,应用程序才会继续执行其他任务。

2. 在创建好一个新的对话框时,系统会已定义好2个方法。

● 构造函数:调用父类的构造函数,传入自己的IDD
● DoDataExchange:完成对话框数据的交换和校验
3. 模态对话框的显示和关闭
CDialog::DoModal和CDialog::EndDialog
程序示例:
void CMyboleView::OnDiadlog()
{
// TODO: Add your command handler code here
CTestDlg dlg;
dlg.DoModal();
}
4. 非模态对话框的创建
CDialog::Create
BOOL Create( LPCTSTR lpszTemplateName, CWnd* pParentWnd = NULL );
BOOL Create( UINT nIDTemplate, CWnd* pParentWnd = NULL );
默认参数为NULL,就是父窗口是框架类。

程序示例:
void CMyboleView::OnDiadlog()
{
// TODO: Add your command handler code here
CTestDlg dlg;
dlg.Create(IDD_DIALOG1,this);
dlg.ShowWindow(SW_SHOW);
}
PS:注意要用ShowWindow显示对话框。

问题:程序执行后,对话框还是没显示出来。

为什么?
这里的CTestDlg dlg;我们是定义成局部变量的。

但是当这个函数执行完了,就会销毁dlg 的。

那为什么模态可以呢?
这就是刚才我们说的创建模态对话框时,程序会暂停在那的原因导致的。

相关文档
最新文档