QWndClass : (二) 兩種DrawText的字體大小設置方法

 在設備上下文(即所謂的DC)中使用DrawText來繪製文字其實不難,大概很久前我就弄明白了,直接用CDC的成員函數就好,但若想設置字體的粗細還有大小就讓人有些頭痛。其實GDI說難也不難,問題就是要注意的小節太多,最致命的是各種GDI資源的創建與回收。其實GDI是落後於年代的東西了,像GDI+就很方便,其實,看應用吧,GDI這種東西能不用就不用是最好的。

在實際應用的過程中,發現CDC本來是挺好用的,但容易產生內存泄漏問題,尤其是作用於兼容DC的操作,而且這純粹是微軟的BUG來的,無法修復。於是我改用HDC,用更基礎的API來繪製界面,可能是我個人能力問題——依然存在內存泄漏的隱患。在自己的某項測試中,使用CDC的成員函數循環幾百次系統(CE系統)內存就開始狂掉——當然我的實際應用不會如此頻繁調用,用HDCAPI的話循環三四千次也能測到同樣的內存問題,其中的原因我不瞭解,但從實測上看,使用HDCAPI貌似是更好的選擇。儘管不如使用CDC的成員函數那麼方便,但越是基礎的東西使用起來也是越靈活的,接下來就看你自己的封裝如何了。以上是自己使用GDI中的一點小感慨。說明本文的主題,如何使用不同大小的字體來DrawText呢?我還是直接貼代碼吧,相信應該很容易明瞭的。

 

1、使用CDC的成員函數繪製:

  1. CDC * pDC = this->GetDC();//繪圖的DC設備,注意事後釋放 
  2. for (int i = 1; i <= 4 ; i++) 
  3.     for (int j = 1 ; j <= 8; j++) 
  4.     { 
  5.         CFont myFont; 
  6.         LOGFONT lFont; 
  7.         memset(&lFont, 0, sizeof(LOGFONT)); 
  8.         //計算字體高度與磅值 
  9.         int nNumerator = pDC->GetDeviceCaps(LOGPIXELSY); 
  10.         lFont.lfHeight = ::MulDiv( j * 2, -nNumerator, 72); 
  11.         lFont.lfWeight = i * 200; 
  12.         //創建字體 
  13.         BOOL bRes = myFont.CreateFontIndirect(&lFont); 
  14.         ASSERT(bRes); 
  15.         //選擇字體 
  16.         CFont * pOldFont = pDC->SelectObject(&myFont); 
  17.         //繪製 
  18.         CString str; 
  19.         str.Format(_T("H:%d, W:%d"), j * 2, i * 200); 
  20.         pDC->DrawText(str, CRect( (i - 1) * 150, (j -1) * 30, i * 150 , j * 30), DT_SINGLELINE|DT_LEFT|DT_VCENTER); 
  21.         //釋放GDI資源 
  22.         pDC->SelectObject(pOldFont); 
  23.         bRes = myFont.DeleteObject(); 
  24.         ASSERT(bRes); 
  25.         pOldFont = NULL; 
  26.     } 

 2、使用HDCAPI來繪製:

  1. HDC hDC = ::GetDC(this->m_hWnd);//其實跟上面的方法沒有太多的不一樣,我只是想說CFont跟HDC真的不兼容的 
  2. for (int i = 1; i <= 4 ; i++) 
  3.     for (int j = 1 ; j <= 8; j++) 
  4.     { 
  5.         HFONT hFont; 
  6.         LOGFONT lFont; 
  7.         memset(&lFont, 0, sizeof(LOGFONT)); 
  8.         //計算字體高度與磅值 
  9.         int nNumerator = ::GetDeviceCaps(hDC, LOGPIXELSY); 
  10.         lFont.lfHeight = ::MulDiv( j * 2, -nNumerator, 72); 
  11.         lFont.lfWeight = i * 200; 
  12.         //創建字體 
  13.         hFont = ::CreateFontIndirect(&lFont); 
  14.         ASSERT(hFont); 
  15.         //選擇字體 
  16.         HGDIOBJ hOldFont = ::SelectObject(hDC, hFont); 
  17.         ASSERT(hOldFont); 
  18.         //繪製 
  19.         CString str; 
  20.         str.Format(_T("H:%d, W:%d"), j * 2, i * 200); 
  21.         ::DrawText(hDC, str, -1, CRect( (i - 1) * 150, (j -1) * 30, i * 150 , j * 30), DT_SINGLELINE|DT_LEFT|DT_VCENTER); 
  22.         //釋放GDI資源 
  23.         ::SelectObject(hDC, hOldFont); 
  24.         BOOL bRes = ::DeleteObject(hFont); 
  25.         ASSERT(bRes); 
  26.         hFont = NULL; 
  27.         hOldFont = NULL; 
  28.     } 

 上面兩段函數的效果是一樣的,如下圖所示,其中H表示字體的高度,W表示磅值(單位我就不管了),代碼應該也挺好懂的。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章