SP:建立Windows應用程式的要點詳解

來源:互聯網
上載者:User

標籤:

主要是對前面幾個部分知識內容的一些總結並進行詳細的分析主函數進入點

在 main.cpp 中需要做得第一件事是包含 Win32 程式所需的標頭檔和定義函數進入點。 需要注意的是, Win32表單應用程式的主函數進入點是 WinMain 函數(控制台程式的進入點是 main 函數)。 對於現在來說,我們只需要在源檔案的頂部包含 windows.h 標頭檔即可。 源檔案 main.cpp 的標頭檔和空的 WinMain 函數見於以下程式:

#include<Windows.h>int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE prevInstance, LPWSTR cmdLine, int cmdShow){return 0;}

使用 wWinMain 代替 WinMain。這兩個主函數的不同在於 wWinMain 的第三個參數cmdLine 使用 Unicode 編碼,而另一個使用 ANSI 編碼將會轉換 Unicode 為 ANSI。 因此將導致 Unicode 字串中的字元丟失,而使用 wWinMain 則允許我們正確處理傳入應用程式的 Unicode 參數。

(w)WinMain 函數有四個參數,其定義如下:
HINSTANCE hInstance: 應用程式當前執行個體的控制代碼(譯者註:瞭解 Win32 的基本知識最好是看 Windows 程式
設計第五版)。
HINSTANCE prevInstance:應用程式的前一個執行個體的控制代碼。 根據 MSDN 的文檔現在此參數將一直是 NULL。雖然此參數一直是 NULL,如果你想要確定該應用程式是否已經有執行個體在運行,文檔推薦使用 CreateMutex函數來建立唯一名字的 mutex(互斥體)。 當已經有執行個體運行時,再次建立 mutex, CreateMutex 函數將會返回 ERROR_ALREADY_EXISTS。
LPSTR cmdLine :(或使用 Unicode 編碼的 LPWSTR):應用程式的命令列由程式外部輸入。允許你傳遞命令給程式,例如通過 cmd 命令終端,或者是通過捷徑提供命令參數,等等。
int cmdShow:視窗被顯示為哪個模式的 識別碼(譯者註:例如最小化,正常,最大化等)。

視窗初始化

儘管上述程式能夠編譯運行,可是由於沒有建立視窗,運行時什麼也沒顯示。 So,下一個步驟就是建立 Win32視窗。 首先要註冊一個視窗類別並且建立視窗本身。 應用程式必須在系統中註冊它的視窗
程式迴圈就是一個無限的迴圈,直到使用者跳出該迴圈為止。 由接受 WM_QUIT 事件(Win32 的退出訊息)來發生結束指令, 假如在主菜單中設定了使用者按下 Esc 鍵產生該事件(當遊戲中時,按下 Esc 鍵並沒有退出,而是暫停,除非是製作者設計了該退出方式),或者你設定它退出的任何其他方式。
MSG 是一個用於持有來自於作業系統中 window 訊息的 Win32 結構,它用於程式響應這些訊息。如果發送一定數量的訊息後程式一直沒有響應,則作業系統將會報告該程式未響應。 通常我們假定它的意思就是程式被凍結或者發生了某些錯誤,這也意味著應用程式沒有從作業系統中恢複過來。 如果程式被設計為響應式的,假設程式已經被凍結即視窗顯示“未響應”訊息或工作管理員顯示該應用未響應,過一會兒它仍然是安全的。我就曾經多次運行十分複雜並且長時間查詢在網路上的微軟 Access。作業系統就報告程式未響應,儘管程式只是忙於做一些任務沒有處理事件而已。
對於 window 訊息,我們需要做兩件事。首先需要取得新的訊息並且處理它們,其次需要調度(響應)這些訊息。PeekMessage 函數取得相關視窗的訊息(我們使用 CreateWindow 函數建立的視窗)。此函數的第一個參數是持有訊息的結構的地址,其次是視窗控制代碼(可選),最小最大訊息過濾標誌,移除標誌。PM_REMOVE 移除標誌,將會將訊息從它的隊列中移除。因為我們處理該訊息,一旦處理後它將不需要留在隊列中。如果有訊息被 PeekMessage 函數獲得,我們調用 TranslateMessage 函數和 DispatchMessage 函數來響應該訊息。Win32 函數 TranslateMessage 將虛擬鍵訊息翻譯為字元訊息,調度函數 DispatchMessage 將訊息傳給視窗過程處理,視窗過程將對於它所接受到的訊息執行實際的行動。如果沒有收到訊息,在程式中就只做更新 Update 和渲染 rendering 這兩件事。例如根據所偵測到的使用者輸入,物理計算,動畫,更新音頻緩衝等的更新操作和渲染情境幾何體。
拿大家熟悉的視頻遊戲舉個例子,查看遊戲迴圈就一目瞭然了。遊戲程式對於每一幀的渲染做一系列的具體事情。遊戲中的幀是遊戲迴圈的單一的反覆過程。大多數遊戲力求達到每秒 30 或 60 幀,換句話說就是相對於真實世界中的每一秒鐘,遊戲做 30 到 60 次的迴圈。當遊戲變得越來越複雜時,這一目標更難達到。 每秒的幀數通常用來衡量遊戲渲染的速度,但是遊戲不僅僅有渲染代碼,還需要每數幀就處理遊戲中的物理,碰撞, AI(人工智慧) 資料流和遊戲的特效。

視窗過程(回呼函數)

在我們能夠編譯和運行我們的程式之前的最後一部分就是所提供的視窗過程,也就是視窗過程函數。視窗過程函數是回呼函數,意味著在我們的程式中當獲得訊息後就調用該函數來處理。回呼函數一般寫成下面的形式:

LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam){switch(message){case WM_DESTROY:PostQuitMessage(0);break;default:return DefWindowProc(hwnd, message, wParam, lParam);}return 0; }

視窗過程函數返回 LRESULT 類型並且有回調 CALLBACK 修飾。 此函數的命名遵循普通函數命名標準該回呼函數接受參數視窗的控制代碼來調度該視窗的訊息,無符號整型訊息代號,兩個可攜帶額外資訊的參數(wParam 和 lParam) 。最後兩個參數用於補充的資料,在回呼函數中處理訊息需要更多的資料時。
退出訊息由調用 Win32 函數 PostQuitMessage 來處理,這將導致在應用程式迴圈中的 MSG 對象取得 WM_QUIT訊息,然後就按照我們的設定結束應用程式迴圈並且退出程式。 假如想退出而又不立即退出的話,只需要發送一個退出訊息即可。 例如,在微軟的 Word 軟體中如果沒有儲存就嘗試退出的話,將會彈出一個對話方塊詢問你是否儲存之後再退出。
回呼函數的最後一部分就是調用 DefWindowProc 函數,它有著與視窗過程函數同樣的參數。 這個函數只被那些我們沒有寫自訂響應代碼的訊息所調用。 在此 Demo 中我們只響應了繪製訊息和退出訊息,但是還有其他大量的可以查到的訊息,如按鍵,滑鼠點擊,滑鼠移動,計時器等等。 DefWindowProc 函數是一個 Win32 函數,它調用預設行為處理所有的訊息,來確保我們響應每一個訊息,即使我們對那些訊息不感興趣。

SP:建立Windows應用程式的要點詳解

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.