友情提示:如果本网页打开太慢或显示不完整,请尝试鼠标右键“刷新”本网页!
C语言实例教程(PDF格式)-第23部分
快捷操作: 按键盘上方向键 ← 或 → 可快速上下翻页 按键盘上的 Enter 键可回到本书目录页 按键盘上方向键 ↑ 可回到本页顶部! 如果本书没有阅读完,想下次继续接着阅读,可使用上方 "收藏到我的浏览器" 功能 和 "加入书签" 功能!
afx_msg void OnPaint();
afx_msg HCURSOR OnQueryDragIcon();
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};
//{{AFX_INSERT_LOCATION}}
// Microsoft Developer Studio 将在紧贴前一行前面添加附加的声明
#endif
// !defined(AFX_DIALOGDEMODLG_H__7ABABF8A_0C8C_11D2_BC21_0000B4810A31__INCLUDED_)
ClassWizard和AppWizard在生成代码时向源代码文件中插入了一些特
定的格式化注释分隔符,以标明那些ClassWizard可以写入的地方。
在前几节的内容中我们已经看到了一些这样的注释分隔符,如
AFX_MSG和AFX_MSG_MAP等。在头文件DialogDemoDlg中出现了一些新
的分隔符,如AFX_DATA用来标记在头文件中为对话框数据交换
(dialog data exchange,DDX)所声明的成员变量的开始和结束。
AFX_VIRTUAL用来标记在头文件中由ClassWizard生成和管理的虚函数
的开始和结果。在。CPP文件中没有对应的块。
下一个看到的函数是DoDataExchange。框架调用该函数来交换和验证
…………………………………………………………Page 187……………………………………………………………
对话框数据。该函数从来不直接调用,而总是在成员函数UpdateData
中调用。成员函数UpdateData用户初始化对话框控件或从对话框中获
取数据。
如果需要利用框架的自动数据交换和验证,则需要在从类CDialog派
生应用程序特定的对话框时得载该成员函数。ClassWizard会为你创
建一个该成员函数的重载版本,在该重载版本的DoDataExchange函数
中包括了所期望的对话框数据交换 (DDX)和有效性验证 (DDV)的全局函
数的 “数据映射”。
DoDataExchange函数的重载版本将在后面的内容中给出和进行更为详
细的分析。
成员变量m_hIcon包括了应用程序主对话框的图标句柄。
下面介绍重载的几个消息映射函数。
第一个介绍的是OnInitDialog成员函数。该成员函数为消息
WM_INITDIALOG的处理函数。当成员函数Create、CreateIndirect或
DoModal被调用时该消息被发送至对话框,但此时对话框尚未显示于
屏幕上。
一般情况下我们重载该成员函数以进行一些对话框的初始化。在
OnInitDialog成员函数的重载版本中,我们应该先调用基类的
OnInitDialog成员函数,但无需理会其返回值。在正常情况下,
OnInitDialog成员函数的重载版本返回TRUE。
不需要为该成员函数添加一个消息映射入口。这是因为Windows通过
一个标准全局对话框函数来调用OnInitDialog函数,该对话框函数对
所有的MFC对话框都是一样的,这种调用并不通过消息映射来完成。
表4。3 OnSysmand成员函数的nID参数
参数nID的值 含义
SC_CLOSE 关闭CWnd对象
SC_HOTKEY 激活与应用程序指定的热键相关联的CWnd
对象。lParam参数的低位字节标识了待激
活窗口的HWND。
SC_HSCROLL 垂直滚动
SC_KEYMENU 通过按键检索菜单
…………………………………………………………Page 188……………………………………………………………
SC_MAXIMIZA 最大化CWnd对象
(或SC_ZOOM)
SC_MINIMIZE 最小化CWnd对象
(或SC_ICON)
SC_MOUSEMENU 通过鼠标单击检索菜单
SC_MOVE 移动CWnd对象
SC_NEXTWINDOW 移到下一窗口
SC_PREVWINDOW 移到上一窗口
SC_RESTORE 恢复窗口到通常位置和大小
SC_SCREENSAVE 执行由SYSTEM。INI文件的'boot'段指定的
屏幕保护程序
SC_SIZE 改变窗口的大小
SC_TASKLIST 运行或激活Windows任务管理程序
(Windows Task Manager)
l 注意:
l OnInitDialog成员函数的返回值将影响应用程序设置对话框中控
件的输入焦点的方式。如果OnInitDialog返回非零值,窗口设置
输入焦点为对话框中的第一个控件。如果已显式的将输入焦点设
置为对话框中的某个控件,那么应该返回0。
接下来声明的是成员函数OnSysmand,它是WM_SYSMAND消息的
处理函数。当用户从控制菜单选择了某一个命令或单击了最大化或最
小化按钮。
该函数的原型如下:
afx_msg void OnSysmand( UINT nID; LPARAM lParam );
第一个参数nID指定了系统命令要求的类型,它可以为表4。3所示值之
一。如果通过鼠标选择控制菜单命令,则参数lParam包含了鼠标的当
前坐标。低位字代表x坐标,而高位字代表y坐标。
在默认情况下,OnSysmand执行表4。3所示的预定义行为。
…………………………………………………………Page 189……………………………………………………………
在WM_SYSMAND消息中,参数nID的低4位由Windows内部使用,当应
用程序测试nID的值时,必须使用按位与(bitwise…AND)操作符组合值
0xFFF0和nID来得到正确的结果。
应用程序可以在任何时候通过传递一个WM_SYSMAND消息给成员函
数OnSysmand来执行任何系统命令。
已被定义为用来选择控制菜单项的加速键 (快捷键)消息将解释为
OnSysmand的调用,其它快捷键将翻译为WM_MAND消息。
l 注意:
l 控制菜单项可以通过成员函数GetSystemMenu、AppendMenu、
InsertMenu以及ModifyMenu来进行修改。修改了控制菜单的应用
程序必须处理WM_SYSMAND消息,所有未被应用程序处理的消息
必须传递给成员函数OnSysmand。由应用程序添加的命令值必
须由应用程序处理,而不能传递给函数OnSysmand。
l 该成员函数由框架所调用,以允许应用程序处理Windows消息。传
递给函数的消息代表了当获得消息时由框架获得的参数。如果你
调用了基类的实现,该实现将使用消息最初传递的参数,而不是
由函数提供的参数。
成员函数OnPaint是消息WM_PAINT的处理函数,它当窗口客户区需要
重绘时被调用。
成员函数OnQueryDragIcon对应于消息WM_QUERYDRAGICON,它也是由
框架在最小化窗口而没有为类定义一个图标时调用。系统通过对该函
数的调用来获得当用户拖动被最小化的窗口时用来显示的光标。
如果应用程序返回了一个图标名光标的句柄,系统将其转换了黑白
的。该句柄必须标识一个与显示驱动程序分辨率相兼容的单色光标或
图标。应用程序可以调用CWinApp::LoadCursor或CWinApp::LoadIcon
成员函数来从它的可执行文件中的资源内加载一个光标或图标并获得
其句柄。
下面给出类CDialogDemoDlg的实现文件DialogDemoDlg。cpp的清单:
// DialogDemoDlg。cpp : 实现文件
//
#include 〃stdafx。h〃
…………………………………………………………Page 190……………………………………………………………
#include 〃DialogDemo。h〃
#include 〃DialogDemoDlg。h〃
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE'' = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
// 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。
类CDialo
快捷操作: 按键盘上方向键 ← 或 → 可快速上下翻页 按键盘上的 Enter 键可回到本书目录页 按键盘上方向键 ↑ 可回到本页顶部!
温馨提示: 温看小说的同时发表评论,说出自己的看法和其它小伙伴们分享也不错哦!发表书评还可以获得积分和经验奖励,认真写原创书评 被采纳为精评可以获得大量金币、积分和经验奖励哦!