正在加载
请稍等

菜单

红楼飞雪 梦

15526773247

文章

Home windows程序设计 windows程序设计入门篇(七) CCmdTarget类
Home windows程序设计 windows程序设计入门篇(七) CCmdTarget类

windows程序设计入门篇(七) CCmdTarget类

windows程序设计 by

       CCmdTarget继承来的按键框架类包括:CView、CWinApp、CDocument、CWnd和CFrameWnd。如果想生成一个处理按键消息的类,可以选择其中的一个派生一个子类。很少需要直接从CCmdTarget派生类。
       MFC为该类设计了许多成员函数和一些成员数据,基本上是为了解决消息映射问题的,而且,很大一部分是针对OLE设计的。在OLE应用中,CCmdTarget是MFC处理模块状态的重要环节,它起到了传递模块状态的作用:其构造函数获取当前模块状态,并保存在成员变量m_pModuleState里头。
CCmdTarget有两个与消息映射有密切关系的成员函数:DispatchCmdMsg和OnCmdMsg。
类CmdTarget包括了处理沙漏形光标显示的成员函数。当某个命令的执行时间比较长时,可以显示沙漏标提示用户命令正在执行。
和消息映射类似,分派映射用于列出OLE自动的IDispatch功能。列出这个接口后,其它的应用(如VB)就能调用这个应用了。有关IDispatch接口的更详细的信息,请参阅“Win32 SDK OLE程序员参考”中的“创建IDPatch接口”和“分派接口与API函数”。
所需头文件:#include <afxwin.h>

静态成员函数DispatchCmdMsg

static BOOL DispatchCmdMsg(
CCmdTarget* pTarget,
UINT nID,
int nCode,
AFX_PMSG pfn,
void* pExtra,
UINT nSig,
AFX_CMDHANDLERINFO* pHandlerInfo)

虚拟函数OnCmdMsg

CCmdTarget的虚拟函数OnCmdMsg,用来传递和发送消息、更新用户界面对象的状态,其原型如下:
OnCmdMsg(
UINT nID,
int nCode,
void* pExtra,
AFX_CMDHANDLERINFO* pHandlerInfo)
框架的命令消息传递机制主要是通过该函数来实现的。
命令目标指希望或者可能处理消息的对象;命令目标类指命令目标的类。
CCmdTarget对OnCmdMsg的默认实现:在当前命令目标(this所指)的类和基类的消息映射数组里搜索指定命令消息的消息处理函数(标准Windows消息不会送到这里处理)。
这里使用虚拟函数GetMessageMap得到命令目标类的消息映射入口数组_messageEntries,然后在数组里匹配指定的消息映射条目。匹配标准:命令消息ID相同,控制通知代码相同。因为GetMessageMap是虚拟函数,所以可以确认当前命令目标的确切类。
如果找到了一个匹配的消息映射条目,则使用DispachCmdMsg调用这个处理函数;
如果没有找到,则使用_GetBaseMessageMap得到基类的消息映射数组,查找,直到找到或搜寻了所有的基类(到CCmdTarget)为止;
如果最后没有找到,则返回FASLE。
每个从CCmdTarget派生的命令目标类都可以覆盖OnCmdMsg,利用它来确定是否可以处理某条命令,如果不能,就通过调用下一命令目标的OnCmdMsg,把该命令送给下一个命令目标处理。通常,派生类覆盖OnCmdMsg时,要调用基类的被覆盖的OnCmdMsg。
在MFC框架中,一些MFC命令目标类覆盖了OnCmdMsg,如框架窗口类覆盖了该函数,实现了MFC的标准命令消息发送路径。
必要的话,应用程序也可以覆盖OnCmdMsg,改变一个或多个类中的发送规定,实现与标准框架发送规定不同的发送路径。例如,在以下情况可以作这样的处理:在要打断发送顺序的类中把命令传给一个非MFC默认对象;在新的非默认对象中或在可能要传出命令的命令目标中。
该类派生于CObject,经封装了MFC的消息映射机制, 希望接收系统事件和窗口消息的类都从它派生,如CDocument和CWnd分支。此外,在系统繁忙,无法响应窗口消息时,鼠标光标应该显示为沙漏等待状 态,CCmdTarget类封装了3个成员函数完成该功能。封装COM的IDispatch接口是它的另一项主要功能。IDispatch是COM的标准 接口,不含指针操作的语言(如VB)以及描述性语言(如Web脚本语言和VBA)都通过该接口操作COM组件。CCmdTarget类以一种类似消息映射的机制提供IDispatch接口,所以使用MFC可以轻松地编写AUTOMATION客户程序和组件。
CCmdTarget类定义BeginWaitCursor()、EndWaitCursor()和 RestoreWaitCursor()3个成员函数处理等待光标。BeginWaitCursor()将光标设置为沙漏形状,该函数有可能被程序框架调 用,通知用户状态忙,例如当加载和存储文档时。EndWaitCursor()将光标恢复为沙漏之前的形状,一般与BeginWaitCursor()配 合使用。
在实际编程中,在一个比较耗费机时的处理前应该主动调用BeginWaitCursor()设置光标,在处理结束时要调用EndWaitCursor()恢复光标。
例如:
void CWaitCursorDoc::LoadFile(char * Filepath)
{
//显示沙漏光标
BeginWaitCursor();
//耗费机时的处理过程
TRACE(“正在装入文件,请等待…\n”);
……
//恢复为沙漏前的光标形状
EndWaitCursor();
}
如果在BeginWaitCursor()和EndWaitCursor()之间的处理中,弹出了模式对话框,光标会由沙漏变为标准形状(通常是标准箭头)。为处理这种情形,可以在对话框关闭后,调用成员RestoreWaitCursor()重新将光标设置回沙漏形状,直到处理结束后调用EndWait Cursor()。例如:
void CWaitCursorDoc::LoadFile(char * Filepath)
{
WIN32_FIND_DATA FindData;
//显示沙漏光标
BeginWaitCursor();
//耗费机时的处理过程
if(::FindFirstFile(Filepath,&FindData)==INVALID_HANDLE_VALUE)
{
TRACE(“打开文件出错,请重新指定文件\n”);
CFileDlg dlg;
dlg.DoModal();
//恢复光标的沙漏形状
RestoreWaitCursor();
}
TRACE(“正在装入文件,请等待…\n”);
……
//恢复沙漏前的光标形状
EndWaitCursor();
}
但如果弹出的是MessageBox()消息框,就不必调用RestoreWaitCursor(),光标会自动恢复为沙漏。
在非CCmdTarget派生类中,可以使用CWaitCursor类设置等待光标。该类的构造函数析构函数相当于CCmdTarget::BeginWaitCursor()和CCmdTarget::EndWaitCursor(),成员函数Restore()相当于CCmdTarget:: RestoreWaitCursor()。

原文出处:http://baike.baidu.com/link?url=Ob4QtlSzx46gkNTrsHlecNQxNcWD-59Cn29Ll1rwDX0-hBo4PZG9nyoxcg4R4xwkhplmb9xW8A844tiMxLY2hq

 

22 2015-03

 

我要 分享

 

 

本文 作者

 

相关 文章