您的位置:逆风者 VC++ 正文
 添加时间:2007-09-01 原文发表:2007-08-31 人气:80 来源:vckbase.com

本文章共5248字,分4页,当前第1页,快速翻页:
 

VC初学者入门系列之二:消息循环


作者:jxhnuaa(铁凌)


适用读者:VC初学者并有C 基础。
逆风编程精品

VC初学者入门系列之一:窗口类的诞生

一、传统SDK程序的消息循环

在传统的SDK程序中,消息循环是很简单的,也许你不信,那我们就看看下面这段代码吧:

#include <windows.h>

LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM) ;

int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance,

                    PSTR szCmdLine, int iCmdShow)

{

	static TCHAR szAppName[] = TEXT ("HelloWin") ;

	WNDCLAS	wndclass ;



 	wndclass.style	  = CS_HREDRAW | CS_VREDRAW ;

 	wndclass.lpfnWndProc  = WndProc ;

	wndclass.lpszClassName	= szAppName ;



	RegisterClass (&wndclass);



	hwnd = CreateWindow( szAppName,……,NULL);

     

	ShowWindow (hwnd, iCmdShow) ;

	UpdateWindow (hwnd) ;

     

	while (GetMessage (&msg, NULL, 0, 0))

       {

		TranslateMessage (&msg) ;

  		DispatchMessage (&msg) ;

          }

	return msg.wParam ;

}

LRESULT CALLBACK WndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)

{    

	switch (message)

          {

case WM_CREATE:

                     ………

	case WM_PAINT:

                     ………

	case WM_DESTROY:

		PostQuitMessage (0) ;

		return 0 ;

          }

   return DefWindowProc (hwnd, message, wParam, lParam) ;

}

  在WinMain 中 CreateWindow通过一个参数将创建的窗口和窗口类(见"窗口类的诞生"一文)联系起来,这样该窗口的所有消息都将发送到该窗口类的窗口函数WndProc,其后WndProc根据不同的消息给予不同的动作。

二、MFC期望的消息循环
  在传统的SDK程序中消息循环是非常简单的,并且将窗口和窗口函数绑定在一起。而在MFC中就出现了问题,比如CDocument类,不是窗口,所以没有窗口类,但是我也想让它响应消息,怎办?问题不仅仅如此,我们再看看MFC的消息,就会发现更多问题。
  MFC将消息分为三大类:1.标准消息,即除WM_COMMAND之外的任何WM_开头的消息,任何派生自CWnd的类都可以接受该消息,并按照继承关系接受(如从CScrollView到CView再到CWnd)。2.命令消息,即WM_COMMAND,任何派生自CCmdTarget的类,兼可接受该消息,接受顺序如下图所示,其中标号标注了接受消息的顺序,箭头代表调用顺序 :


图1 消息的拐弯流动

3.Control Notification,通知类消息,也以WM_COMMAND形式出现,由控件产生,通知其父窗口。

三、消息宏背后的秘密
  知道了MFC消息流动的要求,那MFC是怎样实现的呢?当一个消息出现时,Application FrameWork怎么知道将该消息发送给哪个对象的呢?其实都是CCmdTarget类在作怪,所有能够接受消息的类都必须继承于CCmdTarget类,因为这些类都一个共同的特征:含有DECLARE_MESSAGE_MAP、BEGIN_MESSAGE_MAP、END_MESSAGE_MAP三个宏。啊!就这三个宏组织了一张庞大的消息映射网,也许你不信,那我们就看看这三个宏是怎样定义的:
#define DECLARE_MESSAGE_MAP()\

private:\

     static const AFX_MSGMAP_ENTRY _messageEntries[];\

protected:

     static AFX_DATA const AFX_MSGMAP messageMap;\

     virtual const AFX_MSGMAP* GetMessageMap() const;\



#define BEGIN_MESSAGE_MAP(theClass, baseClass)\

     const AFX_MSGMAP* theClass::GetMessageMap() const\

{return &theClass::messageMap;}\

AFX_DATADEF const AFX_MSGMAP theClass::messageMap = \

{&baseClass::messageMap, &theClass::_messageEntries[0]};\

const AFX_MSGMAP_ENTRY theClass::_messageEntries[]=\

{\



#define END_MESSAGE_MAP()\

{0,0,0,0,AfxSig_end,(AFX_pMSG)0}\

};\



typedef void (AFX_MSG_CALL CCmdTarget::*AFX_PMSG)(void);

struct AFX_MSGMAP_ENTRY

{

     UINT  nMessage;

     UINT  nCode;

     UINT  nID;

     UINT  nLastID;

     UINT  nSig;

     AFX_PMSG pfn;

};

struct AFX_MSGMAP

{

    const AFX_MSGMAP* pBaseMap;

    const AFX_MSGMAP_ENTRY* lpEntries;

};

 
 
本文章更多内容1 - 2 - 3 - 4 - 下一页>>
相关文章

PhotoShop插件开发之选区(Selection)
编写多文档应用程序
COM 组件设计与应用(五)——用 ATL 写第一
MFC程序员的WTL指南: 中文版序言
不重起Windows直接更改IP地址
类似于FlashGet的悬浮框的制作
毫秒定时器
C :使用 Visual C 2005 的现代语言特色
IP Messenger 详细分析
可设置单元格颜色的ClistCtrl类
定制调试诊断工具和实用程序——摆脱DLL“地
WMI 的一个实现
自绘按钮的实现
《系统飞狐》系列软件中的“系统监视器”开
定时显示远程计算机的桌面
一个实用的CToolBar扩展类CToolBarEx
简单实用的Xml解析类
SQL Server 索引结构及其使用(三)
图形显示特技算法
论程序设计方法

相关评论


本文章所属分类:首页 VC++

  热门关键字: