欧美性猛交XXXX免费看蜜桃,成人网18免费韩国,亚洲国产成人精品区综合,欧美日韩一区二区三区高清不卡,亚洲综合一区二区精品久久

打開(kāi)APP
userphoto
未登錄

開(kāi)通VIP,暢享免費電子書(shū)等14項超值服

開(kāi)通VIP
VC美化原理補充

3.3.4 WM_DRAWITEM

OnCtlColor只能修改元素的顏色,但不能修改元素的界面框架,WM_DRAWITEM則可以。

當一個(gè)具有Owner draw風(fēng)格的元素(包括按鈕、組合框、列表框和菜單等)需要顯示外觀(guān)時(shí),該元素會(huì )發(fā)送一條WM_DRAWITEM消息至它的隸屬窗口(Owner)。

WM_DRAWITEM的映射函數原型如下:

afx_msg void OnDrawItem( int nIDCtl, LPDRAWITEMSTRUCT lpDrawItemStruct );

參數:

nIDCtl 該控件的ID,如果該元素為菜單,則nIDCtl為0

lpDrawItemStruct 指向DRAWITEMSTRUCT結構對象的指針,DRAWITEMSTRUCT的結構定義如下:

  1. typedef struct tagDRAWITEMSTRUCT   
  2. {   
  3.     UINT    CtlType;   
  4.     UINT    CtlID;   
  5.     UINT    itemID;   
  6.     UINT    itemAction;   
  7.     UINT    itemState;   
  8.     HWND    hwndItem;   
  9.     HDC     hDC;   
  10.      RECT    rcItem;   
  11.     DWORD   itemData;   
  12. }DRAWITEMSTRUCT;   
typedef struct tagDRAWITEMSTRUCT { UINT CtlType; UINT CtlID; UINT itemID; UINT itemAction; UINT itemState; HWND hwndItem; HDC hDC; RECT rcItem; DWORD itemData; }DRAWITEMSTRUCT;

CtlType指定了控件的類(lèi)型,其取值如表3所示:

類(lèi)型值 含義

ODT_BUTTON 按鈕控件

ODT_COMBOBOX 組合框控件

ODT_LISTBOX 列表框控件

ODT_LISTVIEW 列表視圖

ODT_MENU 菜單項

ODT_STATIC 靜態(tài)文本控件

ODT_TAB Tab控件

表3 CtlType的類(lèi)型值與含義

CtlID 指定自繪控件的ID值,該成員不適用于菜單項

itemID表示菜單項ID,也可以表示列表框或者組合框中某項的索引值。對于一個(gè)空的列表框或組合框,該成員的值為?C1。這時(shí)應用程序只繪制焦點(diǎn)矩形(該矩形的坐標由rcItem 成員給出)雖然此時(shí)控件中沒(méi)有需要顯示的項,但是繪制焦點(diǎn)矩形還是很有必要的,因為這樣做能夠提示用戶(hù)該控件是否具有輸入焦點(diǎn)。當然也可以設置itemAction 成員為合適值,使得無(wú)需繪制焦點(diǎn)。

itemAction 指定繪制行為,其取值為表4中所示值的一個(gè)或者多個(gè)的聯(lián)合:

類(lèi)型值 含義

ODA_DRAWENTIRE 當整個(gè)控件都需要被繪制時(shí),設置該值。

ODA_FOCUS 如果控件需要在獲得或失去焦點(diǎn)時(shí)被繪制,則設置該值。此時(shí)應該檢查itemState成員,以確定控件是否具有輸入焦點(diǎn)。

ODA_SELECT 如果控件需要在選中狀態(tài)改變時(shí)被繪制,則設置該值。此時(shí)應該檢查itemState 成員,以確定控件是否處于選中狀態(tài)。

表4 itemAction的類(lèi)型值與含義

itemState 指定了當前繪制項的狀態(tài)。例如,如果菜單項應該被灰色顯示,則可以指定ODS_GRAYED狀態(tài)標志。其取值為表5中所示值的一個(gè)或者多個(gè)的聯(lián)合:

類(lèi)型值 含義

ODS_CHECKED 標記狀態(tài),僅適用于菜單項。

ODS_DEFAULT 默認狀態(tài)。

ODS_DISABLED 禁止狀態(tài)。

ODS_FOCUS 焦點(diǎn)狀態(tài)。

ODS_GRAYED 灰化狀態(tài),僅適用于菜單項。

ODS_SELECTED 選中狀態(tài)。

ODS_HOTLIGHT 僅適用于Windows 98/Me/Windows 2000/XP,熱點(diǎn)狀態(tài):如果鼠標指針位于控件之上,則設置該值,這時(shí)控件會(huì )顯示高亮顏色。

ODS_INACTIVE 僅適用于Windows 98/Me/Windows 2000/XP,非激活狀態(tài)。

ODS_NOACCEL 僅適用于Windows 2000/XP,控件是否有快速鍵。

ODS_COMBOBOXEDIT 在自繪組合框控件中只繪制選擇區域。

ODS_NOFOCUSRECT 僅適用于Windows 2000/XP,不繪制捕獲焦點(diǎn)的效果。

表5 itemState的類(lèi)型值與含義

hwndItem 指定了組合框、列表框和按鈕等自繪控件的窗口句柄;如果自繪的對象為菜單項,則表示包含該菜單項的菜單句柄。

hDC 指定了繪制操作所使用的設備環(huán)境。

rcItem 指定了將被繪制的矩形區域。這個(gè)矩形區域就是上面hDC的作用范圍。系統會(huì )自動(dòng)裁剪組合框、列表框或按鈕等控件的自繪制區域以外的部分。也就是說(shuō)rcItem中的坐標點(diǎn)(0,0)指的就是控件的左上角。但是系統不裁剪菜單項,所以在繪制菜單項的時(shí)候,必須先通過(guò)一定的換算得到該菜單項的位置,以保證繪制操作在我們希望的區域中進(jìn)行。

itemData

對于菜單項,該成員的取值為由CMenu::AppendMenu、CMenu::InsertMenu、CMenu::ModifyMenu等函數傳遞給菜單的值。

對于列表框或這組合框,該成員的取值為由ComboBox::AddString、CComboBox::InsertString、CListBox::AddString或者CListBox::InsertString等函數傳遞給控件的值。

如果ctlType 的取值是ODT_BUTTON或者ODT_STATIC,itemData的取值為0。

圖5是個(gè)相應的例子,它修改了按鈕的界面:

圖8 利用WM_DRAWITEM消息美化界面

實(shí)現代碼如下:

  1. BOOL CUi6Dlg::OnInitDialog()   
  2. {   
  3.     //…   
  4.     //創(chuàng )建字體   
  5.     //CFont CUi1View::m_Font   
  6.      m_Font.CreatePointFont(120, "Impact");   
  7.     //…   
  8. }   
  9.   
  10. void CUi6Dlg::OnDrawItem(int nIDCtl, LPDRAWITEMSTRUCT lpDrawItemStruct)   
  11. {   
  12.     if(nIDCtl == IDC_HELLO_CFAN)   
  13.      {   
  14.         //繪制按鈕框架   
  15.   
  16.         UINT uStyle = DFCS_BUTTONPUSH;   
  17.         //是否按下去了?   
  18.         if (lpDrawItemStruct->itemState & ODS_SELECTED)   
  19.              uStyle |= DFCS_PUSHED;   
  20.   
  21.          CDC dc;   
  22.          dc.Attach(lpDrawItemStruct->hDC);   
  23.          dc.DrawFrameControl(&lpDrawItemStruct->rcItem, DFC_BUTTON, uStyle);   
  24.   
  25.         //輸出文字   
  26.          dc.SelectObject(&m_Font);   
  27.          dc.SetTextColor(RGB(0, 0, 255));   
  28.          dc.SetBkMode(TRANSPARENT);   
  29.   
  30.         CString sText;   
  31.          m_HelloCFan.GetWindowText(sText);   
  32.          dc.TextOut(lpDrawItemStruct->rcItem.left + 20, lpDrawItemStruct->rcItem.top + 20, sText);   
  33.   
  34.         //是否得到焦點(diǎn)   
  35.         if(lpDrawItemStruct->itemState & ODS_FOCUS)   
  36.          {   
  37.             //畫(huà)虛框   
  38.              CRect rtFocus = lpDrawItemStruct->rcItem;   
  39.              rtFocus.DeflateRect(3, 3);   
  40.              dc.DrawFocusRect(&rtFocus);   
  41.          }   
  42.   
  43.         return;   
  44.      }   
  45.      CDialog::OnDrawItem(nIDCtl, lpDrawItemStruct);   
  46. }   
BOOL CUi6Dlg::OnInitDialog() { //… //創(chuàng )建字體 //CFont CUi1View::m_Font m_Font.CreatePointFont(120, "Impact"); //… } void CUi6Dlg::OnDrawItem(int nIDCtl, LPDRAWITEMSTRUCT lpDrawItemStruct) { if(nIDCtl == IDC_HELLO_CFAN) { //繪制按鈕框架 UINT uStyle = DFCS_BUTTONPUSH; //是否按下去了? if (lpDrawItemStruct->itemState & ODS_SELECTED) uStyle |= DFCS_PUSHED; CDC dc; dc.Attach(lpDrawItemStruct->hDC); dc.DrawFrameControl(&lpDrawItemStruct->rcItem, DFC_BUTTON, uStyle); //輸出文字 dc.SelectObject(&m_Font); dc.SetTextColor(RGB(0, 0, 255)); dc.SetBkMode(TRANSPARENT); CString sText; m_HelloCFan.GetWindowText(sText); dc.TextOut(lpDrawItemStruct->rcItem.left + 20, lpDrawItemStruct->rcItem.top + 20, sText); //是否得到焦點(diǎn) if(lpDrawItemStruct->itemState & ODS_FOCUS) { //畫(huà)虛框 CRect rtFocus = lpDrawItemStruct->rcItem; rtFocus.DeflateRect(3, 3); dc.DrawFocusRect(&rtFocus); } return; } CDialog::OnDrawItem(nIDCtl, lpDrawItemStruct); }

別忘了標記Owner draw屬性:

圖9 指定按鈕的Owner draw屬性

值得一提的是,CWnd內部截獲了WM_DRAWITEM、WM_MEASUREITEM等消息,并映射成子元素的相應虛函數的調用,如CButton::DrawItem()。所以,以上例子也可以通過(guò)派生出一個(gè)CButton的派生類(lèi),并重載該類(lèi)的DrawItem()函數來(lái)實(shí)現。使用虛函數機制實(shí)現界面美化參見(jiàn)3.4章節。

3.3.5 WM_MEASUREITEM

僅僅WM_DRAWITEM還是不夠的,對于一些特殊的控件,如ListBox,系統在發(fā)送WM_DRAWITEM消息前,還發(fā)送WM_MEASUREITEM消息,需要你設置ListBox中每個(gè)項目的高度。

WM_DRAWITEM的映射函數原型如下:

afx_msg void OnMeasureItem( int nIDCtl, LPMEASUREITEMSTRUCT lpMeasureItemStruct );

nIDCtl 該控件的ID,如果該元素為菜單,則nIDCtl為0

lpMeasureItemStruct指向MEASUREITEMSTRUCT結構對象的指針,MEASUREITEMSTRUCT的結構定義如下:

  1. typedef struct tagMEASUREITEMSTRUCT   
  2. {   
  3.     UINT    CtlType;   
  4.     UINT    CtlID;   
  5.     UINT    itemID;   
  6.     UINT    itemWidth;   
  7.     UINT    itemHeight;   
  8.     DWORD   itemData   
  9. } MEASUREITEMSTRUCT;   
typedef struct tagMEASUREITEMSTRUCT { UINT CtlType; UINT CtlID; UINT itemID; UINT itemWidth; UINT itemHeight; DWORD itemData } MEASUREITEMSTRUCT;

CtlType指定了控件的類(lèi)型,其取值如表6所示:

類(lèi)型值 含義

ODT_COMBOBOX 組合框控件

ODT_LISTBOX 列表框控件

ODT_MENU 菜單項

表6 CtlType的類(lèi)型值與含義

CtlID 指定自繪控件的ID值,該成員不適用于菜單項

itemID表示菜單項ID,也可以表示可變高度的列表框或組合框中某項的索引值。該成員不適用于固定高度的列表框或組合框。

itemWidth 指定菜單項的寬度

itemHeight指定菜單項或者列表框中某項的的高度,最大值為255

itemData

對于菜單項,該成員的取值為由CMenu::AppendMenu、CMenu::InsertMenu、CMenu::ModifyMenu等函數傳遞給菜單的值。

對于列表框或這組合框,該成員的取值為由ComboBox::AddString、CComboBox::InsertString、CListBox::AddString或者CListBox::InsertString等函數傳遞給控件的值。

圖示出了OnMeasureItem的效果:

圖10 利用WM_MEASUREITEM消息美化界面

相應的OnMeasureItem()實(shí)現如下:

  1. void CUi7Dlg::OnMeasureItem(int nIDCtl, LPMEASUREITEMSTRUCT lpMeasureItemStruct)   
  2. {   
  3.     if(nIDCtl == IDC_COLOR_PICKER)   
  4.      {   
  5.         //設定高度為30   
  6.          lpMeasureItemStruct->itemHeight = 30;   
  7.         return;   
  8.      }   
  9.      CDialog::OnMeasureItem(nIDCtl, lpMeasureItemStruct);   
  10. }   
void CUi7Dlg::OnMeasureItem(int nIDCtl, LPMEASUREITEMSTRUCT lpMeasureItemStruct) { if(nIDCtl == IDC_COLOR_PICKER) { //設定高度為30 lpMeasureItemStruct->itemHeight = 30; return; } CDialog::OnMeasureItem(nIDCtl, lpMeasureItemStruct); }

同樣別忘了指定列表框的Owner draw屬性:

圖11 指定下拉框的Owner draw屬性

3.3.6 NM_CUSTOMDRAW

大家也許熟悉WM_NOTIFY,控件通過(guò)WM_NOTIFY向父窗口發(fā)送消息。在WM_NOTIFY消息體中,部分控件會(huì )發(fā)送NM_CUSTOMDRAW告訴父窗口自己需要繪圖。

可以反射N(xiāo)M_CUSTOMDRAW消息,如:

ON_NOTIFY_REFLECT(NM_CUSTOMDRAW, OnCustomDraw)

afx_msg void OnCustomDraw(NMHDR *pNMHDR, LRESULT *pResult);

參數:

pNMHDR 說(shuō)到底只是一個(gè)指針,大多數情況下它指向一個(gè)NMHDR結構對象,NMHDR結構如下:

  1. typedef struct tagNMHDR   
  2. {   
  3.     HWND hwndFrom;   
  4.     UINT idFrom;   
  5.     UINT code;   
  6. } NMHDR;   
typedef struct tagNMHDR { HWND hwndFrom; UINT idFrom; UINT code; } NMHDR;

其中:

hwndFrom 發(fā)送方控件的窗口句柄

idFrom 發(fā)送方控件的ID

code 通知代碼

對于某些控件來(lái)說(shuō),pNMHDR則會(huì )解釋成其它內容更豐富的結構對象的指針,如:對于列表控件來(lái)說(shuō),pNMHDR常常指向一個(gè)NMCUSTOMDRAW對象,NMCUSTOMDRAW結構如下:

  1. typedef struct tagNMCUSTOMDRAWINFO   
  2. {   
  3.      NMHDR   hdr;   
  4.     DWORD   dwDrawStage;   
  5.     HDC     hdc;   
  6.      RECT    rc;   
  7.     DWORD   dwItemSpec;   
  8.     UINT    uItemState;   
  9.     LPARAM lItemlParam;   
  10. } NMCUSTOMDRAW, FAR * LPNMCUSTOMDRAW;   
typedef struct tagNMCUSTOMDRAWINFO { NMHDR hdr; DWORD dwDrawStage; HDC hdc; RECT rc; DWORD dwItemSpec; UINT uItemState; LPARAM lItemlParam; } NMCUSTOMDRAW, FAR * LPNMCUSTOMDRAW;

hdr NMHDR對象

dwDrawStage 當前繪制狀態(tài),其取值如表7所示:

類(lèi)型值 含義

CDDS_POSTERASE 擦除循環(huán)結束

CDDS_POSTPAINT 繪制循環(huán)結束

CDDS_PREERASE 準備開(kāi)始擦除循環(huán)

CDDS_PREPAINT 準備開(kāi)始繪制循環(huán)

CDDS_ITEM 指定dwItemSpec, uItemState, lItemlParam參數有效

CDDS_ITEMPOSTERASE 列表項擦除結束

CDDS_ITEMPOSTPAINT 列表項繪制結束

CDDS_ITEMPREERASE 準備開(kāi)始列表項擦除

CDDS_ITEMPREPAINT 準備開(kāi)始列表項繪制

CDDS_SUBITEM 指定列表子項

表7 dwDrawStage的類(lèi)型值與含義

hdc指定了繪制操作所使用的設備環(huán)境。

rc指定了將被繪制的矩形區域。

dwItemSpec 列表項的索引

uItemState 當前列表項的狀態(tài),其取值如表8所示:

類(lèi)型值 含義

CDIS_CHECKED 標記狀態(tài)。

CDIS_DEFAULT 默認狀態(tài)。

CDIS_DISABLED 禁止狀態(tài)。

CDIS_FOCUS 焦點(diǎn)狀態(tài)。

CDIS_GRAYED 灰化狀態(tài)。

CDIS_SELECTED 選中狀態(tài)。

CDIS_HOTLIGHT 熱點(diǎn)狀態(tài)。

CDIS_INDETERMINATE 不定狀態(tài)。

CDIS_MARKED 標注狀態(tài)。

表8 uItemState的類(lèi)型值與含義

lItemlParam 當前列表項的綁定數據

pResult 指向狀態(tài)值的指針,指定系統后續操作,依賴(lài)于dwDrawStage:

當dwDrawStage為CDDS_PREPAINT,pResult含義如表9所示:

類(lèi)型值 含義

CDRF_DODEFAULT 默認操作,即系統在列表項繪制循環(huán)過(guò)程不再發(fā)送NM_CUSTOMDRAW。

CDRF_NOTIFYITEMDRAW 指定列表項繪制前后發(fā)送消息。

CDRF_NOTIFYPOSTERASE 列表項擦除結束時(shí)發(fā)送消息。

CDRF_NOTIFYPOSTPAINT 列表項繪制結束時(shí)發(fā)送消息。

表9 pResult的類(lèi)型值與含義(一)

當dwDrawStage為CDDS_ITEMPREPAINT,pResult含義如表10所示:

類(lèi)型值 含義

CDRF_NEWFONT 指定后續操作采用應用中指定的新字體。

CDRF_NOTIFYSUBITEMDRAW 列表子項繪制時(shí)發(fā)送消息。

CDRF_SKIPDEFAULT 系統不必再繪制該子項。

表10 pResult的類(lèi)型值與含義(二)

以下是一個(gè)利用NM_CUSTOMDRAW消息繪制出的多色列表框的例子:

圖12 利用NM_CUSTOMDRAW消息美化界面

對應代碼如下:

  1. void CCoolList::OnCustomDraw(NMHDR *pNMHDR, LRESULT *pResult)   
  2. {   
  3.     //類(lèi)型安全轉換   
  4.      NMLVCUSTOMDRAW* pLVCD = reinterpret_cast<NMLVCUSTOMDRAW*>(pNMHDR);   
  5.      *pResult = 0;   
  6.        
  7.     //指定列表項繪制前后發(fā)送消息   
  8.     if(CDDS_PREPAINT == pLVCD->nmcd.dwDrawStage)   
  9.      {   
  10.          *pResult = CDRF_NOTIFYITEMDRAW;   
  11.      }   
  12.     else if(CDDS_ITEMPREPAINT == pLVCD->nmcd.dwDrawStage)   
  13.      {   
  14.         //奇數行   
  15.         if(pLVCD->nmcd.dwItemSpec % 2)   
  16.              pLVCD->clrTextBk = RGB(255, 255, 128);   
  17.         //偶數行   
  18.         else  
  19.              pLVCD->clrTextBk = RGB(128, 255, 255);   
  20.         //繼續   
  21.          *pResult = CDRF_DODEFAULT;   
  22.      }   
  23. }   
void CCoolList::OnCustomDraw(NMHDR *pNMHDR, LRESULT *pResult) { //類(lèi)型安全轉換 NMLVCUSTOMDRAW* pLVCD = reinterpret_cast<NMLVCUSTOMDRAW*>(pNMHDR); *pResult = 0; //指定列表項繪制前后發(fā)送消息 if(CDDS_PREPAINT == pLVCD->nmcd.dwDrawStage) { *pResult = CDRF_NOTIFYITEMDRAW; } else if(CDDS_ITEMPREPAINT == pLVCD->nmcd.dwDrawStage) { //奇數行 if(pLVCD->nmcd.dwItemSpec % 2) pLVCD->clrTextBk = RGB(255, 255, 128); //偶數行 else pLVCD->clrTextBk = RGB(128, 255, 255); //繼續 *pResult = CDRF_DODEFAULT; } }

注意到上例采取了3.1所推薦的第2種實(shí)現方法,派生了一個(gè)新類(lèi)CCoolList。

3.4 使用MFC類(lèi)的虛函數機制

修改Windows界面,除了從Windows消息機制下功夫,也可以從MFC類(lèi)下功夫,這應該得益于類(lèi)的虛函數機制。為了防止諸如“面向對象技術(shù)”等術(shù)語(yǔ)在此泛濫,以下僅舉一段代碼作為例子:

  1. void CView::OnPaint()   
  2. {   
  3.     // standard paint routine   
  4.      CPaintDC dc(this);   
  5.      OnPrepareDC(&dc);   
  6.      OnDraw(&dc);   
  7. }   
void CView::OnPaint() { // standard paint routine CPaintDC dc(this); OnPrepareDC(&dc); OnDraw(&dc); }

這是MFC中viewcore.cpp中的源代碼,很多讀者總不明白OnDraw()和OnPaint()之間的關(guān)系,從以上的代碼中很容易看出,CView的WM_PAINT消息響應函數OnPaint()會(huì )自動(dòng)調用CView::OnDraw()。而作為開(kāi)發(fā)者的用戶(hù),可以通過(guò)簡(jiǎn)單的OnDraw()的重載實(shí)現對WM_PAINT的處理。所以說(shuō),對MFC類(lèi)的虛函數的重載是對消息機制的擴展。

以下列出了與界面美化相關(guān)的虛函數,參數說(shuō)明略去:

CButton::DrawItem

CCheckListBox::DrawItem

CComboBox::DrawItem

CHeaderCtrl::DrawItem

CListBox::DrawItem

CMenu::DrawItem

CStatusBar::DrawItem

CStatusBarCtrl::DrawItem

CTabCtrl::DrawItem

virtual void DrawItem( LPDRAWITEMSTRUCT lpDrawItemStruct );

Owner draw元素自繪函數

很顯然,位圖菜單都是通過(guò)這個(gè)DrawItem畫(huà)出來(lái)的。限于篇幅,在此不再附以例程。

本文為白喬原創(chuàng ),曾經(jīng)在《電腦愛(ài)好者》合訂本上發(fā)表。

本站僅提供存儲服務(wù),所有內容均由用戶(hù)發(fā)布,如發(fā)現有害或侵權內容,請點(diǎn)擊舉報。
打開(kāi)APP,閱讀全文并永久保存 查看更多類(lèi)似文章
猜你喜歡
類(lèi)似文章
白喬原創(chuàng ):VC之美化界面篇
WM_MEASUREITEM
MFC按鈕自繪消息分析
VC MFC列表視圖(CListCtrl)控件
自繪控件的4種方法
自繪按鈕的實(shí)現
更多類(lèi)似文章 >>
生活服務(wù)
分享 收藏 導長(cháng)圖 關(guān)注 下載文章
綁定賬號成功
后續可登錄賬號暢享VIP特權!
如果VIP功能使用有故障,
可點(diǎn)擊這里聯(lián)系客服!

聯(lián)系客服

欧美性猛交XXXX免费看蜜桃,成人网18免费韩国,亚洲国产成人精品区综合,欧美日韩一区二区三区高清不卡,亚洲综合一区二区精品久久