Windows核心編程隨筆

最近在學習Windows底層原理,準備寫個系列文章分享給你們,Michael Li(微軟實習期間的Mentor,爲人超好)在知乎回答過一些關於學習Windows原理的書籍推薦,你們能夠拜讀其中一原本入門。我是先從《Windows核心編程》開始瞭解一些Windows底層管理與硬件交互的原理,而後買了一套冬瓜哥撰寫的《大話計算機》系列叢書,學有餘力的童鞋強烈推薦你去看看,這套書對計算機總體的運做原理講解的很系統,涉及了計算機組成原理、網絡原理、編譯原理、操做系統、硬件等,能夠做爲不錯的入門教材。html

Windows核心編程(第5版)電子書及配套代碼linux

學習前須要理解一些系統專業詞彙的概念,好比:系統資源、內存管理、句柄、內核態/用戶態、Hook、事件、消息處理機制等。否則後續對Windows底層原理的理解會有些偏差和盲區,例如很容易將系統資源和CPU資源(CPU使用率)相混淆。git

咱們將Linux、Unix、Windows對其內核進行對比學習Windows的內核管理機制。參考

Linux:
Linux 優先使用物理內存,當物理內存還有空閒時,linux是不會釋放內存的,即時佔用內存的程序已經被關閉了(這部份內存就用來作緩存了)。也就是說,即時你 有很大的內存,用過一段時間後,也會被佔滿。這樣作的好處是,啓動那些剛開啓過的程序、或是讀取剛存取過得數據會比較快,對於服務器頗有好處。github

Windows:
windows則老是給內存留下必定的空閒空間,即時內存有空閒也會讓程序使用一些虛擬內存,這樣作的好處是,啓動新的程序比較快,直接分給它些空閒內存就能夠了,而linux下呢?因爲內存常常處於所有被使用的狀態,則要先清理出一塊內存,再分配給新的程序使用,所以,新程序的啓動會慢一些。編程

Windows是由C語言編寫的,可是整個系統是面向對象設計的,因此引入了句柄這種數據結構。句柄是一種指向指針的指針,確切點說句柄是一種指向結構體的指針,而指針就是一串內存地址。
Windows是基於事件驅動機制的,整個系統都是經過消息傳遞來實現的。windows

Issue:

各大系統平臺的程序是用什麼機制來接收用戶的事件而作出反應的?緩存

Windows的消息系統是如何支持帶有圖形用戶界面的應用程序?安全

點擊鼠標,觸發一個系統事件(事件本質上是對消息的封裝)——>Windows把這個事件翻譯爲消息,而後把它放到消息隊列中,傳遞給應用程序——>應用程序從消息隊列中接收到這個消息,把它存放在TMsg記錄中——>應用程序把消息傳遞給一個適當的窗口的窗口過程(回調函數)——>窗口過程響應這個消息並進行處理服務器

Windows操做系統消息包括:標準Windows消息(WM_打頭) + 通知消息(針對標註Windows控件) + 自定義消息(編程)網絡

消息系統(內核控制中心)組成:消息隊列 + 消息循環 + 窗口過程

在Windows中發生的一切均可以用消息來表示,消息用於告訴操做系統發生了什麼,全部的Windows應用程序都是消息驅動的。消息自己是做爲一個記錄傳遞給應用程序的,這個記錄(通常在 C/C++/彙編 中稱爲「結構體」)中包含了消息的類型以及其餘信息。例如,對單擊鼠標所產生的消息來講,這個記錄(結構體)中包含了單擊鼠標的消息號(WM_LBUTTONDOWN)、單擊鼠標時的座標(由X,Y值鏈接而成的一個32位整數)。這個記錄類型叫作TMsg。

在C語言中消息的定義:

typedef struct Msg
{
HWND hwnd; / /窗口句柄
UINT message; / /消息常量標識符
WPARAM wParam; // 32位消息的特定附加信息
LPARAM lParam; // 32位消息的特定附加信息
DWORD time; / /消息建立時的時間
TPoint pt; / /消息建立時的鼠標位置
} TMsg;
typedef struct TPoint
{
int x;
int y;
}TPoint;

不是每一個控件都能接收消息,轉發消息和繪製自身,只有具備句柄(handle)的控件才能作到。有句柄的控件本質上都是一個窗體(window),它們能夠獨立存在,能夠做爲其它控件的容器,而沒有句柄的控件,如Label,是不能獨立存在的,只能做爲窗口控件的子控件,它不能繪製自身,只能依靠父窗體將它繪製來。

然而,並不是全部的句柄都是窗體的句柄,Windows系統中還中不少其它類型的句柄,如畫布(hdc)句柄,畫筆句柄,畫刷句柄,應用程序句柄(hInstance)等。這種句柄是不能接收消息的。但不論是哪一種句柄,都是系統中對象的惟一標識。本文只討論窗體句柄。

那爲何句柄使窗口具備瞭如此獨特的特性呢?實際是都是因爲消息的緣由。因爲有了句柄,窗體可以接收消息,也就知道了該何時繪製本身,繪製子控件,知道了鼠標在何時點擊了窗口的哪一個部分,從而做出相應的處理。句柄就好像是一我的的身份證,有了它,你就能夠從事各類社會活動;不然的話,你要麼是一個社會看不到的黑戶,要麼跟在別人後面,經過別人來證實你的存在。

Windows保存的消息隊列是以線程(Thread)來分組的,也就是說每一個線程都有本身的消息隊列。事件本質上是對消息的封裝。


有哪些內核對象:

令牌對象 Token

事件對象 Event

文件對象 File

文件映射對象 Mapping File

線程對象 Thread

時鐘對象 Timer

線程池對象 ThreadPool

I/O完成端對象 Completion port

工做對象 Job

郵槽對象 Mailslot

互斥對象 Mutex

管道對象 Pipe

進程對象 Process

信號燈對象 Semaphore

...

內核對象的結構:

公用部分(安全描述符、計數器) + 個性部分

句柄、Windows數據類型:

WORD:16位無符號整型數據

DWORD:32位無符號整型數據(DWORD32)

DWORD64:64位無符號整型數據

INT:32位有符號整型數據類型

INT_PTR:指向INT數據類型的指針類型

INT32:32位符號整型

INT64:64位符號整型

UINT:無符號INT

LONG:32位符號整型(LONG32)

ULONG:無符號LONG

LONGLONG:64位符號整型(LONG64)

SHORT:無符號短整型(16位)

LPARAM:消息的L參數

WPARAM:消息的W參數

HANDLE:對象的句柄,最基本的句柄類型

HICON:圖標的句柄

HINSTANCE:程序實例的句柄

HKEY:註冊表鍵的句柄

HMODULE:模塊的句柄

HWND:窗口的句柄

LPSTR:字符指針,也就是字符串變量

LPCSTR:字符串常量

LPCTSTR:根據環境配置,若是定義了UNICODE宏,則是LPCWSTR類型,不然則爲LPCSTR類型

LPCWSTR:UNICODE字符串常量

LPDWORD:指向DWORD類型數據的指針

CHAR:8比特字節

TCHAR:若是定義了UNICODE,則爲WCHAR,不然爲CHAR

UCHAR:無符號CHAR

WCHAR:16位Unicode字符

BOOL:布爾型變量

BYTE:字節類型(8位)

CONST:常量

FLOAT:浮點數據類型

SIZE_T:表示內存大小,以字節爲單位,其最大值是CPU最大尋址範圍

VOID:無類型,至關於標準C語言中的void

WINAPI:Windows API的函數調用方式,常見於SDK頭文件中對API函數的聲明中,至關於_stdcall(更嚴格地說,這不是數據類型,而是一種函數調用約定

BYTE 8位 unsigned char

CHAR 8位 char

BOOL 16位 int

DWORD 32位 unsigned long int

HANDLE 通常句柄

HWND 32位 long int

LONG 32位 long int

LPCSTR 指向字符串的 const 指針

LPSTR 指向字符串的指針

SHORT 16位短整數

UINT 32位無符號長整數

WORD 16位無符號短整數

BITMAP 獨立於邏輯設備的位圖(DIB)

LOGBRUSH 邏輯刷

LOGFONT 邏輯字體

LOGPEN 邏輯筆

MSG 窗口消息

POINT 點

RECT 矩形

WNDCLASS 窗口類結構

hBitmap 爲保存DIB圖像信息的內存域的句柄

hBrush 當畫圖時用於填滿設備範圍的刷子的句柄

hCtl 子窗口控件的句柄

hCursor 鼠標光標句柄

hDc 設備描述表句柄

hDlg 文本字體的句柄

hFont 文本字體的句柄

hIcon 圖標的句柄

hInstance windows應用程序實例句柄

hMem 內存塊句柄

hMenu 菜單或彈出式菜單句柄

hModule 模式的句柄,經常使用於從一可執行文件獲取資源數據

hPalette 顏色調色板

hPen 當在設備上畫圖時用於指明線型的筆的句柄

hRgn 在窗口上剪貼一塊區域的句柄

hTask 獨立於已執行的任務的句柄

hWnd 窗口句柄

持續更新中...

相關文章
相關標籤/搜索