上學期學習了Java ,感覺Java寫一個視窗真心簡單,很易上手,也就難怪很多開發人員選擇Java作為自己的開發程式語言。但是由於自身對windows的熱愛,讓我覺得c、c++語言才是我親睞的程式語言,雖然難度大些,但是這才能體現能力所在。其實之前一直想自學一下win32,但是由於時間的顯示和種種原因而耽擱了,於是今年暑假決心深入學習win32。
在學習過程中呢,我會在此留下自己的學習心得,當做自己的筆記。初學者可以借鑑,高手可以多多指教,呵呵……
好了,今天開始做第一課的筆記吧:
學習Win32最好是對windows作業系統有較為深入的理解,這樣才能學得深入、紮實。因此學習Win32的第一步就是了解windows
作業系統的訊息機制,這個可是重中之重
首先上一張自己親手繪製的圖,能很清晰地表示windows訊息機制的工作原理
也許你初次看到這張圖,感覺密密麻麻的,不是很懂,別擔心,我將逐步講解:
(1) 數字1箭頭: 表示windows(os)將訊息傳遞到應用程式的訊息佇列中
(2) 數字2箭頭: 表示應用程式通過訊息迴圈在訊息佇列中讀取訊息
(3) 數字3箭頭: 表示應用程式的訊息迴圈將讀取到的訊息告訴給windows(os)
(4) 數字4箭頭: 表示windows(os)通過應用程式傳遞的訊息來呼叫應用程式繫結的回撥函式(WndProc) , 根據回撥函式 , 來確定是否做出響應
到這裡,想必你能從本質上了解到windows的訊息機制了吧
講程式終究和程式碼脫不了關係,下面我借用一下P先生(Charles Petzold)的第一個例子(HelloWin.c),不過裡面包含了我自己的東西,你一看就知道了:
- //windows程式的基礎程式碼
- #include<windows.h>
- LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);//回撥函式宣告
- int WINAPI WinMain(HINSTANCE hInstance, // 程式的當前例項控制程式碼
- HINSTANCE hPrevInstance, // 程式的上一個例項控制程式碼 , 在win32程式中 , 它始終是NULL
- PSTR szCmdLine, // 命令列
- int iCmdShow) // 視窗顯示狀態
- {
- static TCHAR szAppName[] = TEXT("HelloWin"); //以'\0'字元結尾的字串 , 這裡是程式的名稱(實際用作後面的視窗類的名字)
- HWND hwnd; //視窗控制程式碼
- MSG msg; //訊息結構體
- WNDCLASS wndclass; //視窗類
- wndclass.style = CS_HREDRAW | CS_VREDRAW; //視窗類的風格
- wndclass.lpfnWndProc = WndProc; //視窗類繫結的回撥函式(也稱為視窗過程)
- wndclass.cbClsExtra = 0; //視窗類額外引數(預設為0)
- wndclass.cbWndExtra = 0;//視窗類額外引數(預設為0)
- wndclass.hInstance = hInstance; //程式的當前例項控制程式碼 , 繫結到視窗類中
- wndclass.hIcon = LoadIcon(NULL, IDI_APPLICATION); //載入程式圖示
- wndclass.hCursor = LoadCursor(NULL, IDC_ARROW); //載入游標
- wndclass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH); //背景刷
- wndclass.lpszMenuName = NULL; //選單名指標
- wndclass.lpszClassName = szAppName; //視窗類的名字
- if(!RegisterClass(&wndclass))//註冊視窗類
- {
- MessageBox(NULL, TEXT("This program requires Windows NT!"),
- szAppName, MB_ICONERROR);
- return 0;
- }
- //這裡建立的是一段記憶體 , 用於儲存建立視窗的資訊 , 同時返回該視窗的一個控制程式碼(視窗的標示)
- hwnd = CreateWindow(szAppName, //視窗類的名字
- TEXT("The Hello Program"), //視窗名稱(標題欄顯示的內容)
- WS_OVERLAPPEDWINDOW, //視窗的風格
- CW_USEDEFAULT, //視窗x座標
- CW_USEDEFAULT, //視窗y座標
- CW_USEDEFAULT, //視窗寬度
- CW_USEDEFAULT, //視窗長度
- NULL, //父視窗控制程式碼
- NULL, //選單控制程式碼
- hInstance, //程式的當前例項
- NULL); //視窗建立資料
- /* 程式執行完CreateWindow , 還沒執行ShowWindow時 ,
- windows向視窗的WndProc傳送了第一條訊息: WM_Create */
- ShowWindow(hwnd, iCmdShow); //顯示視窗
- UpdateWindow(hwnd); //更新視窗
- /* 執行完UpdateWindow後 , windows向視窗的WndProc
- 傳送了第二條訊息: WM_PAINT . 如果ShowWindow沒有呼叫或是呼叫失敗 , WM_PAINT訊息是不會傳送的*/
- //訊息迴圈
- while(GetMessage(&msg, NULL, 0, 0))//這裡的NULL不能寫成hwnd , 否則程式不能正常執行
- {
- TranslateMessage(&msg);//轉換鍵盤訊息
- DispatchMessage(&msg);//將訊息傳送給windows(os) , 由windows來回撥
- }
- return msg.wParam;//結束返回
- }
- //視窗過程(回撥函式)
- LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
- {
- HDC hdc; //裝置控制程式碼
- PAINTSTRUCT ps; //包含視窗客戶區繪製的資訊 是一個結構體
- RECT rect; //矩形(兩個點)
- //這裡是訊息處理
- switch(message)
- {
- //視窗建立訊息
- case WM_CREATE:
- //PlaySound (TEXT ("hellowin.wav"), NULL, SND_FILENAME | SND_ASYNC) ;//播音
- return 0 ;
- //視窗客戶區重繪訊息
- case WM_PAINT:
- PlaySound (TEXT ("hellowin.wav"), NULL, SND_FILENAME | SND_ASYNC) ;//播音
- hdc = BeginPaint(hwnd, &ps);//獲取裝置控制程式碼 , 開始重繪
- GetClientRect(hwnd, &rect);//獲取客戶區的大小
- DrawText(hdc, TEXT("Hello, Windows 98!"), -1, &rect,
- DT_SINGLELINE | DT_CENTER | DT_VCENTER);//繪製一個字串
- EndPaint(hwnd, &ps);//結束重繪
- return 0;
- //視窗退出訊息
- case WM_DESTROY:
- PostQuitMessage(0);//傳送退出訊息
- return 0;
- }
- return DefWindowProc(hwnd, message, wParam, lParam);
- //windows對於訊息的預設處理
- //(注意: 第三個和第四個引數不能傳遞錯誤!!!)
- }
沒錯,我逐行註釋了,這樣我覺得很好,對於掌握和理解是很有幫助的,ni不放試試……
好了,今天到此為止吧,下次繼續了^_^