当前位置: 首页 > article >正文

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为共享内存),因此可以将消息队列存储在内核空间


http://www.kler.cn/a/487964.html

相关文章:

  • matlab编写分段Hermite插值多项式
  • idea全局替换显示不全(ctrl+shift+R)
  • ADO.NET知识总结3---SqlCommand命令对象
  • 力扣刷题:数组OJ篇(下)
  • unity学习14:unity里的C#脚本的几个基本生命周期方法, 脚本次序order等
  • IDEA 字符串拼接符号“+”位于下一行的前面,而不是当前行的末尾
  • 优化 Azure Synapse Dedicated SQL Pool中的 SQL 执行性能的经验方法
  • 在爱快iKuai路由系统上添加docker功能!操作很简单
  • 【漫话机器学习系列】041.信息丢失(dropout)
  • Http请求响应——请求
  • CES Asia 2025:VR/AR/XR引领科技新潮流
  • 12_Redis发布订阅
  • Unity + Firebase + GoogleSignIn 导入问题
  • 三线结构光避障远近有度,石头自清洁扫拖机器人G30上市
  • 信息系统管理师试题-流程管理
  • 【环境搭建】Metersphere v2.x 容器部署教程踩坑总结
  • 道品科技智慧农业与云平台:未来农业的变革之路
  • 【集成学习】Bagging算法详解及代码实现
  • 初学stm32 --- DAC模数转换器工作原理
  • #Phi-4:微软 14B 参数开源模型,性能匹敌 OpenAI GPT-4o-mini,现已登陆 Ollama
  • 互联网全景消息(10)之Kafka深度剖析(中)
  • 软件测试基础知识③—计算机网络基础
  • redis 模糊删除
  • 电脑每次开机卡到windows图标界面进不去
  • 设计模式 行为型 模板方法模式(Template Method Pattern)与 常见技术框架应用 解析
  • Git:merge合并、冲突解决、强行回退的终极解决方案