自学内容网 自学内容网

11 消息机制

我们在初级班对于Win32 API的学习中,知道可以通过向窗口发送消息实现交互,但是我们始终没有从本质上了解什么是消息机制,从而也就无法回答如下这些问题。

images/download/attachments/3440655/image2023-9-18_10-55-18.png

因此为了弄清楚这些问题,我们就必须进入0环,从底层理解消息机制的本质。

消息队列

什么是消息队列

首先我们要理解什么是消息队列,我们可以编写运行如下代码,在桌面的左上角画上一个窗口,接着我们可以通过发送消息来与窗口进行互动:

#include <Windows.h>

typedef struct _Color

{

DWORD red;

DWORD green;

DWORD blue;

} Color;

typedef struct _WindowClass

{

DWORD x;

DWORD y;

DWORD width;

DWORD height;

Color color;

} WindowClass;

void PaintWindow(HDC hdc, WindowClass* window)

{

HBRUSH hBrush = (HBRUSH)GetStockObject(DC_BRUSH);

SelectObject(hdc, hBrush);

SetDCBrushColor(hdc, RGB(window->color.red, window->color.green, window->color.blue));

MoveToEx(hdc, window->x, window->y, NULL);

LineTo(hdc, window->x + window->width, window->y);

LineTo(hdc, window->x + window->width, window->y + window->height);

LineTo(hdc, window->x, window->y + window->height);

LineTo(hdc, window->x, window->y);

Rectangle(hdc, window->x, window->y, window->x + window->width, window->y + window->height + 1);

DeleteObject(hBrush);

}

int main()

{

char cMessage;

HWND hwnd;

HDC hdc;

WindowClass windowClass;

windowClass.x = 0;

windowClass.y = 0;

windowClass.width = 800;

windowClass.height = 400;

windowClass.color.red = 0xEF;

windowClass.color.green = 0xEB;

windowClass.color.blue = 0xDE;

hwnd = GetDesktopWindow();

hdc = GetWindowDC(hwnd);

for (;;)

{

PaintWindow(hdc, &windowClass);

cMessage = getchar();

switch (cMessage)

{

case 'a':

windowClass.color.red += 0x10;

windowClass.color.green += 0x10;

windowClass.color.blue += 0x10;

break;

case 'b':

windowClass.color.red -= 0x10;

windowClass.color.green -= 0x10;

windowClass.color.blue -= 0x10;

break;

}

}

getchar();

return 0;

}

编译运行这段代码,我们输入a或者b进行回车,一开始创建的窗口就会随着不同的指令进行颜色的切换。

images/download/attachments/3440655/image2023-10-8_20-30-43.png

这段代码是一个简单的交互程序,它通过接收键盘消息与窗口进行交互。然而,它有一个限制,即只能处理键盘消息,而无法处理鼠标或其他进程发来的消息。

因此我们希望接收并处理所有类型的消息,就需要提供一个容器,即消息队列。将所有消息都存放在消息队列中,进程再从消息队列中获取。

images/download/attachments/3440655/image2023-10-8_20-45-1.png

消息队列存放位置

用户空间

如果消息队列存在于用户空间,也就表示每个进程有一个独属于自己的消息队列,那么就需要有一个专用进程来对不同类型的消息进行分发。

Linux操作系统就采用了一种类似的机制,通过单独的进程专门负责接收消息,并将消息发送给不同的进程进行处理。但这种方法需要进行频繁的跨进程通信,可能导致效率下降。

images/download/attachments/3440655/image2023-10-8_20-56-46.png

内核空间

在Windows操作系统上微软采用了一种不同的策略。由于在0环(内核空间)中,不同进程的地址空间往往是相同的(即我们常说的高2G为共享内存),因此可以将消息队列存储在内核空间


原文地址:https://blog.csdn.net/qicaiyuwu/article/details/144999828

免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!