对话框
一、CDialog/CDialogEx对话框类重载构造函数函数传参方式
DLayerSet::DLayerSet(CMapLayerList*
pLayerList,CWnd* pParent /*= NULL*/)
: CDialogEx(DLayerSet::IDD, pParent)
, m_bZDvisble(true), m_bQYvisble(true), m_bSHvisble(true), m_bRGvisble(true), m_bFTvisble(true), m_bNTvisble(true)
, m_bTYNvisble(true)
{
ASSERT(pLayerList);
if(m_MapLayerSet.GetCount() != 0)m_MapLayerSet.RemoveAll();
POSITION pos =pLayerList->GetHeadPosition();
while(pos != NULL)
{
CMapLayer* pLayer = pLayerList->GetNext(pos);
m_MapLayerSet.AddTail(pLayer);
}
}
//////这段代码最重要的是绿色部分,记得一定要加。否者会出现ASSERT错误: INT_PTR
CDialog::DoModal()中
//////ASSERT(m_lpszTemplateName != NULL ||
m_hDialogTemplate != NULL ||m_lpDialogTemplate != NULL)无法通过!!
模式对话框的销毁是使用EndDialog,而非模式对话框的销毁是使用DestroyWindow.。所以我们在销毁对话框的时候,也要对其进行区别。
非模式对话框,用户关闭对话框时,对话框消息处理函数将收到WM_CLOSE消息,接到后调用DestroyWindow以销毁非模式对话框。
模式对话框,则一般响应IDOK和IDCANCEL。在PPC上,我们对于OK键和X键的处理要注意这点。
二、模态对话框与非模态对话框
非模态对话框的模板必须具有Visible风格,否则对话框将不可见,而模态对话框则无需设置该项风格。更保险的办法是调用ShowWindow(hDialog, SW_SHOW)来显示对话框,而不管对话框是否具有Visible风格。
非模态对话框对象是用new操作符在堆中动态创建的,而不是以成员变量的形式嵌入到别的对象中或以局部变量的形式构建在堆栈上。通常应在对话框的拥有者窗口类内声明一个指向对话框类的指针成员变量,通过该指针可访问对话框对象。通过调用Create函数来启动对话框,而不是DoModal,这是模态对话框的关键所在。由于Create函数不会启动新的消息循环,对话框与应用程序共用同一个消息循环,这样对话框就不会垄断用户的输入。Create在显示了对话框后就立即返回,而DoModal是在对话框被关闭后才返回的。众所周知,在MFC程序中,窗口对象的生存期应长于对应的窗口,也就是说,不能在未关闭屏幕上窗口的情况下先把对应的窗口对象删除掉。由于在Create返回后,不能确定对话框是否已关闭,这样也就无法确定对话框对象的生存期,因此只好在堆中构建对话框对象,而不能以局部变量的形式来构建之。因为是用new操作符构建非模态对话框对象,因此必须在对话框关闭后,用delete操作符删除对话框对象。必须有一个标志表明非模态对话框是否是打开的。这样做的原因是用户有可能在打开一个模态对话框的情况下,又一次选择打开命令。程序根据 标志来决定是打开一个新的对话框,还是仅仅把原来打开的对话框激活。通常可以用拥有者窗口中的指向对话框对象的指针作为这种标志,当对话框关闭时,给该指 针赋NULL值,以表明对话框对象已不存在了。
注意:在C++编程中,判断一个位于堆中的对象是否存在的常用方法是判断指向该对象的指针是否为空。这种机制要求程序员将指向该对象的指针初始化为NULL值,在创建对象时将返回的地址赋给该指针,而在删除对象时将该指针置成NULL值。
|
模态 |
非模态 |
|
|
形式上 |
①一个模式对话框是一个有系统菜单、标题栏、边线等的弹出式窗口。 |
①一个无模式对话框是一个有系统菜单、标题栏、 |
|
创建 |
DoModal() |
Create() |
|
销毁 |
一个应用程序通过调用::EndDialog函数来销毁一个模式对话框。一般情况下,当用户从系统菜单里选择了关闭(Close)命令或者按下了确认(OK)或取消(CANCLE)按钮,::EndDialog被对话框过程所调用。调用::EndDialog时,指定其参数nResult的值,Windows将在销毁对话框窗口后返回这个值,一般,程序通过返回值判断对话框窗口是否完成了任务或者被用户取消。 |
在应用程序结束之前,它必须销毁所有的无模式对话框。使用::DestroyWindow销毁一个无模式对话框,不是使用::EndDiaLog。一般来说,对话框过程响应用户输入,如用户选择了“取消”按钮,则自动调用::DestroyWindow;如果用户没有有关动作,则应用程序必须调用::DestroyWindow。 |
非模态对话框的创建和销毁过程:
CTestDlg *pDlg=new
CTestDlg;pDlg->Create(IDD_TESTDLG,this);pDlg->ShowWindow(SW_SHOW);
void
CTestDlg::OnCancel()
{
DestroyWindow();
}
void
CTestDlg::PostNcDestroy()
{
CDialog::PostNcDestroy();
delete
this;//////一般非模态都是由new创建的,要用delete销毁
}
MFC应用程序中处理消息的顺序
1.AfxWndProc()
该函数负责接收消息,找到消息所属的CWnd对象,然后调用AfxCallWndProc
2.AfxCallWndProc()
该函数负责保存消息(保存的内容主要是消息标识符和消息参数)供应用程序以后使用,然后调用WindowProc()函数
3.WindowProc()
该函数负责发送消息到OnWndMsg()函数,如果未被处理,则调用DefWindowProc()函数
4.OnWndMsg()
该函数的功能首先按字节对消息进行排序,对于WM_COMMAND消息,调用OnCommand()消息响应函数,对于WM_NOTIFY消息,调用OnNotify()消息响应函数。任何被遗漏的消息将是一个窗口消息。OnWndMsg()函数搜索类的消息映像,以找到一个能处理任何窗口消息的处理函数。如果OnWndMsg()函数不能找到这样的处理函数的话,则把消息返回到WindowProc()函数,由它将消息发送给DefWindowProc()函数
5.OnCommand()
该函数查看这是不是一个控件通知(lParam参数不为NULL,如果lParam参数为空的话,说明该消息不是控件通知),如果它是,OnCommand()函数会试图将消息映射到制造通知的控件;如果他不是一个控件通知(或者如果控件拒绝映射的消息)OnCommand()就会调用OnCmdMsg()函数
6.OnCmdMsg()
根据接收消息的类,OnCmdMsg()函数将在一个称为命令传递(Command
Routing)的过程中潜在的传递命令消息和控件通知。 例如:如果拥有该窗口的类是一个框架类,则命令和通知消息也被传递到视图和文档类,并为该类寻找一个消息处理函数
MFC应用程序创建窗口的过程
1.PreCreateWindow() 该函数是一个重载函数,在窗口被创建前,可以在该重载函数中改变创建参数 (可以设置窗口风格等等)
2.PreSubclassWindow() 这也是一个重载函数,允许首先子分类一个窗口
3.OnGetMinMaxInfo() 该函数为消息响应函数,响应的是WM_GETMINMAXINFO消息,允许设置窗口的最大或者最小尺寸
4.OnNcCreate()
该函数也是一个消息响应函数,响应WM_NCCREATE消息,发送消息以告诉窗口的客户区即将被创建
5.OnNcCalcSize()
该函数也是消息响应函数,响应WM_NCCALCSIZE消息,作用是允许改变窗口客户区大小
6.OnCreate()
该函数也是一个消息响应函数,响应WM_CREATE消息,发送消息告诉一个窗口已经被创建
7.OnSize()
该函数也是一个消息响应函数,响应WM_SIZE消息,发送该消息以告诉该窗口大小已经发生变化
8.OnMove()
消息响应函数,响应WM_MOVE消息,发送此消息说明窗口在移动
9.OnChildNotify()
该函数为重载函数,作为部分消息映射被调用,告诉父窗口即将被告知一个窗口刚刚被创建
MFC应用程序关闭窗口的顺序(非模态窗口)
1.OnClose()
消息响应函数,响应窗口的WM_CLOSE消息,当关闭按钮被单击的时候发送此消息
2.OnDestroy()
消息响应函数,响应窗口的WM_DESTROY消息,当一个窗口将被销毁时,发送此消息
3.OnNcDestroy() 消息响应函数,响应窗口的WM_NCDESTROY消息,当一个窗口被销毁后发送此消息
4.PostNcDestroy() 重载函数,作为处理OnNcDestroy()函数的最后动作,被CWnd调用
MFC应用程序中打开模式对话框的函数调用顺序
1.DoModal()
重载函数,重载DoModal()成员函数
2.PreSubclassWindow() 重载函数,允许首先子分类一个窗口
3.OnCreate()
消息响应函数,响应WM_CREATE消息,发送此消息以告诉一个窗口已经被创建
4.OnSize()
消息响应函数,响应WM_SIZE消息,发送此消息以告诉窗口大小发生变化
5.OnMove()
消息响应函数,响应WM_MOVE消息,发送此消息,以告诉窗口正在移动
6.OnSetFont()
消息响应函数,响应WM_SETFONT消息,发送此消息,以允许改变对话框中控件的字体
7.OnInitDialog()
消息响应函数,响应WM_INITDIALOG消息,发送此消息以允许初始化对话框中的控件,或者是创建新控件
8.OnShowWindow()
消息响应函数,响应WM_SHOWWINDOW消息,该函数被ShowWindow()函数调用
9.OnCtlColor()
消息响应函数,响应WM_CTLCOLOR消息,被父窗口发送已改变对话框或对话框上面控件的颜色
10.
OnChildNotify() 重载函数,作为WM_CTLCOLOR消息的结果发送
MFC应用程序中关闭模式对话框的顺序//////自动完成
1.OnClose()
消息响应函数,响应WM_CLOSE消息,当"关闭"按钮被单击的时候,该函数被调用
2.OnKillFocus()
消息响应函数,响应WM_KILLFOCUS消息,当一个窗口即将失去键盘输入焦点以前被发送
3.OnDestroy()
消息响应函数,响应WM_DESTROY消息,当一个窗口即将被销毁时,被发送
4.OnNcDestroy()
消息响应函数,响应WM_NCDESTROY消息,当一个窗口被销毁以后被发送
5.PostNcDestroy() 重载函数,作为处理OnNcDestroy()函数的最后动作被CWnd调用
打开无模式对话框的顺序
1.PreSubclassWindow()
重载函数,允许用户首先子分类一个窗口
2.OnCreate()
消息响应函数,响应WM_CREATE消息,发送此消息以告诉一个窗口已经被创建
3.OnSize()
消息响应函数,响应WM_SIZE消息,发送此消息以告诉窗口大小发生变化
4.OnMove()
消息响应函数,响应WM_MOVE消息,发送此消息以告诉窗口正在移动
5.OnSetFont()
消息响应函数,响应WM_SETFONT消息,发送此消息以允许改变对话框中控件的字体
以上这些的执行都是按给定的顺序执行!
三、颜色对话框
CColorDialog
dlg;
dlg.m_cc.Flags
|= CC_FULLOPEN |
CC_RGBINIT;
dlg.m_cc.rgbResult
= m_refColor;
if(dlg.DoModal()==IDOK)
m_refColor
= dlg.m_cc.rgbResult;
四、字体对话框
pFontDlg = new
CFontDialog(&(m_pZDLayer->LogFont),CF_SCREENFONTS/*|CF_EFFECTS*/);
if(IDOK ==
pFontDlg->DoModal())
memcpy(&(m_pZDLayer->LogFont),pFontDlg->m_cf.lpLogFont,sizeof(LOGFONT));
delete
pFontDlg;pFontDlg = NULL;
五、文件对话框
CFileDialog
imgFile(true,NULL,m_strImgPath,OFN_HIDEREADONLY,"Image Files(*.ico;*.bmp;*.png)|*.ico;*.bmp;*.png|ALL
File(*.*)|*.*||",
NULL,0,true);
if(IDOK ==
imgFile.DoModal())
m_strImgPath
=
imgFile.GetPathName();
六、BOOL UpdateData( BOOL
bSaveAndValidate = TRUE );
TRUE
控件—>变量
FALSE 变量—>控件
它的范围是你调用它的类所代表的框架中生效。
1.用于数据交换的DoDataExchange函数是不能被直接调用的,必须通过调用UpdateData()函数来调用DoDataExchange函数。所以在用到控件与关联的成员变量交换数据时,要首先调用UpdateData()函数。
2.当模态对话框被创建时,在OnInitialDialog()函数里Framework自动的调用UpdateData(FALSE)。而且在默认的接口函数OnOk()里也调用了该函数UpdateData(TRUE)来获取数据,如果调用成功,将会关闭对话框。
七、ScreenToClient()
m_ZDShow.GetWindowRect(&m_rectZDShow);
//在对话框中涉及到绘图操作时,切切不要忘记进行转换,否则出错!!!!!
ScreenToClient(m_rectZDShow);
CPen
pen1(LineStyle,LineWidth,Color);
dc.SelectObject(&pen1);
dc.MoveTo(m_rectZDShow.left+5,m_rectZDShow.top+m_rectZDShow.Height()/4);
dc.LineTo(m_rectZDShow.right-7,m_rectZDShow.top+m_rectZDShow.Height()/4);

浙公网安备 33010602011771号