/************************************************************************//* Win32程式設計基礎 *//************************************************************************//************************************************************************//* Win32程式的注釋,雖然很簡單,但是這是Win32程式設計的起步,所以詳細些
*//************************************************************************//************************************************************************//* 匯入包含檔案WINDOWS.H,此檔案包含了其它的Windows標頭檔 *//* WINDEF.H 基本類型定義 *//* WINNT.H 支援Unicode的類型定義 *//* WINBASE.H 核心功能
*//* WINUSER.H 使用者介面函數 *//* WINGDI.H 圖形裝置介面函數 *//************************************************************************/#include /************************************************************************//* 視窗對象的過程處理函數 *//* LRESULT: 簡單定義為LONG(long) *//* CALLBACK:__stdcall,指在Windows本身和使用者的應用程式之間發生的函數調
*//* 用的特殊調用序列。 *//* HWND: 視窗控制代碼,32位元字,該參數為接受訊息的視窗的控制代碼, *//* CreateWindow函數的傳回值。 *//* UINT: unsigned int 無符號整型32位, *//* 該參數為MSG結構中的message域相同,表示該訊息的數字 *//* WPARAM: UINT,32位訊息參數 *//* LPARAM: LONG,32位訊息參數 *//************************************************************************/LRESULT
CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);/************************************************************************//* Windows應用程式的主函數,有四個參數,名稱固定為WinMain,傳回值為int *//* WINAPI 在WINDEF.H中定義,#define WINAPI __stdcall *//* HINSTANCE:執行個體控制代碼,數字 *//* 在32位系統中WinMain的第二個參數總為NULL(定義為0)
*//* 第三個參數用於運行程式的命令列, *//* 某些Windows應用程式使用這個參數在程式啟動時將檔案載入到記憶體 *//* LPSTR/PSTR:指向字串的指標,相當於 char * *//* 第四個參數指出程式最初顯示的方式,正常,最大化,最小化等。 *//************************************************************************/int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE,
PSTR lpszCmdLine, int iCmdShow){ /************************************************************************/ /* 定義視窗類別 */ /* TCHAR:char */ /* _T和TEXT宏,功能一致,通常沒用,在Unicode系統中, */ /* 自動把後面的字串轉換為寬字元串 */ /************************************************************************/
TCHAR tcClassName[] = TEXT("My Window"); //視窗類別名字串 /************************************************************************/ /* WNDCLASS:視窗類別結構,定義了視窗的一般特性,可以建立不同的視窗 */ /* typedef struct */ /* { */ /* UINT style ; */ /* WNDPROC lpfnWndProc ; */ /* int cbClsExtra
; */ /* int cbWndExtra ; */ /* HINSTANCE hInstance ; */ /* HICON hIcon ; */ /* HCURSOR hCursor ; */ /* HBRUSH hbrBackground ; */ /* LPCTSTR lpszMenuName ; */ /* LPCTSTR lpszClassName ; */ /* } */ /* WNDCLASS, * PWNDCLASS ; */ /************************************************************************/
WNDCLASS wc; //視窗類別屬性描述結構 wc.lpszClassName = tcClassName; //視窗類別名 wc.lpszMenuName = NULL; //視窗類別菜單資源名 wc.lpfnWndProc = WndProc; //視窗對象的過程處理函數,指向函數的指標 wc.hInstance = hInstance; //當前進程物件控點,接收於WinMain參數 wc.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH); //視窗背景刷子物件
wc.hIcon = LoadIcon(NULL, IDI_APPLICATION); //表徵圖對象 wc.hCursor = LoadCursor(NULL, IDC_ARROW); //游標對象 wc.cbClsExtra = 0; //同類視窗對象公用資料區大小 wc.cbWndExtra = 0; //當前視窗對象私人資料區大小 wc.style = CS_HREDRAW | CS_VREDRAW; //視窗類別風格,水平或垂直尺寸改變後重新整理 if (!RegisterClass(&wc)) //註冊視窗類別,參數為指向WNDCLASS結構的指標
{ /************************************************************************/ /* 視窗類別註冊不成功的錯誤資訊 */ /* MessageBox 訊息框 */ /* 參數一:視窗控制代碼,如果沒有則為NULL */ /* 參數二:訊息框主體顯示的字串 */ /* 參數三:訊息框標題列上的字串 */ /* 參數四:winuser.h中定義的MB_開始的常數組合,訊息框風格:按鈕,表徵圖 */ /* 為0,則只有ok按鈕 */ /* 傳回值:返回IDOK(1)。
*/ /* 還可以返回IDYES、IDNO、IDCANCEL、IDABORT、IDRETRY、IDIGNORE等 */ /************************************************************************/ MessageBox(NULL, TEXT("RegisterClassError!"), TEXT("Error"), MB_ICONERROR); return 0; //如果註冊失敗,返回並終止程式 } /************************************************************************/
/* 定義視窗對象屬性,指定有關視窗的更詳細資料 */ /************************************************************************/ TCHAR tcWindowCaptionName[] = TEXT("Win32 API"); //視窗對象標題名稱 CREATESTRUCT cs; //視窗對象屬性描述結構,定義在WINUSER.H cs.lpszClass = tcClassName; //視窗類別名 cs.lpszName = tcWindowCaptionName;
//視窗對象標題名稱,顯示在標題列 cs.style = WS_OVERLAPPEDWINDOW; //視窗對象風格 cs.x = 100; //視窗對象在螢幕上的x座標 cs.y = 100; //視窗對象在螢幕上的y座標 cs.cx = 400; //視窗對象的寬度 cs.cy = 300; //視窗對象的高度 cs.hwndParent = NULL; //視窗對象的父視窗控制代碼 cs.hMenu = NULL; //視窗對象的菜單控制代碼或子視窗編號 cs.hInstance = hInstance; //當前進程的執行個體控制代碼,WinMain參數
cs.lpCreateParams = NULL; //建立參數指標,可以訪問以後想要引用的程式中的資料 /************************************************************************/ /* 建立視窗對象 */ /* 定義視窗控制代碼hWnd,值為CreateWindows函數的傳回值。 */ /* 即建立成功返回視窗的控制代碼,否則返回NULL */ /************************************************************************/
HWND hWnd = CreateWindow( cs.lpszClass, cs.lpszName, cs.style, cs.x, cs.y, cs.cx, cs.cy, cs.hwndParent, cs.hMenu, cs.hInstance, cs.lpCreateParams); if (hWnd == NULL) //判斷建立是否成功 { /************************************************************************/ /*
視窗對象建立不成功的錯誤提示 */ /************************************************************************/ MessageBox(NULL, TEXT("CreateWindowError!"), TEXT("Error!"),MB_ICONERROR); return 0; } /************************************************************************/ /*
顯示視窗對象 */ /* 此時Windows內部已經建立了這個視窗。已經分配記憶體。 */ /* 但是要顯示在顯示器上還需要調用兩個函數。 */ /* ShowWindows(hwnd,iCmdShow) */ /* 第一個參數是剛剛用CreateWindow建立的視窗的控制代碼。 */ /* 第二個參數是傳給WinMain的iCmdShow。用來確定最初如何在螢幕上顯示視窗。*/ /* 也可以自訂選擇以選項: */ /* SW_SHOWNORMAL //常規 */ /* SW_SHOWMAXIMIZED //最大化
*/ /* SW_SHOWMINNOACTIVE //只顯示在工作列 */ /* UpdateWindow(hWnd) */ /* 導致用戶端區域被繪製。通過給視窗過程(Wndproc)發送一個WM_PAINT訊息實現 */ /************************************************************************/ ShowWindow(hWnd, iCmdShow); UpdateWindow(hWnd);//立即重新整理視窗對象 /************************************************************************/
/* 訊息檢索,訊息迴圈 */ /* MSG:訊息結構,被定義在WINUSER.H */ /* 訊息迴圈以GetMessage調用開始,它從訊息佇列中取出一個訊息 */ /* 這一調用傳遞給Windows一個指向msg的MSG結構指標。 */ /* 第二、三、四個參數為NULL或者0表示程式接收自己建立的所有視窗的所有訊息*/ /* Windows用從訊息佇列中取出的下一個訊息填充msg結構的各個域 */ /* MSG:訊息結構: */ /* typedef struct tagMSG */ /* { */
/* HWND hwnd ; //訊息發向的視窗的控制代碼。 */ /* UINT message ; //訊息標識符,一個數值,定義在Window標頭檔中 */ /* WPARAM wParam ; //一個32位的訊息參數,含義根據訊息不同而不同 */ /* LPARAM lParam ; //同上 */ /* DWORD time ; //訊息放入訊息佇列時的時間 */ /* POINT pt ; //訊息放入訊息佇列時的滑鼠座標 */ /* } */ /* MSG, * PMSG ; //結構名 */
/************************************************************************/ MSG msg; while (GetMessage(&msg, NULL, 0, 0)) { /************************************************************************/ /* 檢索訊息;當檢索到WM_QUIT(其值為0x0012)訊息時,從訊息迴圈中退出 */ /************************************************************************/
TranslateMessage(&msg);//將msg結構傳遞給Windows,進行虛擬鍵盤訊息的轉換 DispatchMessage(&msg); //發送訊息,由此作業系統調用相應的視窗過程處理訊息 } /************************************************************************/ /* 主視窗返回 */ /************************************************************************/
return msg.wParam;}/************************************************************************//* 視窗對象的過程處理函數 *//* 四個參數與MSG結構中的前四個參數相同。 *//* 程式通常不直接調用視窗過程,由Windows本身調用。 *//* 程式可以通過SendMessage函數調用自己的視窗過程 *//************************************************************************/LRESULT
CALLBACK WndProc(HWND hWnd, UINT iMsg, WPARAM wParam, LPARAM lParam){ /************************************************************************/ /* 對訊息進行分類處理 */ /* WINUSER.H為每個訊息定義以WM為首碼的標識符 */ /*一般Windows程式元用switch和case結構來處理,此時必須返回0。 */ /*視窗過程不處理的其它訊息必須傳遞給DefWindowProc函數,
*/ /*視窗過程返回該函數傳回值 */ /************************************************************************/ switch (iMsg) { /************************************************************************/ /* 客戶區的繪製訊息,視窗用戶端區域無效時重新整理 */ /************************************************************************/
case WM_PAINT: { /************************************************************************/ /* PAINTSTRUCT:繪圖結構,定義在WINUSER.H中 */ /* RECT:矩形結構 */ /* HDC:裝置描述表控制代碼 */ /************************************************************************/ PAINTSTRUCT ps; HDC
hDC; RECT rect; /************************************************************************/ /* 對於WM_PAINT的處理幾乎總是從一個BeginPaint函數開始的: */ /* hDC = BeginPaint(hWnd, &ps) */ /* 而已一個EndPaint函數結束 */ /* EndPaint(hWnd, &ps) */ /* 兩個調用中第一個參數是程式的視窗控制代碼, */ /* 第二個參數是指向類型為PAINTSTRUCT的結構指標
*/ /************************************************************************/ hDC = BeginPaint(hWnd, &ps); //擷取顯示裝置對象及繪製描述屬性 GetClientRect(hWnd, &rect); //擷取當前視窗對象客戶區矩形 SetBkMode(hDC,TRANSPARENT); //設定背景方式 SetTextColor(hDC, RGB(255, 0, 0)); //設定文本顏色 /************************************************************************/
/* 繪製文本 */ /* DrawText函數,第一個參數是從BeginPaint返回的裝置描述表控制代碼 */ /* 第二個參數是要輸出的文本 */ /* 第三個參數是-1,表示文本串是以位元組0終結的。 */ /* 第四個參數要繪製的矩形地區 */ /* 最後一個參數是系列標誌位,定義在WINDUSER.H中,水平、垂直中央,單行 */ /************************************************************************/ DrawText(hDC,
TEXT("Hello, Win32!"), -1, &rect, DT_CENTER | DT_VCENTER | DT_SINGLELINE); EndPaint(hWnd, &ps); //客戶區繪製結束,歸還顯示裝置對象 return 0; } case WM_DESTROY: //接收到WM_DEFTROY訊息 { /************************************************************************/ /* 發送WM_QUIT訊息,通知線程訊息檢索迴圈,清除視窗主程式可以退出
*/ /* PostQuitMessage(0)函數在訊息佇列裡插入一個WM_QUIT訊息 */ /************************************************************************/ PostQuitMessage(0); return 0; } } /************************************************************************/ /* 程式末處理的訊息交給window系統的預設視窗對象的過程處理函數處理
*/ /************************************************************************/ return DefWindowProc(hWnd, iMsg, wParam,lParam);}