天天看點

BeginPaint和EndPaint函數用法

當人們使用軟體時,大多數是想看到自己所需要的結果,比如玩 RPG 遊戲,就是想看到自己所操作的主角做各種各樣的事情。在 2D 的 RPG 遊戲裡,其實做的事情,就是不斷地更新畫面,也就是不斷地顯示 BMP 的圖檔。在普通的程式裡,大多也是顯示各種文本和圖檔的,但是有一種類型的應用程式是不怎麼顯示結果的,那就是服務程式。不管怎麼樣,隻要我們想看到程式所執行後的結果,就需要在程式裡顯示出來。也就是需要調用 BeginPaint 和 EndPaint 函數。 BeginPaint 函數的作用是告訴 Windows 系統,要開始向顯示卡輸出内容了,把這次顯示的操作請求放到系統顯示隊列裡。由于系統上的顯示卡往往隻有一個,那麼這種資源是獨占的,是以作業系統會讓顯示操作線性化,保證每個視窗的顯示是獨立進行的,而不是 A 視窗顯示一部份,或者 B 視窗顯示一部份,而是 A 視窗顯示完成後再讓 B 視窗顯示。是以, BeginPaint 函數就是跟作業系統說,我需要顯示了,你安排好吧。當 BeginPaint 傳回時,就擷取到系統的顯示資源句柄,這樣就可以調 GDI 一大堆函數來操作了。顯示完成後,一定要記得調用函數 EndPaint ,因為使用 BeginPaint 函數請求了獨占的顯示資源後,如果不釋放回去,就會讓其它程式永遠擷取不到顯示資源了,這樣系統就死鎖了。如果你有空仔細地檢視一下 Windows 源程式,就會發現 BeginPaint 函數和 EndPaint 函數怎樣構成的。比如在調用 BeginPaint 函數時先把光标隐藏起來,接着再顯示使用者顯示的東西,最後調用 EndPaint 函數後,又把隐藏的光标顯示出來。   函數 BeginPaint 函數和 EndPaint 函數聲明如下: WINUSERAPI HDC WINAPI BeginPaint(     __in HWND hWnd,     __out LPPAINTSTRUCT lpPaint);   WINUSERAPI BOOL WINAPI EndPaint(     __in HWND hWnd,     __in CONST PAINTSTRUCT *lpPaint); hWnd 是視窗句柄。 lpPaint 是擷取顯示參數。它的結構定義如下: typedef struct tagPAINTSTRUCT {  HDC hdc;  BOOL fErase;  RECT rcPaint;  BOOL fRestore;  BOOL fIncUpdate;  BYTE rgbReserved[32]; } PAINTSTRUCT, *PPAINTSTRUCT; hdc 是擷取裝置句柄。 fErase 是否擦新背景。 rcPaint 是顯示的視窗大小。 fRestore 、 fIncUpdate 、 rgbReserved 是保留使用的參數。   BeginPaint 函數的傳回值也是顯示裝置的句柄。   調用這個函數的例子如下:

 LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)  {   int wmId, wmEvent;   PAINTSTRUCT ps;   HDC hdc;     switch (message)  {   case WM_COMMAND:          wmId    = LOWORD(wParam);          wmEvent = HIWORD(wParam);          // 菜單選項指令響應 :          switch (wmId)          {          case IDM_ABOUT:                DialogBox(hInst, MAKEINTRESOURCE(IDD_ABOUTBOX), hWnd, About);                break;          case IDM_EXIT:                DestroyWindow(hWnd);                break;          default:                return DefWindowProc(hWnd, message, wParam, lParam);          }          break;   case WM_PAINT:         hdc = BeginPaint(hWnd, &ps);         //          EndPaint(hWnd, &ps);          break;   case WM_DESTROY:          PostQuitMessage(0);          break;   default:          return DefWindowProc(hWnd, message, wParam, lParam); }   return 0;  }

繼續閱讀