這兩天看了孫鑫VC教學視頻的第一集:WinDows程式內部運行原理。將所學內容整理成筆記以備將來之需,其文如下:
1. 關於電腦系統,:
電腦系統大致分為三層:應用程式,作業系統,硬體裝置。應用程式通過叫用作業系統提供的API來通知作業系統完成對底層硬體裝置的操作;相反,作業系統會將硬體裝置的感知封裝為訊息傳遞到訊息佇列,然後由應用程式從訊息佇列中取走,並做出對訊息的具體響應。
2. 新名詞解釋。
控制代碼:即資源的標識,作業系統將通過控制代碼來尋找對應的資源。標控制代碼(HICON),游標控制代碼(HCURSOR),視窗控制代碼(HWND),應用程式執行個體控制代碼(HINSTANCE)
視窗類別的一些變數:變數的每一位置1則表示具備對應的那種特性,反之則無。變數中具體位代表的意義難以記憶,所以通過宏來進行代替,如CS_VREDRAW=0x0001,CS_HREDRAW=0x0002。如果想使該變數同時具有幾種特性,則可以將這幾種特性對應的宏進行OR(|)運算,若要從該變數中去掉每一特性,則將對應的宏取反之後再與該變數進行&運算。舉例:style=CS_VREDRAW | CS_HREDRAW | CS_NOCLOSE,表示變數同時設定了以上三種對應的特性。
回呼函數:當應用程式收到訊息時,需要調用一個函數進行訊息處理,函數調用的過程只由作業系統完成,而回呼函數的處理方法的代碼需要應用程式完成。每一種不同類型的視窗都有自己專用的回呼函數,該函數是通過lpfWnsProc成員指定。
3. 第一個WinDows程式。
建立一個完整的視窗程序的四個步驟:
- 設計一個視窗類別:填充WNDCLASS類
- 註冊視窗類別:RegisterClass函數
ATOM RegisterClass( CONST WNDCLASS *lpWndClass // class data);
- 建立視窗:CreateWindow函數
HWND CreateWindow( LPCTSTR lpClassName, // registered class name LPCTSTR lpWindowName, // window name DWORD dwStyle, // window style int x, // horizontal position of window int y, // vertical position of window int nWidth, // window width int nHeight, // window height HWND hWndParent, // handle to parent or owner window HMENU hMenu, // menu handle or child identifier HINSTANCE hInstance, // handle to application instance LPVOID lpParam // window-creation data);
- 顯示並更新視窗:ShowWindow和UpWindow函數,具體聲明查詢MSDN
除此之外,還有兩個重要的過程,即通過while迴圈來擷取各種訊息以及編寫回呼函數對不同訊息的處理方法。具體編寫代碼所示:
#include <windows.h>#include <stdio.h>LRESULT CALLBACK WinWanProc( HWND hwnd, // handle to window UINT uMsg, // message identifier WPARAM wParam, // first message parameter LPARAM lParam // second message parameter);int WINAPI WinMain( HINSTANCE hInstance, // handle to current instance HINSTANCE hPrevInstance, // handle to previous instance LPSTR lpCmdLine, // command line int nCmdShow // show state){//1.設計一個視窗類別WNDCLASS wndcls;wndcls.cbClsExtra = 0;wndcls.cbWndExtra = 0;wndcls.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH);wndcls.hCursor = LoadCursor(NULL, IDC_CROSS);wndcls.hIcon = LoadIcon(NULL, IDI_ERROR);wndcls.hInstance = hInstance;wndcls.lpfnWndProc = WinWanProc;wndcls.lpszClassName = "myfirst";wndcls.lpszMenuName = NULL;wndcls.style = CS_HREDRAW | CS_VREDRAW;//2.註冊視窗類別RegisterClass(&wndcls);//3.建立視窗類別HWND hwnd;hwnd = CreateWindow("myfirst","windows",WS_OVERLAPPEDWINDOW,0,0,600,400,NULL,NULL,hInstance,NULL);//4.顯示和更新視窗ShowWindow(hwnd,SW_SHOWNORMAL);UpdateWindow(hwnd);//擷取訊息MSG msg;while (GetMessage(&msg,NULL,0,0))//從訊息佇列擷取訊息,若有訊息則一直返回TRUE{TranslateMessage(&msg); //將訊息對WM_KEYUP和WM_KEYDOWN轉換成WM_CHAR訊息DispatchMessage(&msg);//將訊息路由給作業系統,由作業系統調用視窗回呼函數}return 0;}//5.回呼函數,對不同的訊息完成不同的響應LRESULT CALLBACK WinWanProc(HWND hwnd, // handle to windowUINT uMsg, // message identifierWPARAM wParam, // first message parameterLPARAM lParam // second message parameter){switch(uMsg){case WM_CHAR:char str[20];sprintf(str,"the key_char is %d",wParam);MessageBox(hwnd,str,"wang",MB_OK);break;case WM_LBUTTONDOWN:MessageBox(hwnd,"mouse clicked!","wang",MB_YESNO);HDC hdc; //裝置上下文,可以屏蔽裝置驅動程式,方便應用程式的調用hdc = GetDC(hwnd);TextOut(hdc,0,50,"yes i do!", strlen("yes i do!"));ReleaseDC(hwnd,hdc);break;case WM_PAINT:HDC hDC;PAINTSTRUCT ps;hDC = BeginPaint(hwnd,&ps);TextOut(hDC,0,0,"paint message!",strlen("paint message!"));EndPaint(hwnd,&ps);break;case WM_CLOSE:if(IDYES==MessageBox(hwnd,"是否要推出程式?","wang",MB_YESNO)){DestroyWindow(hwnd);}break;case WM_DESTROY:PostQuitMessage(0);break;default:return DefWindowProc(hwnd,uMsg,wParam,lParam);}return 0;}孫鑫老師的視頻講的深入淺出,我決定將好好學習VC編程,感謝老師提供這麼好的資源,強者自強!