MFC | Windows窗口消息机制

430 阅读2分钟

「这是我参与2022首次更文挑战的第12天,活动详情查看:2022首次更文挑战

Windows的消息机制:

Windows程序的进行系依靠外部发生的事件来驱动的。程序不断等待(利用一个while循环),等待任何可能的输入,然后做判断,然后再做适当的处理。这个输入由操作系统捕捉到之后,以消息形式进入程序之中。USER模块掌管着各个外围的驱动程序。

  • 由硬件装置所产生的消息(如鼠标移动或键盘被按下),放在系统队列中;
  • 由Windows系统或其它Windows程序传送过来的消息,放在程序队列中。

在应用程序中,应用程序调用GetMessage API来获取一条消息,一个程序能够运行,就是靠它推动的。所有的GUI系统(图形用户界面系统)都是以消息为基础的事件驱动系统。

消息循环:

while(GetMessage(&msg, ...))
{
    TranslateMessage(&msg);//转换键盘消息
    DispatchMessage(&msg);//分派消息
}

TranslateMessage是为了将键盘消息转化,DispatchMessage会将消息传给窗口函数去处理。

消息在发生的时候,操作系统就已经根据当时的状态,为它表明了所属的窗口、消息类型、参数、发生时间等参数,DispatchMessage经过USER模块的协助,就可以把消息发送到窗口函数中。

窗口函数通常利用switch/case的方式判断消息的种类,以决定消息的处置方式。由于消息是被Windows系统所调用的(我们并没有在应用程序的任何地方调用这个函数),所以这是一种callback函数。调用callback函数的原因是因为除了你需要调用它,有很多时候操作系统也要调用你的窗口函数,所以将窗口函数设计为callback形式,才能开放出一个接口给操作系统调用。

窗口函数的形式: LRESULT CALLBACK Wndproc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam);

消息类型结构体:

typedef struct tagMSG
{
    HWND hwnd;
    UINT message;//WM_XXX,例如:WM_MOUSEMOVE
    WPARAM wParam;
    LPARAM lParam;
    DOWRD time;
    POINT pt;
}MSG;

消息映射:

我们常见的MFC的一些消息映射:

消息: 消息处理程序

WM_CREATE, OnCreate,

WM_PAINT, OnPaint,

WM_SIZE, OnSize,

WM_COMMAND, OnCommand,

WM_CLOSE, OnClose,

WM_DESTROY, OnDestroy,

我们在编写MFC程序时,除了会响应系统消息,如鼠标消息,还会响应窗口类消息,如创建、关闭、销毁等,我们有是还需要处理自定义消息。自定义消息是指,程序员自己根据功能的需要,在USER模块中添加一条自定一消息,定义消息的名称和消息的值,这样,当消息循环检测到这条消息时,就会发送到指定的响应函数中去,我们就可以在响应函数中去处理逻辑。