MFC框架原理以及消息运行机制

本文深入探讨MFC框架的基础,详细解释Windows程序的事件驱动机制,侧重于消息结构、消息队列、窗口过程以及窗口类。讨论了如何创建和管理窗口,包括窗口类注册、窗口创建、显示和更新。此外,还涵盖了窗口过程函数(回调函数)、消息循环、以及消息响应函数,如WM_CREATE和WM_PAINT。文章还涉及C++特性在MFC中的应用,如构造函数、析构函数、函数重载和多态性。最后,介绍了MFC中的菜单编程,包括命令消息、菜单项状态更新以及动态菜单的创建与响应处理。
摘要由CSDN通过智能技术生成

1,Windows程序内部运行机制

      (1)windows程序设计是种事件驱动方式的程序设计,主要基于消息的。当用户需要完成某种功能时,需要调用OS某种支持,然后OS将用户的需要包装成消息,并投入到消息队列中,最后应用程序从消息队列中取走消息并进行响应。
2
,消息结构:
typedef struct tagMSG {     // msg 

    HWND   hwnd;     //接收消息的窗口句柄。和哪个窗口相关联。
    UINT   message;  //
消息标识。消息本身是什么。
    WPARAM wParam;   //
消息的附加信息。具体取决于消息本身。  
    LPARAM lParam; 
    DWORD  time;     //消息投递时间。 
    POINT  pt;       //
消息投递时,光标在屏幕上的位置。 
} MSG;

3,消息队列:
每个应用程序OS都为它建立一个消息队列,消息队列是个先进先出的缓冲区,其中每个元素都是一个消息,OS将生成的每个消息按先后顺序放进消息队列中,应用程序总是取走当前消息队列中的第一条消息,应用程序取走消息后便知道用户的操作和程序的状态,然后对其处理即消息响应,消息响应通过编码实现。

4,使用VC编程除了良好的C基础外还需要掌握两方面:
一,消息本身。不同消息所代表的用户操作和应用程序的状态。
二,对于某个特定的消息来说,要让OS执行某个特定的功能去响应消息。

5Window程序入口:
int WINAPI WinMain(
  HINSTANCE hInstance,  //
当前事例句柄。
  HINSTANCE hPrevInstance,  //
先前事例句柄。
  LPSTR lpCmdLine,      //
命令行指针
  int nCmdShow          //
(窗口)显示的状态
);
说明:WinMain函数是Windows程序入口点函数,由OS调用,当OS启动应用程序的时候,winmain函数的参数由OS传递的。

6,创建一个完整的窗口需要经过下面四个操作步骤:
一,设计一个窗口类;如:WNDCLASS wndcls;
二,注册窗口类;    如:RegisterClass(&wndcls);
三,创建窗口;     如:CreateWindow(),CreateWindowEX();
四,显示及更新窗口。如:ShowWindow(),UpdateWindow();

说明:创建窗口的时候一定要基于已经注册的窗口类.

7Windows提供的窗口类:
typedef struct _WNDCLASS { 

    UINT   style;        //窗口的类型
    WNDPROC lpfnWndProc;  //
窗口过程函数指针(回调函数)
    int     cbClsExtra; //
窗口类附加字节,为该类窗口所共享。通常0
    int     cbWndExtra; //
窗口附加字节。通常设为0
    HANDLE  hInstance;  //
当前应用程序事例句柄。
    HICON   hIcon;      //
图标句柄 LoadIcon();
    HCURSOR hCursor;    //
光标句柄 LoadCursor();
    HBRUSH  hbrBackground; //
画刷句柄 (HBRUSH)GetStockObject();
    LPCTSTR lpszMenuName;  //
菜单名字
    LPCTSTR lpszClassName; //
类的名字 
} WNDCLASS;

8,窗口类注册:
ATOM RegisterClass(
  CONST WNDCLASS *lpWndClass   // address of structure withclass 

                              // data
);

9,创建窗口:
HWND CreateWindow(
  LPCTSTR lpClassName,  // pointer to registered class name
  LPCTSTR lpWindowName, // pointer to window name
  DWORD dwStyle,        // window style
  intx,               // horizontal position of window
  inty,               // vertical position of window
  int nWidth,          // window width
  int nHeight,          //window height
  HWND hWndParent,      // handle to parent orowner window
  HMENU hMenu,          //handle to menu or child-window identifier
  HANDLE hInstance,     // handle to applicationinstance
  LPVOID lpParam        // pointer towindow-creation data
);

10,显示和更新窗口窗口:
BOOL ShowWindow(
  HWND hWnd,     // handle to window
  int nCmdShow   // show state of window
);
BOOL UpdateWindow(
  HWND hWnd   // handle of window
);

11,消息循环:
MSG msg;
while(GetMessage(&msg,...))    //
从消息队列中取出一条消息
{
TranslateMessage(&msg); //
进行消息(如键盘消息)转换
DispatchMessage(&msg); //
分派消息到窗口的回调函数处理,OS调用窗口回调函数进行处理)。
}

其中:
//**The GetMessage function retrieves a message from the calling thread'smessage queue and places it in the specified structure. 

//**If the function retrieves a message other than WM_QUIT, the return value isnonzero.If the function retrieves the WM_QUIT message, the return value iszero. If there is an error, the return value is -1.

BOOLGetMessage(
  LPMSG lpMsg,         // addressof structure with message
  HWND hWnd,          // handle of window
  UINT wMsgFilterMin,  // first message
  UINT wMsgFilterMax   // last message
);


//The TranslateMessage function translates virtual-key messages into charactermessages. The character messages are posted to the calling thread's messagequeue, to be read the next time the thread calls the GetMessage or PeekMessagefunction. 

BOOL TranslateMessage(
  CONST MSG *lpMsg   // address of structure with message
);

//TheDispatchMessage function dispatches a message to a window procedure. 
LONG DispatchMessage(
  CONST MSG *lpmsg   // pointer to structure with message
);


12
,窗口过程函数(回调函数)原型:
The WindowProc function is an application-defined function that processesmessages sent to a window. The WNDPROC type defines a pointer to this callbackfunction. WindowProc is a placeholder
(占位符) for the application-defined function name.

LRESULTCALLBACK WindowProc(  //这里WindowProc是个代号名字。
  HWND hwnd,      // handle to window
  UINT uMsg,      // message identifier
  WPARAM wParam,  // first message parameter
  LPARAM lParam   // second message parameter
);

说明:两种函数调用约定(__stdcall __cdecl):
#define CALLBACK    __stdcall 

//__stdcall 标准调用预定,是PASCAL调用约定,象DELPHI使用的就是标准调用约定
#define WINAPIV     __cdecl  

// __cdecl C 语言形式的调用约定。


主要区别:函数参数传递顺序和对堆栈的清除上。
问题:除了那些可变参数的函数调用外,其余的一般都是__stdcall约定。但 C/C++编译默然的是__cdecl约定。所以如果在VC等环境中调用__stdcall约定的函数,必须要在函数声明的时加上__stdcall 修饰符,以便对这个函数的调用是使用__stdcall约定(如使用DELPHI编写的DLL时候)。
VC中可通过这途径修改:project|settings..|c/c++|...)


在窗口过程函数中通过一组switch语句来对消息进行处理:
如:
LRESULT CALLBACK WindowProc(  

  HWND hwnd,
  UINT uMsg,
  WPARAM wParam,
  LPARAM lParam   
)
{
    switch(uMsg)
    {
case WM_PAINT:
  ...
  break;
case ...
  break;
case WM_CLOSE:
  //DestroyWindow(hwnd);
   //销毁窗口,并发送WM_DESTROY消息。
  break;
case WM_DESTROY:
  //PostQuitMessage(0);
  //
发送WM_QUIT消息到消息队列中,请求终止。
         //GetMessage()
取到WM_QUIT消息后,返回0,退出消息循               //   环,从而终止应用程序。
  break;
default:
  return DefWindowProc(hwnd,uMsg,wParam,lParam);
//
用缺省的窗口过程处理我们不感兴趣的消息(其它消息)。
//
这是必须的。
    }//switch
return 0;
}//WindowProc

13DestroyWindow()函数和PostQuitMessage()函数原型:
//**The DestroyWindow function destroys the specified window. The functionsends WM_DESTROY and WM_NCDESTROY messages

BOOLDestroyWindow(
  HWND hWnd   // handle to window to destroy
);

//**ThePostQuitMessage function indicates to the system that a thread has made arequest to terminate (quit). It is typically used in response to a WM_DESTROYmessage. 
//**The PostQuitMessage function posts a WM_QUIT message to the thread'smessage queue and returns immediately; the function simply indicates(预示,通知) to the system that thethread is requesting to quit at some time in the future.

When the thread retrieves the WM_QUIT message from its messagequeue, it should exit its message loop and return control to the system.

VOIDPostQuitMessage(
  int nExitCode   // exit code
);

14,关于DC句柄获取:
a)
使用BeginPaint(),EndPaint()对。注意只能在响应WM_PAINT消息时使用。
b)
使用GetDc(),ReleaseDC()对。注意他们不能在响应WM_PAINT中使用。

(2)C++

1c语言中,结构体struct中不能包括函数的,而在C++struct中可以包括函数。
2
C++中结构体和类可以通用,区别主要表现在访问控制方面:struct中默认是public,而 class中默认的是private
3
,构造函数最重要的作用是创建对象的本身,C++中每个类可以拥有多个构造函数,但必须至少有一个构造函数,当一个类中没有显式提供任何构造函数,C++编辑器自动提供一个默认的不带参数的构造函数,这个默认的构造函数只负责构造对象,不做任何初始化工作。但在一个类中只要自己定义一个构造函数,不管带参不带参,编辑器不再提供默认的不带参的构造函数了。构造函数没有返回值。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值