首页 > 代码库 > MFC对话框

MFC对话框

 

创建对话框步骤:

第一,创建对话框资源,主要包括创建新的对话框模板、设置对话框属性和为对话框添加各种控件;

第二,生成对话框类,主要包括新建对话框类、添加控件变量和控件的消息处理函数等。

 

创建对话框类 Add Class…

 

添加成员变量 Add Variable,类的成员变量名一般以m_打头。

控件与变量数据交换和检验:

DoDataExchange(),需要在程序中调用CDialogEx::UpdateData()函数,由UpdateData()函数再去自动调用DoDataExchange()的。

CDialogEx::UpdateData()函数的原型为:

?
1
2
3
4
5
6
<font face="微软雅黑">BOOL UpdateData(BOOL bSaveAndValidate = TRUE);
 
参数:bSaveAndValidate用于指示数据传输的方向,<strong>TRUE表示从控件传给变量,FALSE表示从变量传给控件</strong>。默认值是TRUE,即从控件传给变量。
 
返回值:CDialogEx::UpdateData()函数的返回值表示操作是否成功,成功则返回TRUE,否则返回FALSE。
</font>

添加消息处理函数:

?
1
<font face="微软雅黑">方法一:Class Wizard</font>
?
1
<font face="微软雅黑">方法二:Add Event Handler...</font>
?
1
<font face="微软雅黑">方法三:控件的属性视图中添加消息处理函数</font>
?
1
<font face="微软雅黑">方法四:双击按钮控件添加消息处理函数</font>
?
1
<font face="微软雅黑"></font> 
?
1
<font face="微软雅黑">创建好消息处理函数,就可以在函数体内编写代码实现功能。</font>
?
1
<font face="微软雅黑"></font> 

设置控件Tab顺序

?
1
<font face="微软雅黑">在主菜单中选择“Format”->"Tab Order",或者按快捷键Ctrl+D,对话框模板上就会显示各个控件的Tab顺序数字:</font>
?
1
<font face="微软雅黑">从自己认为Tab顺序应该为1的控件开始依次单击,随着单击的完成,各控件的Tab响应顺序也按我们的想法设置好了。</font>
?
1
<font face="微软雅黑"></font> 

模态与非模态

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

非模态对话框则是,它弹出后,本程序其他窗口仍能响应用户输入。非模态对话框一般用来显示提示信息等。

 

?
1
2
3
4
5
6
7
CDialog::DoModal()函数的原型为:
 
virtual INT_PTR DoModal();   
 
返回值:整数值,指定了传递给CDialog::EndDialog(该函数用于关闭对话框)的nResult参数值。如果函数不能创建对话框,则返回-1;如果出现其它错误,则返回IDABORT。
 
调用了它对话框就会弹出,返回值是退出对话框时所点的按钮的ID,比如,我们点了“退出”按钮,那么DoModal返回值为IDCANCEL。

 

属性页对话框

属性页对话框就是包含一般属性页对话框和向导对话框两类。它将多个对话框集成于一身,通过标签或按钮来切换页面。

我们使用属性页对话框时,用到的类主要有两个:CPropertyPage类和CPropertySheet类。

CPropertyPage类

CPropertyPage类继承自CDialog类,它被用于处理某单个的属性页,所以要为每个属性页都创建一个继承自CPropertyPage的子类。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
(1)构造函数
 
        这里讲三个CProperty类的构造函数,函数原型为:
 
        CPropertyPage( );
 
        explicit CPropertyPage(
                UINT nIDTemplate,
                UINT nIDCaption = 0,
                DWORD dwSize = sizeof(PROPSHEETPAGE)
        );
 
        explicit CPropertyPage(
                LPCTSTR lpszTemplateName,
                UINT nIDCaption = 0,
                DWORD dwSize = sizeof(PROPSHEETPAGE)
        );
 
第一个是没有任何参数的构造函数。
 
第二个构造函数中,参数nIDTemplate是属性页的对话框资源ID,参数nIDCaption是属性页对话框选项卡的标题所用字符串资源的ID,若设为0,则选项卡标题就使用该属性页的对话框资源的标题。
 
第三个构造函数中,参数lpszTemplateName为属性页的对话框资源的名称字符串,不能为NULL。参数nIDCaption同上。
 
(2)CancelToClose()函数
 
在模态属性页对话框的属性页进行了某不可恢复的操作后,使用CancelToClose()函数将“OK”按钮改为“Close”按钮,并禁用“Cancel”按钮。函数原型为:
 
       void CancelToClose( );
 
(3)SetModified()函数
 
调用此函数可激活或禁用“Apply”按钮,函数原型为:
 
       void SetModified(BOOL bChanged = TRUE);
 
(4)可重载函数
 
可重载的消息处理函数包括:
 
       OnApply:处理属性页的“Apply”按钮被单击的消息
       OnCancel:处理属性页的“Cancel”按钮被单击的消息
       OnKillActive:处理属性页当前活动状态被切换的消息,常用于数据验证
       OnOK:处理属性页的“OK”按钮、“Apply”按钮或者“Close”按钮被单击的消息
       OnQueryCancel:处理属性页的“Cancel”按钮被单击前发出的消息
       OnReset:处理属性页的“Reset”按钮被单击的消息
       OnSetActive:处理属性页被切换为当前活动页的消息
       OnWizardBack:处理属性页的“Next”按钮被单击的消息,仅在向导对话框中有效
       OnWizardFinish:处理属性页的“Finish”按钮被单击的消息,仅在向导对话框中有效
       OnWizardNext:处理属性页的“下一步”按钮被单击的消息,仅在向导对话框中有效

CPropertySheet类

CPropertySheet类继承自CWnd类,它是属性表类,负责加载、打开或删除属性页,并可以在属性页对话框中切换属性页。它跟对话框类似,也有模态和非模态两种。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
(1)构造函数
 
  这里依然列出CPropertySheet类的三个构造函数:
 
  CPropertySheet( );
 
  explicit CPropertySheet(
          UINT nIDCaption,
          CWnd* pParentWnd = NULL,
          UINT iSelectPage = 0
  );
 
  explicit CPropertySheet(
          LPCTSTR pszCaption,
          CWnd* pParentWnd = NULL,
          UINT iSelectPage = 0
  );
 
  参数nIDCaption:标题的字符串资源的ID。
 
  参数pParentWnd:属性页对话框的父窗口,若设为NULL,则父窗口为应用程序的主窗口。
 
  参数iSelectPage:初始状态时,活动属性页的索引,默认为第一个添加到属性表的属性页。
 
  参数pszCaption:标题字符串。
 
 (2)GetActiveIndex()函数
 
  获取当前活动属性页的索引。函数原型为:
 
  int GetActiveIndex( ) const;
 
  返回值:当前活动属性页的索引。
 
 (3)GetActivePage()函数
 
  获取当前活动属性页对象。函数原型为:
 
  CPropertyPage* GetActivePage( ) const;
 
  返回值:当前活动属性页对象的指针。
 
 (4)GetPage()函数
 
  获取某个属性页对象。函数原型为:
 
  CPropertyPage* GetPage(int nPage) const;
 
  参数nPage:目标属性页的索引。
 
  返回值:目标属性页对象的指针。
 
 (5)GetPageCount()函数
 
  获取属性页的数量。函数原型为:
 
  int GetPageCount( ) const;
 
  返回值:属性页的数量。
 
 (6)GetPageIndex()函数
 
  获取某属性页在属性页对话框中的索引。函数原型为:
 
  int GetPageIndex(CPropertyPage* pPage);
 
  参数pPage:要获取索引的属性页对象的指针。
 
  返回值:属性页对象在属性页对话框中的索引。
 
 (7)SetActivePage()函数
 
  设置某个属性页为活动属性页。函数原型为:  
 
  BOOL SetActivePage(
            int nPage
  );
 
  BOOL SetActivePage(
            CPropertyPage* pPage
  );
 
  参数nPage:要设置为活动属性页的索引。
 
  参数pPage:要设置为活动属性页的对象指针。
 
 (8)SetWizardButtons()函数
 
  在向导对话框上启用或禁用Back、Next或Finish按钮,应在调用DoModal之前调用此函数。函数原型为:
 
  void SetWizardButtons(
           DWORD dwFlags
  );
 
  参数dwFlags:设置向导按钮的外观和功能属性。可以是以下值的组合:
 
  PSWIZB_BACK                    启用“Back”按钮,如果不包含此值则禁用“Back”按钮。
  PSWIZB_NEXT                    启用“Next”按钮,如果不包含此值则禁用“Next”按钮。
  PSWIZB_FINISH                  启用“Finish”按钮。
  PSWIZB_DISABLEDFINISH   显示禁用的“Finish”按钮。
 
 (9)SetWizardMode()函数
 
  设置属性页对话框为向导对话框模式,应在调用DoModal之前调用此函数。函数原型为:
 
  void SetWizardMode( );
 
 (10)SetTitle()函数
 
  设置属性对话框的标题。函数原型为:
 
  void SetTitle(
          LPCTSTR lpszText,
          UINT nStyle = 0
  );
 
  参数lpszText:标题字符串。
 
  参数nStyle:指定属性表标题的风格。应当为0或PSH_PROPTITLE。如果设为PSH_PROPTITLE,则单词“Properties”会出现在指定标题之后。例如,SetTitle("Simple",PSH_PROPTITLE)这种调用会使得属性表标题为“Simple Properties”。
 
 (11)AddPage()函数
 
  为属性对话框添加新的属性页。函数原型为:
 
  void AddPage(
          CPropertyPage *pPage
  );
 
  参数pPage:要添加的新的属性页的对象指针。
 
 (12)PressButton()函数
 
  模拟按下某指定的按钮。函数原型为:  
 
  void PressButton(
          int nButton
  );
 
  参数nButton:要模拟按下的按钮,它可以是下列值之一:
 
  PSBTN_BACK   选择“Back”按钮。
  PSBTN_NEXT   选择“Next”按钮。
  PSBTN_FINISH   选择“Finish”按钮。
  PSBTN_OK   选择“OK”按钮。
  PSBTN_APPLYNOW   选择“Apply”按钮。
  PSBTN_CANCEL   选择“Cancel”按钮。
  PSBTN_HELP   选择“帮助”按钮。
 
 (13)RemovePage()函数
 
  删除某属性页。函数原型为:
 
  void RemovePage(
          CPropertyPage *pPage
  );
 
  void RemovePage(
          int nPage
  );
 
  参数pPage:要删除的属性页的对象指针。
 
   参数nPage:要删除的属性页的索引。
?
1
  
?
1
创建属性页对话框
?
1
创建属性页类:基类CPropertyPage,关联对话框资源
?
1
创建属性表类:基类CPropertySheet,用来容纳属性表对象
?
1
一般属性页对话框和向导对话框的创建和显示的不同包括,是否需要OnSetActive和OnWizardFinish等重载函数,是否需要调用属性表类的SetWizardMode函数设置为向导对话框模式。
?
1
  

消息对话框

CWnd::MessageBox()函数

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
CWnd::MessageBox()的函数原型如下:
 
       int MessageBox(
           LPCTSTR lpszText,
           LPCTSTR lpszCaption = NULL,
           UINT nType = MB_OK
       );
 
       参数说明:
 
       lpszText:需要显示的消息字符串。
 
       lpszCaption:消息对话框的标题字符串。默认值为NULL。取值为NULL时使用默认标题。
 
       nType:消息对话框的风格和属性。默认为MB_OK风格,即只有“确定”按钮。
 
       nType的取值可以是下面两个表中任取一个值,也可以是各取一个值的任意组合。即可以指定一个对话框类型,也可以指定一个对话框图标,还可以两者都设定。
?
1
2
3
4
5
6
7
nType 取值    参数说明
MB_ABORTRETRY   有“终止”、“重试”和“忽略”按钮
MB_OK   有“确定”按钮
MB_OKCANCEL 有“确定”和“取消”按钮
MB_RETRYCANCEL  有“重试”和“取消”按钮
MB_YESNO    有“是”和“否”按钮
MB_YESNOCANCEL  有“是”、“否”和“取消”按钮

nType 取值                                   显示图标

MB_ICONEXCLAMTION
MB_ICONWARNING                   VS2010/MFC编程入门之十六(对话框:消息对话框)

 

MB_ICONASTERISK
MB_ICONINFORMATION           VS2010/MFC编程入门之十六(对话框:消息对话框)

 

MB_ICONQUESTION                     VS2010/MFC编程入门之十六(对话框:消息对话框)

 

MB_ICONHAND
MB_ICONSTOP
MB_ICONERROR                            VS2010/MFC编程入门之十六(对话框:消息对话框)

 

       如果想要设置nType的值为类型和图标的组合,可以像这样取值:MB_OKCANCEL | MB_ICONQUESTION。按位取或就可以了。

?
1
  

全局AfxMessageBox()函数

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
AfxMessageBox()的函数原型为:
 
     int AfxMessageBox(
         LPCTSTR lpszText,
         UINT nType = MB_OK,
         UINT nIDHelp = 0
     );
 
     参数说明:
 
     lpszText:同CWnd::MessageBox()函数
 
     nType:CWnd::MessageBox()函数
 
     nIDHelp:此消息的帮助的上下文ID。默认值为0,取0时表示要使用应用程序的默认帮助上下文。

CWnd::MessageBox()和AfxMessageBox()的返回值

我们在调用了上面两个函数后,都可以弹出模态消息对话框。消息对话框关闭后,我们也都可以得到它们的返回值。两者的返回值就是用户在消息对话框上单击的按钮的ID,可以是以下值:

      IDABORT:单击“终止”按钮。
      IDCANCEL:单击“取消”按钮。
      IDIGNORE:单击“忽略”按钮。
      IDNO:单击“否”按钮。
      IDOK:单击“确定”按钮。
      IDRETRY:单击“重试”按钮。
      IDYES:单击“是”按钮。

 

文件对话框CFileDialog

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
  MFC使用文件对话框类CFileDialog封装了对文件对话框的操作。CFileDialog类的构造函数原型如下:
 
explicit CFileDialog(
   BOOL bOpenFileDialog,
   LPCTSTR lpszDefExt = NULL,
   LPCTSTR lpszFileName = NULL,
   DWORD dwFlags = OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT,
   LPCTSTR lpszFilter = NULL,
   CWnd* pParentWnd = NULL,
   DWORD dwSize = 0,
   BOOL bVistaStyle = TRUE
);
 
       参数说明:
 
       bOpenFileDialog:指定要创建的文件对话框的类型。设为TRUE将创建打开文件对话框,否则将创建保存文件对话框。
 
       lpszDefExt:默认的文件扩展名。如果用户在文件名编辑框中没有输入扩展名,则由lpszDefExt指定的扩展名将被自动添加到文件名后。默认为NULL。
 
       lpszFileName:文件名编辑框中显示的初始文件名。如果为NULL,则不显示初始文件名。
 
       dwFlags:文件对话框的属性,可以是一个值也可以是多个值的组合。关于属性值的定义,可以在MSDN中查找结构体OPENFILENAME,元素Flags的说明中包含了所有属性值。默认为OFN_HIDEREADONLY和OFN_OVERWRITEPROMPT的组合,OFN_HIDEREADONLY表示隐藏文件对话框上的“Read Only”复选框,OFN_OVERWRITEPROMPT表示在保存文件对话框中如果你选择的文件存在了,就弹出一个消息对话框,要求确定是否要覆盖此文件。
 
       lpszFilter:文件过滤器,它是由若干字符串对组成的一个字符串序列。如果指定了文件过滤器,则文件对话框中只有符合过滤条件的文件显示在文件列表中待选择。给大家看看VS2010 MSDN中给出的一个例子:
 
       static TCHAR BASED_CODE szFilter[] = _T("Chart Files (*.xlc)|*.xlc|Worksheet Files (*.xls)|*.xls|Data Files (*.xlc;*.xls)|*.xlc; *.xls|All Files (*.*)|*.*||");
 
       这样设置过滤器以后,文件对话框的扩展名组合框中将有四个选项:Chart Files (*.xlc)、Worksheet Files (*.xls)、Data Files(*.xlc;*.xls)和All Files (*.*),大家可以看到每种文件的扩展名规定都是一个字符串对,例如Chart Files的过滤字符串是Chart Files(*.xlc)和*.xlc成对出现的。
 
       pParentWnd:文件对话框的父窗口的指针。
 
       dwSize:OPENFILENAME结构体的大小。不同的操作系统对应不同的dwSize值。MFC通过此参数决定文件对话框的适当类型(例如,创建Windows 2000文件对话框还是XP文件对话框)。默认为0,表示MFC将根据程序运行的操作系统版本来决定使用哪种文件对话框。
 
       bVistaStyle:指定文件对话框的风格,设为TRUE则使用Vista风格的文件对话框,否则使用旧版本的文件对话框。此参数仅在Windows Vista中编译时适用。
 
       文件对话框也是模态对话框,所以在打开时也需要调用CFileDialog类的DoModal()成员函数。在打开文件对话框中点了“打开”或者在保存文件对话框中点了“保存”以后,我们可以使用CFileDialog类的成员函数GetPathName()获取选择的文件路径。
 
       下面列出几个CFileDialog类的成员函数,我们可以使用它们获得文件对话框中的各种选择。
 
GetFileExt():获得选定文件的后缀名。
GetFileName():获得选定文件的名称,包括后缀名。
GetFileTitle():获得选定文件的标题,即不包括后缀名。
GetFolderPath():获得选定文件的目录。
GetNextPathName():获得下一个选定的文件的路径全名。
GetPathName():获得选定文件的路径全名。
GetReadOnlyPref():获得是否“以只读方式打开”。
GetStartPosition():获得文件名列表中的第一个元素的位置。
?
1
  

字体对话框CFontDialog

字体对话框也是一种模态对话框。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
CFontDialog类常用构造函数原型如下:
 
CFontDialog(
   LPLOGFONT lplfInitial = NULL,
   DWORD dwFlags = CF_EFFECTS | CF_SCREENFONTS,
   CDC* pdcPrinter = NULL,
   CWnd* pParentWnd = NULL
);
 
       参数说明:
 
       lplfInitial:指向LOGFONT结构体数据的指针,可以通过它设置字体的一些特征。
 
       dwFlags:指定选择字体的一个或多个属性,详情可在MSDN中查阅。
 
       pdcPrinter:指向一个打印设备上下文的指针。
 
       pParentWnd:指向字体对话框父窗口的指针。
 
       上面的构造函数中第一个参数为LOGFONT指针,LOGFONT结构体中包含了字体的大部分特征,包括字体高度、宽度、方向、名称等等。下面是此结构体的定义:
 
typedef struct tagLOGFONT {
    LONG lfHeight;
    LONG lfWidth;
    LONG lfEscapement;
    LONG lfOrientation;
    LONG lfWeight;
    BYTE lfItalic;
    BYTE lfUnderline;
    BYTE lfStrikeOut;
    BYTE lfCharSet;
    BYTE lfOutPrecision;
    BYTE lfClipPrecision;
    BYTE lfQuality;
    BYTE lfPitchAndFamily;
    TCHAR lfFaceName[LF_FACESIZE];
} LOGFONT;

获取字体对话框中所选字体

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
我们在字体对话框中选择了字体后,如何获取选定的字体呢?我们可以通过CFontDialog类的成员变量m_cf间接获得选定字体的CFont对象。m_cf是CHOOSEFONT类型的变量,CHOOSEFONT结构体定义如下:
 
typedef struct {
    DWORD lStructSize;
    HWND hwndOwner;
    HDC hDC;
    LPLOGFONT lpLogFont;
    INT iPointSize;
    DWORD Flags;
    COLORREF rgbColors;
    LPARAM lCustData;
    LPCFHOOKPROC lpfnHook;
    LPCTSTR lpTemplateName;
    HINSTANCE hInstance;
    LPTSTR lpszStyle;
    WORD nFontType;
    INT nSizeMin;
    INT nSizeMax;
} CHOOSEFONT, *LPCHOOSEFONT;
 
       CHOOSEFON结构体中有个成员lpLogFont,它是指向LOGFONT结构体变量的指针,就像上面所说,LOGFONT中包含了字体特征,例如,我们可以通过LOGFONT的lfFaceName得知字体名。
 
       我们最终要获得的是所选择字体的CFont对象,有了字体的LOGFONT怎样获得对应的CFont对象呢?使用CFont类的成员函数CreateFontIndirect可以达到此目的。函数原型如下:
 
       BOOL CreateFontIndirect(const LOGFONT* lpLogFont );
 
       参数是LOGFONT指针类型,我们可以传入CFontDialog类成员变量m_cf的lpLogFont成员,就可以得到所选字体的CFont对象了。

 

颜色对话框CColorDialog

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
CColorDialog类的构造函数
 
CColorDialog(
   COLORREF clrInit = 0,
   DWORD dwFlags = 0,
   CWnd* pParentWnd = NULL
);
 
       参数说明:
 
       clrInit:默认选择颜色的颜色值,类型为COLORREF,实际上就是unsigned long类型。如果没有设置它的值,则默认为RGB(0,0,0),即黑色。
 
       注:RGB(r,g,b)是宏,可以计算颜色值。括号中的三个值分别为红、绿、蓝分量的值。
 
       dwFlags:自定义颜色对话框功能和外观的属性值。详情可在MSDN中查阅。
 
       pParentWnd:颜色对话框的父窗口的指针。

获取颜色对话框中所选颜色值

?
1
2
3
4
5
6
7
8
9
10
11
我们使用颜色对话框的最终目的还是要获得在颜色对话框中选择的颜色值。为此CColorDialog类的成员函数GetColor()能够很好的实现我们的要求。GetColor()函数的原型为:
 
      COLORREF GetColor( ) const;
 
      它返回所选颜色的COLORREF值。
 
      如果我们想获得R、G、B各分量的值呢?可以根据GetColor得到的COLORREF颜色值,通过使用GetRValue、GetGValue和GetBValue三个宏获得。GetRValue的语法形式为:
 
      BYTE GetRValue(DWORD rgb);
 
      参数rgb就是COLORREF颜色值,返回值即是R分量值。其他两个宏的形式与之类似。例如,GetColor()函数返回的COLORREF为10000,则R分量值就是GetRValue(10000)。