




已阅读5页,还剩13页未读, 继续免费阅读
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
软件英才网 软件行业驰名招聘网站消息映射机制SDK编程中,一般处理消息的方法就是使用switch/case判断消息的类型,然后进行响应。更模块化的方法是使用第一章介绍的消息映射表的方法,把消息和消息处理函数关联起来。应该为每个需要处理消息的类构建一个消息映射表,并将基类与派生类的消息映射表连接起来。当窗口函数比较消息时,就沿着这条继承路线传递下去。 为了实现这个目的我们仍然使用两个宏,完成这个功能复杂的构建。首先定义一个数据结构:/消息映射表元素类型。struct AFX_MSGMAP_ENTRYUINT nMessage;UINT nCode;UINT nID;UINT nLastID;UINT nSig;AFX_PMSG pfn;struct AFX_MSGMAPAFX_MSGMAP *pBaseMessageMap;/指向基类的本结构。AFX_MSGMAP_ENTRY*lpEntries;/本类的消息映射表。;在定义一个宏:define DECLARE_MESSAGE_MAPstatic AFX_MSGMAP_ENTRY _messageEntries;static AFX_MSGMAP messageMap;virtual AFX_MSGMAP*GetMessageMap()const;该宏相当于在类中声明两个static数据成员和一个虚成员函数。 它们的定义由以下三个宏实现:#define BEGIN_MESSAGE_MAP(class_name,base_class)AFX_MSGMAP*class_name:GetMessageMap()const return &class_name:message;AFX_MSGMAP messageMap= &base_class:messageMap,class_name:_messageEntriesAFX_MSGMAP_ENTRY _messageEntries= #define ON_COMMAND(id,memFunc) WM_COMMAND,0,id,id,AFx_sig_vv ,(AFX_PMSG)memFunc ,#define END_MESSAGE_MAP() 0,0,0,0,AfxSig_end,(AFX_PMSG)0以CView为例,下面的代码:class CWnd :public CWnd public: DECLARE_MESSAGE_MAP();BEGIN_MESSAGE_MAP(CView,CWnd)ON_COMMAND(CViewid,0)END_MESSAGE_MAP()展开后变为:class CView :public CWndpublic:static AFX_MESSAGE_ENTRY _messageEntries;static AFX_MSGMAP messageMap;virtual AFX_MSGMAP*GetMessageMap()const;AFX_MSGMAP*CView:GetMessageMap()const return &CView:messagemMap;AFX_MSGMAP CView:messageMap=&(CWnd:messageMap),(AFX_MSGMAP_ENTRY*)&(CView:_messageEntries);AFX_MSGMAP_ENTRY CView:_messageEntries=WM_COMMAND,0,122,122,1,(AFX_PMSG)0,0,0,0,0,0,(AFX_PMSG)0为了验证整个消息映射表,我们在每个类的消息映射表中添加了一个空的消息,这是为了做点标记,用于标示消息映射表的最后一个消息。MFC当然不是这样实现的。/* CCmdTarget是消息传递的终点,因此在实现时需要特殊处理,这一点容易出错,要特别注意。class CCmdTarget:public CObjectDECLARE_DYNCREATE(CCmdTarget)DECLARE_MESSAGE_MAP()public:CCmdTarget()/coutCCmdTarget constructor!endl;/CreateObject();CCmdTarget()/coutCCmdTarget destructor!endl;public:;IMPLEMENT_DYNCREATE(CCmdTarget,CObject) AFX_MSGMAP CCmdTarget:messageMap= NULL,CCmdTarget:_messageEntries;AFX_MSGMAP_ENTRY CCmdTarget:_messageEntries= 0,0,10,0,AfxSig_end,0, 0,0,0,0,AfxSig_end,0;AFX_MSGMAP*CCmdTarget:GetMessageMap()const return &CCmdTarget:messageMap; 以下为包含动态创建、类型识别、消息映射的完整代码:cpp view plaincopy1 #include 2 #include 3 #include 4 using namespace std; 5 class CCmdTarget; 6 typedef void (CCmdTarget:*AFX_PMSG)(void); 7 8 /消息映射表元素类型。 9 enum AfxSig 10 11 AfxSig_end=0, 12 AfxSig_vv, 13 ; 14 struct AFX_MSGMAP_ENTRY 15 16 UINT nMessage; 17 UINT nCode; 18 UINT nID; 19 UINT nLastID; 20 UINT nSig; 21 AFX_PMSG pfn; 22 ; 23 struct AFX_MSGMAP 24 25 AFX_MSGMAP *pBaseMessageMap;/指向基类的本结构。 26 AFX_MSGMAP_ENTRY*lpEntries;/本类的消息映射表。 27 ; 28 29 30 #define DECLARE_MESSAGE_MAP() 31 public: 32 static AFX_MSGMAP_ENTRY _messageEntries; 33 static AFX_MSGMAP messageMap; 34 virtual AFX_MSGMAP*GetMessageMap()const; 35 36 #define BEGIN_MESSAGE_MAP(class_name,base_class) 37 AFX_MSGMAP*class_name:GetMessageMap()const 38 return &class_name:messageMap; 39 AFX_MSGMAP class_name:messageMap=&base_class:messageMap,class_name:_messageEntries; 40 AFX_MSGMAP_ENTRY class_name:_messageEntries= 41 42 43 #define ON_COMMAND(id,memFunc) 44 WM_COMMAND,0,id,id,AfxSig_vv,(AFX_PMSG)memFunc , 45 46 #define END_MESSAGE_MAP() 47 0,0,0,0,AfxSig_end,(AFX_PMSG)0 48 ; 49 50 51 52 53 class CObject; 54 class CRuntimeClass 55 56 public: 57 char* m_lpszClassName;/对象所属类名 58 int m_nObjectSize;/对象大小 59 int m_wSchema;/模式号 60 CObject*(PASCAL*m_pfnCreateObject)();/构建函数,抽象类为NULL 61 CRuntimeClass *m_pBaseClasss;/基类CRuntimeClass对象指针。 62 static CRuntimeClass *pFirstClass;/链表头指针。static 63 CRuntimeClass *m_pNextClass;/下一指针。 64 public: 65 CObject*CreateObject() 66 67 if(m_pfnCreateObject=NULL) 68 69 cout该类型不支持动态创建!endl; 70 return NULL; 71 72 CObject*pClass=(*m_pfnCreateObject)(); 73 return pClass; 74 75 static CRuntimeClass*Load() 76 77 couts; 80 for(CRuntimeClass*pClass=pFirstClass;pClass;pClass=pClass-m_pBaseClasss) 81 82 if(pClass-m_lpszClassName=s) 83 84 return pClass; 85 86 87 return NULL; 88 89 ; 90 91 class AFX_CLASSINIT 92 93 public: 94 AFX_CLASSINIT(CRuntimeClass*pNewClass)/构造函数 95 96 pNewClass-m_pNextClass=CRuntimeClass:pFirstClass; 97 CRuntimeClass:pFirstClass =pNewClass; 98 99 ; 100 101 /*/ 102 /* 动态类型识别宏定义 103 /与CRuntimeClass类中的构建函数相区别。此处的CreateObject函数在每个类中都以static成员函数存在,用以 104 /初始化类型型录表,而CRuntimeClass中的CreateObject用于调用每个类的构建函数。仅仅是函数名相同罢了。*/ 105 /*/ 106 107 #define DECLARE_DYNAMIC(class_name) 108 public: 109 static CRuntimeClass Class#class_name; 110 virtual CRuntimeClass*GetRuntimeClass()const; 111 112 113 #define DECLARE_DYNCREATE(class_name) 114 DECLARE_DYNAMIC(class_name) 115 static CObject*PASCAL CreateObject(); 116 117 #define RUNTIME_CLASS(class_name) 118 (&class_name:Class#class_name) 119 120 #define _IMPLEMENT_RUNTIMECLASS(class_name,base_class_name,wSchema,pfnNew) 121 class CRuntimeClass class_name:Class#class_name = 122 #class_name, 123 sizeof(class_name),wSchema,pfnNew,RUNTIME_CLASS(base_class_name),NULL; 124 static AFX_CLASSINIT _init#class_name( RUNTIME_CLASS(class_name); 125 CRuntimeClass *class_name:GetRuntimeClass()const 126 return &class_name:Class#class_name;/此处将class_name写成了classname花了一两天才查出来。啊啊啊啊啊。20120605 127 128 129 #define IMPLEMENT_DYNAMIC(class_name,base_class_name) 130 _IMPLEMENT_RUNTIMECLASS(class_name,base_class_name,0xFFFF,NULL) 131 132 #define IMPLEMENT_DYNCREATE(class_name,base_class_name) 133 CObject*PASCAL class_name:CreateObject()return new class_name; 134 _IMPLEMENT_RUNTIMECLASS(class_name,base_class_name,0xFFFF,class_name:CreateObject) 135 136 137 /*/ 138 /* 对CObject特殊处理。 */ 139 /*/ 140 class CObject 141 142 public: 143 CObject() 144 145 /coutCObject constructor!endl; 146 147 CObject() 148 149 /coutCObject destructor!m_pBaseClasss) 159 160 if(pThis=pClass) 161 162 return true; 163 164 165 return false; 166 167 ; 168 class CRuntimeClass CObject: ClassCObject= 169 170 CObject,sizeof(CObject),0xFFFF,NULL,NULL,NULL 171 ; 172 static AFX_CLASSINIT _init_CObject(&CObject: ClassCObject); 173 CRuntimeClass *CObject:GetRuntimeClass() 174 175 return &CObject:ClassCObject; 176 177 CRuntimeClass*CRuntimeClass:pFirstClass=NULL; 178 179 /*/ 180 /* CCmdTarget是消息传递的终点,因此在实现时不能使用BEGIN_MESSAGE_MAP */ 181 /*/ 182 class CCmdTarget:public CObject 183 184 DECLARE_DYNCREATE(CCmdTarget) 185 DECLARE_MESSAGE_MAP() 186 public: 187 CCmdTarget() 188 189 /coutCCmdTarget constructor!endl; 190 /CreateObject(); 191 192 CCmdTarget() 193 194 /coutCCmdTarget destructor!endl; 195 196 public: 197 198 199 ; 200 IMPLEMENT_DYNCREATE(CCmdTarget,CObject) 201 202 AFX_MSGMAP CCmdTarget:messageMap= 203 NULL,CCmdTarget:_messageEntries; 204 AFX_MSGMAP_ENTRY CCmdTarget:_messageEntries= 205 206 0,0,10,0,AfxSig_end,0, 207 0,0,0,0,AfxSig_end,0 208 ; 209 AFX_MSGMAP*CCmdTarget:GetMessageMap()const 210 211 return &CCmdTarget:messageMap; 212 213 214 class CWnd:public CCmdTarget 215 216 DECLARE_DYNCREATE(CWnd) 217 DECLARE_MESSAGE_MAP() 218 public: 219 CWnd() 220 221 /coutCWnd constructorendl; 222 223 CWnd() 224 225 /coutCWnd destructorendl; 226 227 public: 228 virtual bool Create() 229 230 coutCWnd:Createendl; 231 CreateEx(); 232 return true; 233 234 bool CreateEx() 235 236 coutCWnd:CreateExendl; 237 PreCreateWindow(); 238 return true; 239 240 virtual bool PreCreateWindow() 241 242 coutCWnd:PreCreateWindowendl; 243 return true; 244 245 ; 246 IMPLEMENT_DYNCREATE(CWnd,CCmdTarget) 247 248 class CView :public CWnd 249 250 DECLARE_DYNCREATE(CView) 251 DECLARE_MESSAGE_MAP() 252 public: 253 CView() 254 255 /coutCView constructorendl; 256 257 258 CView() 259 260 /coutCView destructorendl; 261 262 263 ; 264 IMPLEMENT_DYNCREATE(CView,CWnd) 265 266 class CFrameWnd:public CWnd 267 268 DECLARE_DYNCREATE(CFrameWnd) 269 DECLARE_MESSAGE_MAP() 270 public: 271 CFrameWnd() 272 273 /coutCFrameWnd constructorendl; 274 275 276 CFrameWnd() 277 278 /coutCFrameWnd destructorendl; 279 280 public: 281 virtual bool Create() 282 283 coutCFrameWnd:Createendl; 284 CreateEx(); 285 return true; 286 287 virtual bool PreCreateWindow() 288 289 coutCFrameWnd:PreCreateWindowendl; 290 return true; 291 292 ; 293 IMPLEMENT_DYNCREATE(CFrameWnd,CWnd) 294 295 class CWinThread:public CCmdTarget 296 297 public: 298 CWinThread() 299 300 /coutCWinThread constructorendl; 301 302 CWinThread() 303 304 /coutCWinThread destructorendl; 305 306 public: 307 virtual bool InitInstance() 308 309 coutCWinThread:InitInstanceendl; 310 return true; 311 312 virtual bool Run() 313 314 coutCWinThread:Runendl; 315 return true; 316 317 ; 318 class CWinApp:public CWinThread 319 320 DECLARE_MESSAGE_MAP() 321 public: 322 CWinApp() 323 324 /coutCWinApp Constructor endl; 325 m_currentApp=this; 326 327 CWinApp() 328 329 /coutCWinApp destructor endl; 330 331 virtual bool InitApplication() 332 333 coutCWinApp:InitApplicationendl; 334 return true; 335 336 337 virtual bool InitInstance() 338 339 coutCWinApp:InitInstanceendl; 340 return true; 341 342 virtual bool Run() 343 344 coutCWinApp:Runendl; 345 return CWinThread:Run(); 346 347 public: 348 CWinApp*m_currentApp; 349 CFrameWnd*m_currentFrameWnd; 350 ; 351 class CDocument:public CCmdTarget 352 353 DECLARE_MESSAGE_MAP() 354 public: 355 CDocument() 356 357 /coutCDocument constructor endl; 358 359 CDocument() 360 361 /coutCDocunment destructor endl; 362 363 ; 364 class CMyFrameWnd:public CFrameWnd 365 366 DECLARE_DYNCREATE(CMyFrameWnd) 367 DECLARE_MESSAGE_M
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
评论
0/150
提交评论