Windows內部運行機制

 

1.API與SDK

api是windows操作系統提供給應用程序編程的接口(Application Proramming Interface)簡稱api函數,windows有1000多種api函數。

sdk全稱是Software Development Kit,中文譯爲軟件開發包。例如:購買語音卡的同時,廠商就會提供語音卡的sdk,這個sdk通常包含語音卡的api函數庫、幫助文檔、使用手冊、輔助工具等資源。

2.句枘

句柄(HANDLE)是Windows程序中一個重要的概念,使用非常頻繁。在windows程序中,有各種各樣的資源(窗口、圖標、光標等),系統在創建這些資源會爲它們分配內存,並返回標識這些資源的標識號,即句柄。

例窗口句枘(HWND)、圖標句柄(HICON)、光標句柄(HCURSOR)、畫刷句柄(HBRUSH)

 

3.消息

windows程序設計是一事件驅動方式的程序設計模式,主要是基於消息的。

在windows程序中,消息是由MSG結構體來表示的。MSG結構體定義如下

typedef struct tagMSG {

HWND  hwnd;

//消息所屬的窗口

 

UINT   message;

//消息的標識符,消息由數值表識的不便記憶,所以定義爲宏WM_XXX(WM是windows message的縮寫)XXX對定消息英文大寫,例如鼠標左鍵按下消息WM_LBUTTONDOWN,鍵盤按下消息WM_KEYDOWN,字符消息就是WM_CHAR。

 

WPARAM wParam;

LPARAM lParam;

//wParam和lParam用於指定消息的附加信息。例如收到一個字符消息時,message的成員變量就是WM_CHAR,但用戶到底輸入的到底什麼字符,就由wParam和lParam來說明。

 

DWORD  time;

//消息投遞到消息隊列的時間。

 

POINT  pt;

//鼠標的當前位置。

} MSG;

4.消息隊列

每一個windows應用程序開始執行後,系統都會爲該程序創建一個消息隊列,這個消息隊列用來存放該程序創建的窗口的消息。

當消息投放到消息隊列中後,應用程序則通過一個消息循環不斷地從消息隊列中取出消息,並進行響應。這種消息機制,就是windows程序運行的機制。

5.進隊消息和不進隊消息

進隊消息將由系統放入到應用程序的消息隊列中,然後由應用程序取出併發送。不進隊消息在系統調用窗口過程時直接發送給窗口。不管是進隊消息還是不進隊消息,最終都由系統調用窗口過程函數對消息進行處理。

6.WinMain函數

當Windows操作系統啓動一個程序時,它調用的就是該程序的WinMain函數(實際是由插入到可執行文件中的啓動代碼調用的)。WinMain是Windows程序的入口點函數。當WinMain函數結束或返回時,Windows應用程序結束。

int WINAPI WinMain(

  HINSTANCE hInstance,

//當前運行實例的句柄

 

HINSTANCE hPrevInstance,

// 當前實例的前一個實例的句柄,在win32環境下,這個參數總是NULL

 

LPSTR lpCmdLine, 

//以空終止的字符串,指定傳遞給應用程序的命令行參數。

 

int nCmdShow

//指定程序的窗口應該如何顯示,例如最大化、最小化、隱藏等。這個參數的值由該程序的調用者所指定,應用程序通常不需要理會這個參數的值。

);

7.窗口的創建過程

1.設計一個窗口類;

2.註冊窗口類;

3.創建窗口;

4.顯示及更新窗口;

8.窗口類

typedef struct _WNDCLASS {

UINT       style;

//指定這一類型窗口的樣式,CS_HREDRAW水平重畫,CS_VREDRAW垂直重畫,CS_NOCLOSE 禁用Close命令,這將導致窗口沒有關閉按鈕。CS_DBLCLKS當用戶在窗口中雙擊時,向窗口過程發送鼠標雙擊消息。CS(Class Style)

WNDPROC    lpfnWndProc;

//函數指針,指向窗口過程函數,窗口過程函數就是一個回調函數。一個Windows程序可以包包含多個窗口過程函數,一個窗口過程總是與某一個特定的窗口相關聯(通過本成員變量指定),基於該窗口類創建的窗口使用同一窗口過程。

int        cbClsExtra;

//可以爲窗口類分配一個附加的內存空間,由屬於這種窗口類的所有窗口所共享,我們一般將這個參數設置爲0。

int        cbWndExtra;

//爲窗口分配一個附加內存空間,應用程序可以用這部分內存存儲窗口的特有的數據。初始化一般爲0。如果應用程序用WNDCLASS結構註冊對話框(用資源文件中的CLASS僞指令創建)必須給DLGWINDOWEXTRA設置這個成員。

HINSTANCE  hInstance;

//指令包含窗口過程的程序的實例句柄。

HICON      hIcon;

//指定窗口類的圖標句柄。如果這個成員爲NULL,那麼系統提供一個默認的圖標。在爲hIcon變量賦值時可以調用LoadIcon函數加載一個圖標資源,返回一個圖標句柄。

HCURSOR    hCursor;

//爲光標變量賦值時,可以用LoadCusrsor加載一個光標資源,返回光標句柄。用法同LoadIcon

HBRUSH     hbrBackground;

//指定窗口類的畫刷句柄,當窗口發生重繪時,系統使用這裏指定的畫刷來擦除窗口背景。,既可以指定畫刷句柄,也可以指定標準系統顏色值。GetStockObject得到系統標準刷。還可以獲取畫筆、字體和調色板句柄,因爲反回多種資源對像句柄,使用時要根據具體情況,強制轉換。

LPCTSTR    lpszMenuName;

//指定菜單資源的名字。如果爲NULL那麼基於這個窗口類創建的窗口將沒有菜單。

LPCTSTR    lpszClassName;

//指定窗口類的名字。

} WNDCLASS;

9.LoadIcon

HICON LoadIcon(HINSTANCE hInstance,LPCTSTR lpIconName)

如果加載的是系統的標準圖標,第一個參數爲NULL。

10.回調函數

回調函數不是由該函數的實現方直接調用,而是在特定的事件或條件發生時由另外一方調用的,用於對該事件或條件進行響應。

11.回調函數實現機制

1.創建回調函數

2.函數實現一方在初始化時,將回調函數的指外針註冊給調用者。

3.當特定的事件或條件發生時,調用函數通過函數指針調用函數對事件進行處理。

 

12.註冊窗口類

RegisterClass(CONST WNDCLASS *lpWndClass)

13.創建窗口

HWND CreateWindow(

  LPCTSTR lpClassName, 

//指定一個註冊過的窗口類的名字

  LPCTSTR lpWindowName,

//指定一個窗口名字,如果有窗口標題欄,窗口名字將顯示在標題欄上

  DWORD dwStyle,     

//指定創建窗口的樣式。與窗口類中的style不同,這裏的樣式,指的是特定某一窗口的樣式,窗口類中的樣式基於該窗口類創建的窗口都有該樣式。

  int x,                // horizontal position of window

//如果被設爲CW_USEDEFAULT將默認左上角座標,忽略y座標。

  int y,                // vertical position of window

  int nWidth,           // window width

//如果被設爲CW_USEDEFAULT將默認窗品寬度,並忽略長度。

  int nHeight,          // window height

  HWND hWndParent,      // handle to parent or owner window

//子窗口必須有WS_CHILD樣式。對父窗口的操作影響子窗口。

  HMENU hMenu,          // menu handle or child identifier

//指定窗口菜單句柄。

  HINSTANCE hInstance,  // handle to application instance

//指定窗口所屬應用程序實例句柄

  LPVOID lpParam        // window-creation data

//做爲WM_CREATE消息的附加參數lParam傳入的數據指針。創建多文檔界面的客戶窗口時,lpParam必須指向CLIENTCREATESTRUCT結構體。多數窗口將這個參數設置爲NULL。

);

 

14.顯示窗口

調用ShowWindow顯示窗口

BOOL ShowWindow(

HWND hWnd,

//調用CreateWindow時返回的句柄

int nCmdShow

//指定窗口顯示狀態,常用有如下

SW_HIDE:隱藏並激活其他窗口

SW_SHOW:在窗口原來的位置以原來的尺寸激活和顯示窗口。

SW_SHOWMAXIMIZED:激活窗口並將其最大化顯示。

SW_SHOWMINIMIZED:激活窗口並將其最小化顯示。

SW_SHOWNORMAL:激活並顯示窗口。如果窗口最小化或或最大化狀態,系統將其恢復到原來的尺寸和大小。

);

 

15.更新窗口

調用ShowWindow後緊接着調用UpdateWindow來刷新窗口

BOOL UpdateWindow(

HWND hWnd

);

//此處也是CreateWindows返回的窗口句柄

UpdateWindow函數通過發送一個WM_PAINT消息來刷新窗口。UpdateWindow將WM_PAINT消息直接發送給了窗口過程函數進行處理。此消息並沒有放進消息隊列。

 

16.消息循環

在創建窗口,顯示窗口,更新窗口後,需要一個消息循環,不斷地從消息隊列中取出消息,並進行響應。

BOOL GetMessage(

  LPMSG lpMsg,         // message information

//指向一個消息結構體,GetMessage從線程的消息隊列中取出的消息將保存在該結構體對象中。

  HWND hWnd,           // handle to window

//指定接收屬於哪一窗口的消息。通常設置成NULL,用於接收屬於調用線程的所有窗口的窗口消息。

  UINT wMsgFilterMin,  // first message

//指定獲取消息的最小值,通常設置爲0。

  UINT wMsgFilterMax   // last message

//獲取的消息的最大值。如果都設置爲0將獲取所有消息。

);

GetMessage函數接收到除WM_QUIT外的消息均返回非零值。對於WM_QUIT消息,該函數返回零。如果出現錯誤,如果返回-1。

 

 

BOOL PeekMessage(

  LPMSG lpMsg,         // message information

  HWND hWnd,           // handle to window

  UINT wMsgFilterMin,  // first message

  UINT wMsgFilterMax,  // last message

  UINT wRemoveMsg      // removal options

);

另一種從消息隊列中獲取消息的方法,唯一不同的是最後多一個參數,當參數是PM_NOREMOVE時,消息不會從消息隊列中移除,PM_REMOVE時跟GetMessage一樣

發送消息可以使用SendMessage和PostMessage函數。SendMessage將消息發送給窗口,並調用該窗口過程進行處理。在窗口過程對消息處理完畢後,該函數才返回。(SendMessage爲不進隊消息)。PostMessage函數將消息放入與創建窗口的線程相關聯的消息隊列後立即返回。PostThreadMessage函數用於向線程發送消息。

17.窗口過程函數

LRESULT CALLBACK WindowProc(

  HWND hwnd,      // handle to window

  UINT uMsg,      // message identifier

  WPARAM wParam,  // first message parameter

  LPARAM lParam   // second message parameter

);

18.DC

設備描述表,Device Context簡稱DC。DC是一個包含設備(物理輸出設備,如顯示器,以及設備驅動程序)信息的結構體,在Windows平臺下,所有的圖形操作都是利用DC來完成的。比如要得到與窗口相關聯的DC句柄  HDC hdc=GetDC(hWnd);

19.WM_PAINT

當窗口客戶區的一部分或者全部變爲”無效時”系統會發送WM_PAINT消息,如果窗口從無到有、改變尺寸、最小化後在恢復、被其它窗口遮蓋後再顯示時。窗口大小變化是否會發生重繪也取決於在窗口類設計時style是否不水平重繪和垂直重繪。

在響應WM_PAINT消息代碼中,要得到窗口的DC,必須調用BeginPaint函數。BeginPaint函數也只能在WM_PAINT消息響應代碼中使用,在其他地方,只能使用GetDC。另代,BeginPaint函數得到的DC必須用EndPaint函數勻釋放。

20.PostQuitMessage

投放一個WM_QUIT消息到消息隊列中函數參數將做爲WM_QUIT的wParam一般用做WinMain函數的返回值,GetMessage接到WM_QUIT消息時返回0消息循環結束程序退出。

21.DefWindowProc

此函數調用默認窗口過程,對應用程序沒有處理的消息進行默認處理。在編寫窗口過程時一般放在default裏

 


本文來自CSDN博客,轉載請標明出處:http://blog.csdn.net/subleo/archive/2009/08/13/4440532.aspx

發佈了209 篇原創文章 · 獲贊 6 · 訪問量 41萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章