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