BOOLInitWindowsClass(HINSTANCEhInstance);//注冊窗口類BOOLInitWindows(HINSTANCEhInstance,intnCmdShow);//創建窗口LRESULTCALLBACKWndProc(HWND,UINT,WPARAM,LPARAM);//窗口函數聲明HWNDhMainWnd;//全局實例窗口句柄LPCTSTRlpszProviderClass=__TEX" />

欧美三区_成人在线免费观看视频_欧美极品少妇xxxxⅹ免费视频_a级毛片免费播放_鲁一鲁中文字幕久久_亚洲一级特黄

Windows編程之SDK窗口程序淺析

系統 2169 0

Windows編程之SDK窗口程序淺析

SDK 編寫 Windows 程序需完成 3 個框架模塊:

<1> 填空賦值 WNDCLASS 定義窗口類并注冊;

<2> 創建窗口,顯示、刷新窗口;

<3> 消息循環,編寫消息處理函數。

熟悉框架后,我們的重點工作放在感興趣的消息處理上。

有以上分析可分模塊完成注冊窗口類和創建窗口工作,即分別設計功能函數 InitWindowsClass InitWindows ,改造后的完整程序如下,從以下程序可以更清楚的認識 windows 程序框架。

Windows 窗口應用程序與 DOS 控制臺應用程序是不同的,編寫一個基于 Windows API 的典型的應用程序需要編寫處理以下四個任務:

l 初始化

l 實例化

l 啟動消息循環

l 響應消息

前面三個任務總是發生在 WinMain 函數中, WinMain 是每一個 Windows 程序的入口點,相當 C/C++ 中的 main 。第四個任務是傳統上稱為 WndProc 的函數來承擔的。

1 .初始化(注冊窗口類,創建窗口)

要定義一個窗口類 struct WNDCLASS WndClass ; 該數據結構實際存儲的是一個窗口的屬性集。 調用 ATOM RegisterClass ( CONST WNDCLASSW * lpWndClass ); 函數注冊 lpWndClass 指向的窗口類模板。窗口類是一個內核對象,不同的窗口類以名稱( WNDCLASS lpszClassName 字段)區分。

例如后面 MFC 中的 AfxRegisterClass 函數中,注冊窗口類前先調用 GetClassInfo 函數檢測預注冊的窗口類是否已注冊。 GetClassInfo 函數用來獲取指定名稱的窗口類信息,其原型如下:

BOOL GetClassInfo ( HINSTANCE hInstance , LPCTSTR lpClassName , LPWNDCLASSW lpWndClass );

以下為 AfxRegisterClass 函數代碼片段:

// WINCORE.CPP

BOOL AFXAPI AfxRegisterClass ( WNDCLASS * lpWndClass )

{

WNDCLASS wndcls ;

if ( GetClassInfo ( lpWndClass -> hInstance , lpWndClass -> lpszClassName , & wndcls ))

{

// class already registered

return TRUE ;

}

if (!:: RegisterClass ( lpWndClass ))

{

TRACE1 ("Can't register window class named %s/n",

lpWndClass -> lpszClassName );

return FALSE ;

}

//……

}

對于一個已注冊的窗口類,可調用 BOOL UnregisterClass ( LPCTSTR lpClassName , HINSTANCE hInstance ); 函數進行注銷。

以下為 Win32SDK 示例程序中的注冊窗口類、創建窗口的代碼片段:

lpszProviderClass = __TEXT( " MyWndClass ") ;

WndClass . lpszClassName = lpszProviderClass ;

然后給定義窗口風格以及用于該窗口類的消息處理函數。然后 CreateWindow lpszProviderClass ,……)將使用名稱為 lpszProviderClass 的窗口類 WndClass 作為模版創建類的實例。

在調用 CreateWindow(Ex) 時,第一個參數也可以直接使用系統預定義( Predefined )的子窗口控件類,例如 "BUTTON" "EDIT" "COMBOBOX" 等這些是系統內部已注冊的 WNDCLASS ,免去調用 RegisterClass

創建窗口后,調用 GetClassName 函數獲取指定窗口 hWnd 所使用的窗口類名稱。其函數原型如下:

int GetClassName ( HWND hWnd , LPTSTR lpClassName , int nMaxCount );

2 .實例化(顯示窗口,刷新窗口)

一旦窗口被創建,還需要完成若干步才能運行你的程序。首先,當一個窗口被創建時,它通常是不可見的,一般要調用 BOOL ShowWindow ( HWND hWnd , int nCmdShow ); 函數 來顯示窗口,調用 BOOL UpdateWindow ( HWND hWnd ); 函數來刷新窗口。

函數 UpdateWindow 向窗口 hWnd 發送第一個 WM_PAINT 消息以更新它的客戶區。當 ShowWindow 使窗口顯示在屏幕上時,窗口的客戶區會被 WndClass . hbrBackground 擦除,調用 UpdateWindow 函數將促使客戶區重繪,以顯示其內容。

3 .消息循環

1 )消息的產生

無論用戶移動鼠標或按下某個鍵, Windows 系統將創建一個消息(對應數據結構為 MSG )并將之投放到對應窗口 (MSG.hwnd 指標 ) 所在線程的消息隊列中。

2 )獲取消息

應用程序調用 GetMessage 函數從調用線程消息隊列中取出 (pop) 消息。

GetMessage 函數原型如下:

BOOL GetMessage ( LPMSG lpMsg, HWND hWnd , UINT wMsgFilterMin, UINT wMsgFilterMax);

取出的消息存放至參數一 lpMsg 所指內存(本地聲明的 MSG 結構體變量)。

參數二 hWnd 標識要檢查消息的窗口,如果為 NULL ,則獲取屬于調用線程消息隊列中任一(窗口)消息;如果不為 NULL ,則只獲取指定窗口的消息。

wMsgFilterMin wMsgFilterMax 指定獲取消息碼的范圍。一般將兩參數都置零,表示無消息 ID 范圍限制。

注意該函數是阻塞的,直到有一個( hWnd 的)消息到來,它才返回。如果消息為 WM_QUIT ,則該函數返回 FALSE ,結束消息循環;否則返回 TRUE ,繼續下一輪消息循環。

<1> 等待消息

函數 BOOL WaitMessage ( VOID ); 使調用線程掛起,直到一個新的消息放到調用線程消息隊列中才返回。

<2> 取出消息

函數 PeekMessage 查看調用線程消息隊列中(指定窗口 hWnd )是否有消息。如果有消息則取出放入 lpMsg 所指 MSG 結構體中,返回 TRUE ;如果無(指定窗口 hWnd 的)消息則立即退出(即非阻塞),返回 FALSE 。其函數原型如下:

BOOL PeekMessage ( LPMSG lpMsg , HWND hWnd , UINT wMsgFilterMin , UINT wMsgFilterMax , UINT wRemoveMsg );

前四個參數同 GetMessage wRemoveMsg 參數指定當有消息讀取消息后,是否從消息隊列中移除該消息。其為下列值之一:

PM_NOREMOVE: 讀取后消息依然留在隊列中;

PM_REMOVE: 讀取后消息從隊列中移除;

<3> GetMessage = WaitMessage + PeekMessage ( PM_REMOVE )

3 )翻譯消息

如果輸入列表中有一個屬于你的應用程序的消息,并且是按鍵消息時, TranslateMessage 將虛擬鍵消息轉換為字符消息( WM_KEYDOWN + WM_KEYUP = WM_CHAR WM_SYSKEYDOWN + WM_SYSKEYUP = WM_SYSCHAR ),再將字符消息( WM_CHAR WM_SYSCHAR )投遞到調用線程的消息隊列中。

TranslateMessage 函數內部機制大致如下:

BOOL TranslateMessage ( CONST MSG * lpMsg )

{

if ( lpMsg -> message == WM_KEYDOWN || lpMsg -> message == WM_SYSKEYDOWN )

{

UINT message ;

if ( lpMsg -> message == WM_KEYDOWN )

{

message = WM_CHAR ;

}

else if ( lpMsg -> message == WM_SYSKEYDOWN )

{

message = WM_SYSCHAR ;

}

PostMessage ( lpMsg -> hwnd , message , lpMsg -> wParam , lpMsg -> lParam );

return TRUE ; // 消息被轉換

}

return FALSE ;

}

4 )路由消息

取出消息后,需要進行處理。應用程序調用 DispatchMessage 函數 將取得的消息發送到窗口消息處理函數 WndProc WndProc 采用 switch-case 分支結構對不同的消息不同的響應處理。

WndProc WNDPROC 函數指針,其類型如下:

typedef LRESULT ( CALLBACK * WNDPROC )( HWND , UINT , WPARAM , LPARAM );

DispatchMessage 函數內部機制大致如下:

LRESULT DispatchMessage ( CONST MSG * lpMsg )

{

// 根據 lpMsg->hwnd 查找用于創建該窗口的 WNDCLASS CreateWindow lpClassName 指定)的 lpfnWndProc;

CallWindowProc ( lpfnWndProc , lpMsg -> hwnd , lpMsg -> message , lpMsg -> wParam , lpMsg -> lParam );

}

4 .消息處理

Windows 編程中常見的消息有:窗口創建消息 WM_CREATE, 窗口繪制消息 WM_PAINT ,按鍵消息 WM_KEYDOWN, WM_CHAR, 窗口關閉消息 WM_CLOSE ,窗口銷毀消息 WM_DESTROY ,退出應用程序消息 WM_QUIT 等。

默認情況下,關閉窗口的處理流程如下:

點擊關閉按鈕 à 系統向指定窗口發送 WM_CLOSE 消息 à WM_CLOSE 消息響應中調用 DestroyWindow 向窗口發送 WM_DESTROY 消息 à WM_DESTROY 消息響應中調用 PostQuitMessage 向窗口發送 WM_QUIT 消息結束窗口所屬線程的消息循環( GetMessage 函數返回), 終止窗口所屬線程。

實際應用軟件在響應關閉消息時通常將窗口最小化(到托盤),并不真正關閉。應用程序將在沒有窗口的條件下繼續運行。

參考 窗口破 過程與Windows 消息循環 WM_CLOSE 、WM_DESTROY 和WM_QUIT 三者的區別

每個 Windows 程序(進程)都至少包含一個窗口和一個應用程序的實例,在程序中表現為窗口句柄 hWnd 和實例句柄 hInstance. 我們可以透過以下幾條程序語句一窺 Windows 程序運行機制:

WndClass.hInstance= hInstance ; // 這一賦值表明要注冊的窗口類屬于當前實例

ShowWindow( hWnd ,nCmdShow); UpdateWindow( hWnd ); // 顯示刷新該程序窗口

GetMessage // 提取消息隊列中的消息

TranslateMessage(& Msg ); // 翻譯消息,該函數負責將消息的虛擬鍵轉換成字符消息

DispatchMessage(& Msg ); // 將參數 lpMSG 標識的消息發送給窗口函數 WndProc

switch( nMessage ) case: // 按接受到的消息值 nMessage 判斷是哪一種消息并處理

以下為 Windows 應用程序執行流程圖:

Windows編程之SDK窗口程序淺析


更多文章、技術交流、商務合作、聯系博主

微信掃碼或搜索:z360901061

微信掃一掃加我為好友

QQ號聯系: 360901061

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。

【本文對您有幫助就好】

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描上面二維碼支持博主2元、5元、10元、自定義金額等您想捐的金額吧,站長會非常 感謝您的哦!!!

發表我的評論
最新評論 總共0條評論
主站蜘蛛池模板: 欧美第一色 | 91欧美| 欧美在线观看视频网站 | 一区二区三区在线免费看 | 国产免费一区视频 | 成人精品国产 | 780pp亚洲情艺中心 | 色呦呦在线 | 久草欧美 | 亚洲天堂视频在线观看免费 | 成人午夜免费视频 | 亚洲欧美一区二区三区情侣bbw | 九九av| 日韩影视在线 | 深夜福利一区二区 | 九九综合九九 | 免费观看成人拍拍拍1000视频 | 久久精品国产欧美成人 | 另类国产ts人妖高潮系列视频 | 久久国产精品99久久小说 | 精品视频免费在线 | www成人国产在线观看网站 | a视频免费 | 久久精品国产精品亚洲综合 | 午夜精品久久久久久99热软件 | 欧美一级久久久久久久大片 | 九九热精品视频在线播放 | 国产色网| 久久综合九色综合欧美播 | 日本一级在线 | 亚洲一二三在线 | 在线视频不卡国产在线视频不卡 | 欧美成人黑人视频免费观看 | 日韩精品av一区二区三区 | 国产福利视频一区 | 夜色4se.bar| 污在线观看| 亚洲午夜一区 | 精品国产一区二区三区久久影院 | 日韩一区二区三区在线 | 女人一级毛片免费视频观看 |