標籤:long esc 資料 api 狀態列 client 符號 bsp 重繪
---恢複內容開始---
一,繪製與重繪
1,windows不會保留視窗內容,當視窗被覆蓋然後恢複時,Windows會發送WM_PAINT訊息通知視窗過程重繪客戶區(視窗中沒有被標題列,功能表列,工具列,狀態列遮住的地方,可以自由繪製),使用函數 GetClientRect(hwnd, &rect);可獲得用戶端區域,儲存在rect結構中。
2,WM_PAINT訊息
調用 UpdateWindow()函數,windows會向視窗過程發送第一條WM_PAINT訊息。
以下情況視窗過程會收到WM_PAINT訊息
*使用者移動一個視窗,導致原來被覆蓋的部分視窗暴露出來。
*使用者調整視窗大小(當視窗類別型設定為CS_HREDRAW和CS_VREDRAW值時)
*程式調用ScrollWindow或ScrollDC函數滾動客戶區。
*程式調用InvalidateRect或InvalidateRgn顯式產生WM_PAINT訊息
當客戶區被臨時遮蓋,Windows會試圖儲存被覆蓋內容,並不是每次都成功。以下情況,Windows可能會發送一條WM_PAINT訊息。
*Windows關閉一個覆蓋部分視窗的對話方塊或訊息框
*下拉式功能表被下拉然後收回
*顯示提示資訊
以下情況下,Windows總會儲存被覆蓋顯示內容,然後在恢複
*滑鼠指標在客戶區移動
*在客戶區拖動圖
3,有效矩形和無效矩形
需要被繪製的地區被稱為“無效地區”或“更新地區”,當客戶區有一個無效地區Windows會在應用程式的訊息佇列中放一條WM_PAINT訊息。
Windows為每個視窗保留一個繪圖資訊結構(儲存無效矩形及其他資訊)無效地區總是最新的,Windows不會在訊息佇列放置多條WM_PAINT訊息
視窗過程可以調用InvalidateRect強制使客戶區的一個矩形失效,如何訊息佇列中已有一條WM_PAINT訊息,windows將會計算出新的無效矩形;如果沒有將會放置一條WM_PAINT訊息。在任何時候,可以使用GetUpdateRect函數擷取座標
視窗程序呼叫BeginPaint函數後,整個客戶區會變得有效,也可以使用ValidateRect,當前訊息佇列中的WM_PAINT會被刪除
二,GDI簡介
1,繪製一個視窗的客戶區需要調用Windows的圖形裝置介面函
用於字串輸出的函數為
TextOut(hdc ,x ,y ,psText , iLength);
hdc為裝置環境介面,x,y確定了字串的左上方,psText為指向字串的指標,iLength是字串的長度
2,控制代碼是一個32位不帶正負號的整數,用來標識唯一的對象,裝置環境(DC)是GDI內部維護的一個資料結構,與特定裝置相關聯。必須在處理同一訊息過程中,擷取和釋放控制代碼。
擷取方法有兩種
第一種 case WM_PAINT:
hdc=BeginPaint(hwnd ,&ps); //BeginPaint函數會使無效地區有效化,以視窗背景擦去無效地區,並填充ps各個欄位
...
EndPaint(hwnd ,&ps);
return 0;
第二種
hdc=GetDC(hwnd);//裁剪矩形為整個客戶區,不會講無效區有效化
....
ReleaseDC(hwnd,hdc);
//GetWindowDC可以得到整個視窗的裝置環境控制代碼
3,繪製資訊結構PAINTSTRUCT
typedef struct tagPAINTSTRUCT{HDC hdc;BOOL fErase;//調用BeginPaint函數後,為TRUE。使用InvalidateRect(hwnd,NULL,TRUE)true時擦出原有背景RECT rcPaint;BOOL fRestore;BOOL fIncUpdate;BYTE rgbReserved[32];} PAINTSTRUCT;
4,TextOut函數詳解
TextOut(hdc ,x ,y ,psText , iLength);
裝置環境決定了文本顏色和文本背景色
字元大小
typedef struct tagTEXTMETRICW{ LONG tmHeight; LONG tmAscent; LONG tmDescent; LONG tmInternalLeading; LONG tmExternalLeading; LONG tmAveCharWidth; LONG tmMaxCharWidth;} TEXTMETRIC;
---恢複內容結束---
windows api 文本輸出(一)