按键盘上方向键 ← 或 → 可快速上下翻页,按键盘上的 Enter 键可回到本书目录页,按键盘上方向键 ↑ 可回到本页顶部!
————未阅读完?加入书签已便下次继续阅读!
首先你必须决定,在哪里拦截【Edit/Clear All 】才好?本章前面对于消息映射
与命令绕行的深度讨论这会儿派上了用场。【Edit/Clear All 】这个命令的目的
是要清除文件,文件的根本是在资料的「体」,而不在资料的「面」,所以把
文件的命令处理例程放在Document 类别中比放在View 类别来得高明。命令讯
息会不会流经Document 类别?经过前数节的深度之旅,你应该自有定论了。
所以, 让我们在CScribbleDoc 的WizardBar 选择【Object IDs 】为
ID_EDIT_CLEAR_ALL ,并选择【Messages 】为MAND 。
猜猜看,如果你在【Object IDs 】中选择CScribbleDoc,右侧的【Messages 】清
单会出现什么? 什么都没有! 因为Document 类别只可能接受
WM_MAND,这一点你应该已经从前面所说的消息递送过程中知道了。如
果你在CScribbleApp 的WizardBar 上选择【Object IDs 】为CScribbleApp,
右侧的【Messages 】清单中也是什么都没有,道理相同。
你会获得一个对话框,询问你是否接受一个新的处理例程。选择Yes ,于是文
字编辑器中出现该函数之骨干,等待你的幸临。。。。
这样就完成了命令消息与其处理函数的连接工作。这个工作称为〃mand binding〃 。我
们的源代码获得以下修改:
Document 类别之中多了一个函数声明:
class CScribbleDoc : public CDocument
{
protected:
afx_msg void OnEditClearAll();
。。。
}
591
…………………………………………………………Page 654……………………………………………………………
第篇 深入 MFC 程式設計
Document 类别的Message Map 中多了一笔记录:
BEGIN_MESSAGE_MAP(CScribbleDoc; CDocument)
ON_MAND(ID_EDIT_CLEAR_ALL; OnEditClearAll)
。。。
END_MESSAGE_MAP()
Document 类别中多了一个函数空壳:
void CScribbleDoc::OnEditClearAll()
{
}
现在请写下OnEditClearAll 函数码:
依此要领,我们再设计OnPenThickOrThin 函数。此一函数用来更改现行的笔宽,与
Document 有密切关系,所以在Document 类别中放置其消息处理例程是适当的:
void CScribbleDoc::OnPenThickOrThin()
{
// Toggle the state of the pen between thin or thick。
m_bThickPen = !m_bThickPen;
// Change the current pen to reflect the new user…specified width。
ReplacePen();
}
592
…………………………………………………………Page 655……………………………………………………………
第9章 訊息映射與命令繞行
void CScribbleDoc::ReplacePen()
{
m_nPenWidth = m_bThickPen? m_nThickWidth : m_nThinWidth;
// Change the current pen to reflect the new user…specified width。
m_penCur。DeleteObject();
m_penCur。CreatePen(PS_SOLID; m_nPenWidth; RGB(0;0;0)); // solid black
}
注意,ReplacePen 并非由WizardBar (或ClassWizard )加上去,所以我们必须自行在
CScribbleDoc 类别中加上这个函数的声明:
class CScribbleDoc : public CDocument
{
protected:
void ReplacePen();
。。。
}
OnPenThickOrThin 函数用来更换笔的宽度,所以CScribbleDoc 势必需要加些新的成
员变量。变量m_bThickPen 用来记录目前笔的状态(粗笔或细笔),变量m_nThinWidth
和m_nThickWidth 分别记录粗笔和细笔的笔宽…在Step2 中此二者固定为2 和5,
原本并不需要变量的设置,但下一章的Step3 中粗笔和细笔的笔宽可以更改,所以这里
未雨绸缪:
class CScribbleDoc : public CDocument
{
// Attributes
protected:
UINT m_nPenWidth; // current user…selected pen width
BOOL m_bThickPen; // TRUE if current pen is thick
UINT m_nThinWidth;
UINT m_nThickWidth;
CPen m_penCur; // pen created according to
。。。
}
593
…………………………………………………………Page 656……………………………………………………………
第篇 深入 MFC 程式設計
现在重新考虑文件初始化的动作,将Step1 的:
void CScribbleDoc::InitDocument()
{
m_nPenWidth = 2; // default 2 pixel pen width
// solid; black pen
m_penCur。CreatePen(PS_SOLID; m_nPenWidth; RGB(0;0;0));
}
改变为Step2 的:
void CScribbleDoc::InitDocument()
{
m_bThickPen = FALSE;
m_nThinWidth = 2; // default thin pen is 2 pixels wide
m_nThickWidth = 5; // default thick pen is 5 pixels wide
ReplacePen(); // initialize pen according to current width
}
维护UI 对象状态(UPDATE_MAND_UI)
上一节我曾提过WizardBar 右侧的【Messages 】清单中,针对各个命令项,会出现
MAND 和UPDATE_MAND_UI 两种选择。后者做什么用?
一个菜单拉下来,使用者可以从命令项的状态(打勾或没打勾、灰色或正常)得到一些
状态提示。如果Document 中没有任何资料的话,【Edit/Clear All 】照道理就不应该起作
用,因为根本没资料又如何〃Clear All〃 呢?! 这时候我们应该把这个命令项除能
(disable )。又例如在粗笔状态下,程序的【Pen/Thick Line 】命令项应该打一个勾(所
谓的check mark ),在细笔状态下不应该打勾。此外,菜单命令项的状态应该同步影响
到对应之工具栏按钮状态。
所有UI 对象状态的维护可以依赖所谓的UPDATE_MAND_UI 消息。
传统SDK 程序中要改变菜单命令项状态, 可以调用EnableMenuItem 或是
C