Windows消息机制学习笔记(一)—— 消息队列
生活随笔
收集整理的這篇文章主要介紹了
Windows消息机制学习笔记(一)—— 消息队列
小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
Windows消息機制學習筆記(一)—— 消息隊列
- 基本概念
- 實驗一:使用代碼畫出最簡單窗口
- 第一步:編譯并運行以下代碼
- 第二步:查看運行結(jié)果
- 第三步:使用其它窗口對其進行覆蓋,觀察效果
- 總結(jié)
- 消息隊列
- 消息隊列在哪
- Linux:專用進程
- Windows:GUI線程
- Win32Thread
- 總結(jié)
基本概念
接觸過編程的人,或多或少用到過消息機制,但大多數(shù)人(包括我自己)只是知道相關API的基本用法,卻不知道它是如何實現(xiàn)的
從本章起,我們將帶著以下幾個問題一起來學習消息機制:
實驗一:使用代碼畫出最簡單窗口
第一步:編譯并運行以下代碼
#include <stdio.h> #define _WIN32_WINNT 0x500 #include <windows.h>typedef struct _Color {DWORD r;DWORD g;DWORD b; }Color;typedef struct _WindowClass {DWORD x;DWORD y;DWORD width;DWORD height;Color color; }WindowClass;//按照WindowClass的參數(shù),將hdc中的數(shù)據(jù)打印到指定設備 void PaintWindows(HDC hdc, WindowClass *p) {HBRUSH hBrush;hBrush = (HBRUSH)GetStockObject(DC_BRUSH);SelectObject(hdc, hBrush); //畫刷SetDCBrushColor(hdc, RGB(p->color.r, p->color.g, p->color.b));MoveToEx(hdc, p->x, p->y, NULL);LineTo(hdc, p->x+p->width, p->y);LineTo(hdc, p->x+p->width, p->y+p->height);LineTo(hdc, p->x, p->y+p->height);LineTo(hdc, p->x, p->y);Rectangle(hdc, p->x, p->y, p->width, p->height+1);DeleteObject(hBrush); }int main() {char cMessage; //消息HWND hwnd; //畫在哪HDC hdc; //顯卡緩存//設置窗口參數(shù),長寬高之類的WindowClass wClass;wClass.x = 0;wClass.y = 0;wClass.width = 800;wClass.height = 400;wClass.color.r = 0xEF;wClass.color.g = 0xEB;wClass.color.b = 0xDE;//畫在哪hwnd = GetDesktopWindow();//hwnd = FindWindow("dbgviewClass", NULL);//獲取DC設備句柄:可以把DC理解成顯卡緩存hdc = GetWindowDC(hwnd);for(;;){//畫窗口PaintWindows(hdc, &wClass);cMessage = getchar();switch(cMessage){case 'a':wClass.color.r += 0x10;wClass.color.g += 0x10;wClass.color.b += 0x10;break;case 'b':wClass.color.r -= 0x10;wClass.color.g -= 0x10;wClass.color.b -= 0x10;break;}}return 0; }第二步:查看運行結(jié)果
第三步:使用其它窗口對其進行覆蓋,觀察效果
總結(jié)
思考:如何使窗口能夠接收所有消息
答案:將所有消息放入一塊內(nèi)存中,這塊內(nèi)存被稱之為“消息隊列”
消息隊列
描述:本質(zhì)上是一種數(shù)據(jù)結(jié)構,當對象接收到消息時,將接收到的所有消息放入消息隊列中,等待對象進行處理
規(guī)則:先進先出
消息隊列在哪
Linux:專用進程
Windows:GUI線程
查看KTHREAD結(jié)構體
kd> dt _KTHREAD ntdll!_KTHREAD...+0x130 Win32Thread //若當前程序為控制臺程序且無使用任何圖形界面相關API,該成員為空//若當前程序使用了圖形界面相關的API,該成員指向一個結(jié)構體,該結(jié)構體包含了消息隊列...GUI:微軟提供的與圖形界面相關的API,稱為GUI
GDI:自定義的用于圖形界面相關的API,稱為GDI
GUI線程:
Thread.ServiceTable指向KeServiceDescriptorTable
主要做幾件事:
a. 擴充內(nèi)核棧,必須換成64KB的大內(nèi)核棧,因為普通內(nèi)核棧只有12KB大小
b.創(chuàng)建一個包含消息隊列的結(jié)構體,并掛到KTHREAD上
c.將Thread.ServiceTable指向KeServiceDescriptorTableShadow(只有當調(diào)用GUI時,才會指向SSDTShadow)
d.把需要的內(nèi)存數(shù)據(jù)映射到本進程空間
Win32Thread
描述:位于KTHREAD,若當前程序使用了圖形界面相關的API,該成員指向一個結(jié)構體,其中包含了當前線程的消息隊列:THREADINFO
//FROM ReactOS v0.4.13 typedef struct _THREADINFO{...struct _USER_MESSAGE_QUEUE* MessageQueue; //消息隊列... } THREADINFO;總結(jié)
總結(jié)
以上是生活随笔為你收集整理的Windows消息机制学习笔记(一)—— 消息队列的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Windows内存管理学习笔记(三)——
- 下一篇: Windows消息机制学习笔记(二)——