按键盘上方向键 ← 或 → 可快速上下翻页,按键盘上的 Enter 键可回到本书目录页,按键盘上方向键 ↑ 可回到本页顶部!
————未阅读完?加入书签已便下次继续阅读!
// CAboutDlg 用于 App About 的对话框
class CAboutDlg : public CDialog
{
public:
CAboutDlg();
// Dialog Data
//{{AFX_DATA(CAboutDlg)
enum { IDD = IDD_ABOUTBOX };
//}}AFX_DATA
// 由 ClassWizard 生成的虚函数重载
//{{AFX_VIRTUAL(CAboutDlg)
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV 支持
//}}AFX_VIRTUAL
// 实现
protected:
//{{AFX_MSG(CAboutDlg)
//}}AFX_MSG
…………………………………………………………Page 191……………………………………………………………
DECLARE_MESSAGE_MAP()
};
CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD)
{
//{{AFX_DATA_INIT(CAboutDlg)
//}}AFX_DATA_INIT
}
void CAboutDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CAboutDlg)
//}}AFX_DATA_MAP
}
BEGIN_MESSAGE_MAP(CAboutDlg; CDialog)
//{{AFX_MSG_MAP(CAboutDlg)
// 没有消息处理函数
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CDialogDemoDlg 对话框
CDialogDemoDlg::CDialogDemoDlg(CWnd* pParent /*=NULL*/)
: CDialog(CDialogDemoDlg::IDD; pParent)
{
//{{AFX_DATA_INIT(CDialogDemoDlg)
// 注意:ClassWizard 将在此添加成员初始化
//}}AFX_DATA_INIT
…………………………………………………………Page 192……………………………………………………………
// 注意在 Win32 中 LoadIcon 不需要一个相应的 DestroyIcon
m_hIcon = AfxGetApp()…》LoadIcon(IDR_MAINFRAME);
}
void CDialogDemoDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CDialogDemoDlg)
// 注意:ClassWizard 将在此添加 DDX 和 DDV 调用
//}}AFX_DATA_MAP
}
BEGIN_MESSAGE_MAP(CDialogDemoDlg; CDialog)
//{{AFX_MSG_MAP(CDialogDemoDlg)
ON_WM_SYSMAND()
ON_WM_PAINT()
ON_WM_QUERYDRAGICON()
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CDialogDemoDlg 消息处理函数
BOOL CDialogDemoDlg::OnInitDialog()
{
CDialog::OnInitDialog();
// 添加 〃About。。。〃 菜单项到系统菜单
// IDM_ABOUTBOX 必须在系统命令范围之内
ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
ASSERT(IDM_ABOUTBOX 《 0xF000);
…………………………………………………………Page 193……………………………………………………………
CMenu* pSysMenu = GetSystemMenu(FALSE);
if (pSysMenu != NULL)
{
CString strAboutMenu;
strAboutMenu。LoadString(IDS_ABOUTBOX);
if (!strAboutMenu。IsEmpty())
{
pSysMenu…》AppendMenu(MF_SEPARATOR);
pSysMenu…》AppendMenu(MF_STRING; IDM_ABOUTBOX; strAboutMenu);
}
}
// 该当前对话框设置图标。当应用程序主窗口不为对话框时由框架自动完成该任务
SetIcon(m_hIcon; TRUE); // 设置大图标
SetIcon(m_hIcon; FALSE); // 设置小图标
// TODO: 在此添加额外初始化
return TRUE; // 除非将焦点设置为某一控件,否则返回 TRUE
}
void CDialogDemoDlg::OnSysmand(UINT nID; LPARAM lParam)
{
if ((nID & 0xFFF0) == IDM_ABOUTBOX)
{
CAboutDlg dlgAbout;
dlgAbout。DoModal();
}
else
{
…………………………………………………………Page 194……………………………………………………………
CDialog::OnSysmand(nID; lParam);
}
}
// 如果你向对话框添加了一个最小化按钮,你将需要下面的代码来绘制图标。
// 对于使用文件/视模型的 MFC 应用程序,这一步由框架自动完成。
void CDialogDemoDlg::OnPaint()
{
if (IsIconic())
{
CPaintDC dc(this); // 重绘设备上下文
SendMessage(WM_ICONERASEBKGND; (WPARAM) dc。GetSafeHdc(); 0);
// 在窗户区矩形中居中图标
int cxIcon = GetSystemMetrics(SM_CXICON);
int cyIcon = GetSystemMetrics(SM_CYICON);
CRect rect;
GetClientRect(&rect);
int x = (rect。Width() cxIcon + 1) / 2;
int y = (rect。Height() cyIcon + 1) / 2;
// 绘制图标
dc。DrawIcon(x; y; m_hIcon);
}
else
{
CDialog::OnPaint();
}
}
…………………………………………………………Page 195……………………………………………………………
// 在用户拖动被最小化的窗口时系统调用该函数来获得用于显示的光标。
HCURSOR CDialogDemoDlg::OnQueryDragIcon()
{
return (HCURSOR) m_hIcon;
}
在实现文件DialogDemoDlg。cpp 中包括了类CAboutDlg的定义,该类封
装了应用程序的 “关于”对话框。由于类CAboutDlg与类
CDialogDemoDlg相比要简单得多,所以我们在此不再讲述。下面我们
主要分几个部分来讲述类CDialogDemoDlg 。
(1) 构造函数
在类CDialogDemoDlg的构造函数中,注释分隔符AFX_DATA_INIT用于
在对话框类的构造函数中标记对话框数据交换 (DDX)成员变量初始化
的开始和结束。接着使用MFC全局函数AfxGetApp获得指向应用程序对
象的指针,再通过该指针调用成员函数LoadIcon加载图标,并将其句
柄放入成员变量m_hIcon。
类CDialogDemoDlg的成员函数DoDataExchange只是简单的调用基类的
对应成员函数。在成员函数DoDataExchange 内,注释分隔符
AFX_DATA_MAP用于标记对话框数据交换函数调用的开始和结束。
l 注意:
l 尽管在接下来的一章中,我们将要再次对菜单的应用作系统的介
绍,但考虑到程序说明的完整性,在这里,我们仍然先对其作简
明的介绍。
(2) 消息处理成员函数OnInitDialog
消息处理函数OnInitDialog首先调用基类的对应成员函数。接着的两
个ASSERT宏断言IDM_ABOUTBOX处于系统命令范围内。ASSERT宏以一个
布尔表达式为参数,然后对该表达式求值,如果结果为0 (假),
ASSERT输出一个诊断信息,然后中断程序,如果结果为非0,宏
ASSERT什么也不做。
由宏ASSERT输入的诊断信息具下面的格式:
…………………………………………………………Page 196……………………………………………………………
assertion failed in file in line
在这里文件名代表了出现ASSERT错的源代码文件,行号指出了源代码
文件中出错的行。
在MFC的发行版本 (Release version)中,宏ASSERT并不对表达式进行
求值,从而也不会中断程序的执行。与宏ASSERT不同,宏VERIFY在
MFC中调试版本和发行版本中都将对表达式进行求值。
接下来,由类CWnd的成员函数GetSystemMenu返回控制菜单的一个拷
贝。如果传递给该函数的参数为假,函数GetSystemMenu返回正在使
用的控制菜单的一个拷贝的句柄。该拷贝同控制菜单完全相同,但它
可以修改。如果传递的参数为真,函数GetSystemMenu重置控制菜单
为默认值,如果原有控制菜单经过修改,该改动将丢失。在这种情况
下,函数GetSystemMenu的返回值是未定义的。可以通过由成员函数
GetSystemMenu返回的指针使用CMenu::AppendMenu、
CMenu::InsertMenu或CMenu::ModifyMenu函数来改变控制菜单。
控制菜单最初包括由不同ID值,如SC_CLOSE、SC_MOVE和SC_SIZE等标
识的项。这些控制菜单中的项产生WM_SYSMAND消息。所有预定义
的控制菜单具有大于0xF000的ID值,因此,如果应用程序向控制菜单
中添加了新的项,这些项所使用的ID值应该小于0xF000。
Windows可以自动的决定是否使标准控制菜单中的项变灰。类CWnd可
以通过响应WM_INITMENU来执行检查或变灰,该消息在所有菜单显示
之前发送。
表4。 4 成员函数AppendMenu 的nFlags参数
值 含义
MF_CHECKED 在菜单项前面放置一个默认的选中
标记。当应用程序提供了选中标记
位图时,则使用表示选中状态的位
图。
MF_UNCHECKED 清除菜单项前面的选中标记。如果
应用程序提供了选中标记位图,则
使用表示不选中状态的位图。
MF_DISABLED 禁止某项被选择,但不使其变灰。
MF_ENABLED 允许某项被选择。
MF_GRAYED 禁止某项被选择,并使其变灰。
…………………………………………………………Page 197……………………………………………………………
MF_MENUBARBREAK 对于静态菜单,将项放到新的一
行,对于弹出菜单,将项放到新的
一列。新的弹出菜单列和旧的列使
用垂直分隔线隔开。
MF_MENUBREAK 将项放到新的一行,或弹出菜单的
新的一列。列之�