Windows程式設計零基礎自學_3_Windows程式的顯示和更新_之擷取裝置內容控制代碼_非WM_PAINT訊息期間繪製顯示地區

來源:互聯網
上載者:User

      前面看了幾天的書,發現那本書太厚了1600多頁,是我認真看過的最厚的書,看著就累,我不知道作者和翻譯是怎麼堅持下來的,這麼多的文字就那麼寫完了;由於有工作要做,並且與電腦的聯絡不大,自學的時候感到很累,所以學習進度有點慢..........不過這個是我的興趣,學起來雖然感覺累,但也樂在其中...嘿嘿

      上次說到了windows程式顯示和更新視窗的WM_PAINT訊息的處理機制,這次接著上次沒有說完的話題繼續瞎扯........

非WM_PAINT訊息期間繪製顯示地區

    在應用程式編製過程中,有時不需要繪製顯示地區,而只想獲得一些裝置內容的資訊;或者我們想在非WM_PAINT訊息處理期間繪
    制顯示地區的某個地區,這時我們就需要採用另外一種方法了。我們通過下面的方式進行處理:
    1、擷取裝置內容控制代碼和釋放裝置內容控制代碼:
       我們可以通過下面兩個API函數來擷取裝置內容控制代碼和釋放裝置內容控制代碼:
       擷取裝置內容控制代碼: GetDC
       原型: 
                 HDC GetDC(HWND);
       釋放裝置內容控制代碼:  ReleaseDC
       原型:
                int ReleaseDC(HWMD ,HDC )
      2、Tip:
        這裡和BeginPaint和EndPaint一樣, GetDC和ReleaseDC函數必須成對的使用,若在某個訊息處理的時使用呼叫GetDC則
      必須在同一個訊息處理期間呼叫ReleaseDC函數。
        不能在處理A訊息時呼叫GetDC,而在處理B訊息時呼叫ReleaseDC。
      3、與BeginPaint的比較
           GetDC同樣可以擷取裝置內容控制代碼,但是與BeginPaint不一樣的是:GetDC不會使任何無效地區變為有效;
       這個可以理解:
          我們知道當產生無效地區的時候,系統會記錄無效地區的形態同時發送一個WM_PAINT訊息,同時在呼叫
       BeginPaint函數時會清除WM_PAINT訊息,而GetDC函數不會清除WM_PAINT, 我們知道只要有WM_PAINT訊息, 
       則會存在無效地區。
          GetDC返回的裝置內容控制代碼具有一個剪取矩形,它等於整個顯示地區,這樣就可以在顯示地區的某一部分繪製
       而不僅僅是在無效矩形上繪製。
       4、如何不調用BeginPaint函數而是整個地區有效,可以呼叫:
             ValideteRect(hwnd,NULL);
           這樣就可以清除系統投遞到訊息佇列的WM_PAINT訊息。
       5、使用GetDC和ReleaseDC
          可以呼叫GetDC和ReleaseDC來對鍵盤訊息和滑鼠訊息作出響應, 這樣就可以通過滑鼠或者鍵盤輸入來更新顯
       示地區,而不需要等到視窗出現無效地區在對視窗進行繪製。
       6、GetDC與GetWindowDC
          GetDC返回一個用於在顯示地區進行繪製的裝置內容控制代碼,而GetWindow函數返回一個用於在整個視窗進行繪製的
       裝置內容控制代碼。
          程式同樣應該處理 WM_NCPAINT 非顯示地區繪製訊息。
 
    視窗繪製的步驟:
         1、擷取要被繪製視窗的裝置內容控制代碼
         2、調用GDI進行視窗繪製
         3、釋放裝置內容控制代碼。

4.5 TextOut函數
     TextOut函數用於顯示文字;其文法是:
     TextOut(hdc, x, y, psText,iLength);
     參數:
     hdc:  裝置內容控制代碼,可以是GetDC和BeginPaint函數返回的控制代碼
               裝置內容的屬性控制被顯示的字串的特徵
     在裝置內容中有一個屬性指定文字的顏色,預設的顏色為黑色,預設裝置內容還定義了白色的字元輸出背景,在
     用TextOut函數輸出文字時,就按照這個預設的裝置內容屬性進行文字的輸出顯示。
     改文字背景色與視窗類別別定義時裝置的背景不相同,視窗類別別中的背景是一個畫刷,被windows用來擦除顯示地區,不是裝置
     內容的一部分。通常為了使windows擦除的視窗顯示地區的背景畫刷與預設文字背景顏色相同,會將wndclass.hbrBackground
     畫刷設定成白色畫刷WHITE_BRUSH.

     psText: 待顯示的字串, 字串中不能包括ASCII控制字元(如換行、斷行符號、製表和退格),windows會將這些顯示為實心塊。

     x,y: x和y是字元顯示時的開始座標位置。x是水平位置,方向向右值增加; y是垂直位置,向下方向值增加。(0,0)是應用程式
     顯示地區的左上方。這個座標系成為邏輯座標系。在Windows內部有多種座標映像方式,這些座標映像方式將控制GDI函數指定的邏輯
     位置轉換為實際圖素座標的顯示座標。在裝置內容定義,預設方式是MM_TEXT, 其單位與實際單位相同,都是圖素。

     裝置內容定義了一個剪裁地區, GetDC擷取的裝置內容控制代碼為整個顯示地區;而BeginPaint取得的裝置內容控制代碼為無效地區。windows
     不會在剪裁地區之外的任何位置繪製字串。
     
     系統字型:
         裝置內容定義了TextOut顯示文字時windows使用的字型, 預設字型為系統字型,或用windows表標頭檔中的標識符SYSTEM_FONT,
     系統字型是windows用在標題列、菜單和對話方塊中顯示字串的預設字型。
    
      字元大小
         windows顯示器的圖素最小是640*480。 可以通過呼叫系統函數來擷取各種資訊。
        1、 GetSystemMetrics函數取得使用者介面上各類視覺組件大小的資訊,
        2、 GetTextMetrics取得字型的大小,GetTextMetrics返回裝置內容中當前選擇的字型的資訊,
            因此GetTextMetrics函數需要操作裝置內容控制代碼, 調用這個函數時windows將文字大小不同的值賦值
            到TEXTMETRICS結構體中。
            TEXTMETRICS結構體共有20個欄位,通常我們需要操作的是前面的幾個欄位
           
            typedef struct tagTEXTMETRIC
               {
                    LONG  tmHeght;  //tmHeight=tmAscent+tmDescent 表示了在基準線下字元的最大高度
                    LONG  tmAscent;
                    LONG  tmDescent;
                    LONG  tmInternalLeading;
                    LONG  tmExternalLeading;
                    LONG  tmAveCharWidth;
                    LONG  tmMaxCharWidth;
                    其他欄位;
                }TEXTMETRIC, *PTEXTMETRIC;
              leading:即間距指印表機在兩行文字間插入的空間,在TEXTMETRIC結構中,內部間距包括在tmAscent中,並且通常
             是重音符號出現的地方。tmInternalLeading欄位可以設定成0,這時重音符的字母會稍稍縮短以列印重音符號。
             TEXTMETRICS結構包含有描述字元寬度的兩個欄位:
                  tmAveCharWidth: 小寫字母加權平均寬度
                  tmMaxCharWidth: 字型中最寬字元的寬度
                  這裡要說明的是: windows使用的是非等寬的字型, 例如 W就比i寬。
             大寫字母的平均寬度: 大約可以用tmAveCharWidth * 150 % 計算。
             上面的欄位值的單位取決於選定的裝置內容映像方式,在預設的情況下,映像方式是MM_TEXT,其以圖素為單位。
            
             通過下面的方式擷取文字的資訊:
              HDC hdc;
              TEXTMETRIC tm;
              hdc= GetDC(hwnd)
              GetTxtMetrics(hdc, &tm);
              ReleaseDC(hwnd,hdc);
             這樣就可以通過tm結構體變數的各個欄位查看當前裝置內容中關於字元的資訊。

格式化文字:
         windows啟動後,系統字型的大小就不會發生改變。程式當中可以呼叫一次GetTextMetrics函數,擷取系統字型的資訊就可以一直使用。
         通常建議在處理WM_CREATE訊息時進行上述的GetTextMetrics函數呼叫,因為WM_CREATE訊息是視窗訊息處理常式接收的第一個訊息。
     可以這樣處理:
        在訊息處理常式中定義:
          static int cxChar,   //儲存系統字元的寬度
                     cyChar;   //儲存系統字元的高度
          而在訊息處理時:
          case WM_CREATE:
                   hdc=GetDC(hwnd);
                   GetTextMetrics(hdc,&tm);
                   cxChar=tm.tmAvdCharWidth;
                   cyChar=tm.tmHeight+tm.tmExternalLeading;
                   Release(hwnd,hdc);
                   return 0;

       格式化字串函數: sprintf和wsprintf(windows下可用)。
       wspritnf函數原型:
       int wsprintf(char *dest,char *source,...);

       Exp:
             int iLength;
             TCHAR szBuffer[40];
            
             iLength=wsprintf(szBuffer,TEXT("the sum of %i and %i is %i"),iA,iB,iA+iB);
             TextOut(hdc,x,y,szBuffer,iLength);
       wsprintf函數將格式化完的字串放到一個字串中,並且這個函數返回放入到字串中的字元的個數。
       這樣正好符合TextOut函數的使用的兩個參數。

       因為函數的調用方式是__stdcall方式,所以可以:
            TextOut(hdc,x,y,szBuffer,wsprintf(szBuffer,TEXT("the sum of %i and %i is %i"),iA,iB,iA+iB) )。

     擷取系統視覺組件大小資訊: 
     GetSyetemMetrics函數
          GetSystemMetrics函數返回windows中不同視覺組件的大小資訊;標、游標、標題列和捲軸等。這些大小與顯示卡
    和驅動程式相關。
    其函數原型是:
            int WINAPI GetSystemMetrics(int index)

      今天瞎掰就暫時到這,這裡說的有點亂, 不過估計理解應該沒有什麼問題....................

      下一次估計要說捲軸了, 前幾天看書,沒太看明白, 等看明白後再來瞎掰..........

      編製windows的應用程式主要是明白其事件驅動機制以及各個功能的內在機理, 通過那本經典的書可以增強對windows程式的認識, 如果學習有一定的基礎的話,同樣可以學習那本經典核心編程課程,  也是1000+以上的書,估計看完要一陣子......

     計劃慢慢的學完這本書,然後在看看羅老師的那本700多頁的書, 估計會對windows的運行機理有個大概的認識吧.......

     也許以後轉行到挨踢行業,也許就不轉了.........

     誰知道以後的事情呢?

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.