小男孩‘自慰网亚洲一区二区,亚洲一级在线播放毛片,亚洲中文字幕av每天更新,黄aⅴ永久免费无码,91成人午夜在线精品,色网站免费在线观看,亚洲欧洲wwwww在线观看

分享

WM_MEASUREITEM

 DavinTang 2011-03-17

CWnd::OnMeasureItem

afx_msg void OnMeasureItem( int nIDCtl, LPMEASUREITEMSTRUCT lpMeasureItemStruct );

參數(shù):

nIDCtl 控件的ID。
lpMeasureItemStruct 指向一個MEASUREITEMSTRUCT數(shù)據(jù)結(jié)構(gòu),其中包含自畫控件的大小。

說明:
當(dāng)控件被創(chuàng)建的時候,框架為自畫按鈕、組合框、列表框或菜單項調(diào)用這個成員函數(shù)。
重載這個函數(shù)并填充lpMeasureItemStruct指向的MEASUREITEMSTRUCT數(shù)據(jù)結(jié)構(gòu),然后返回;這將通知Windows控件的大小,并使Windows能夠正確地處理控件的用戶交互。
如果列表框或組合框是用LBS_OWNERDRAWVARIABLE或CBS_OWNERDRAWVARIA_BLE風(fēng)格創(chuàng)建的,則框架為控件中的每一個項調(diào)用這個函數(shù);否則這個函數(shù)只被調(diào)用一次。
在發(fā)送WM_INITDIALOG消息之前,Windows為用OWNERDRAWFIXED風(fēng)格創(chuàng)建的組合框和列表框的擁有者發(fā)出對 OnMeasureItem的調(diào)用。其結(jié)果是,當(dāng)擁有者接收到這個調(diào)用時,Windows還沒有確定在控件中使用的字體的高度和寬度;需要這些值的函數(shù)調(diào) 用和計算應(yīng)該發(fā)生在應(yīng)用程序或庫的主函數(shù)中。
如果要測量的的項是CMenu,CListBox或CComboBox對象,則將調(diào)用適當(dāng)?shù)念惖奶摵瘮?shù)MeasureItem。重載適當(dāng)?shù)目丶惖腗easureItem成員函數(shù)以計算并設(shè)置每個項的大小。
僅當(dāng)控件類是在運行時創(chuàng)建,或者它是用LBS_OWNERDRAWVARIABLE或CBS_OWNERDRAWVARIABLE風(fēng)格創(chuàng)建的時候,OnMeasureItem才會被調(diào)用。這是因為WM_MEASUREITEM消息時在控件創(chuàng)建過程的早期被發(fā)送的。
如果你使用DDX_Control,SubclassDlgItem或SubclassWindow進(jìn)行了子類化,則子類化過程通常發(fā)生在創(chuàng)建過程之后。 因此,在控件的OnChildNotify函數(shù)中無法處理WM_MEASUREITEM消息,這是MFC用來實現(xiàn) ON_WM_MEASUREITEM_REFLECT的機(jī)制。
注意 框架調(diào)用這個成員函數(shù)以允許你的應(yīng)用程序處理一個Windows消息。傳遞給你的成員函數(shù)的參數(shù)反映了接收到消息時框架接收到的參數(shù)。如果你調(diào)用了這個函數(shù)的基類實現(xiàn),則該實現(xiàn)將使用最初傳遞給消息的參數(shù)(而不是你提供給這個函數(shù)的參數(shù))。

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

WM_DRAWITEM的映射函數(shù)原型如下:

afx_msg void OnMeasureItem( int nIDCtl, LPMEASUREITEMSTRUCT lpMeasureItemStruct );

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

lpMeasureItemStruct指向MEASUREITEMSTRUCT結(jié)構(gòu)對象的指針,MEASUREITEMSTRUCT的結(jié)構(gòu)定義如下:

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

CtlType指定了控件的類型,其取值如表6所示:

類型值 含義

ODT_COMBOBOX 組合框控件

ODT_LISTBOX 列表框控件

ODT_MENU 菜單項

表6 CtlType的類型值與含義

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

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

itemWidth 指定菜單項的寬度

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

itemData

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

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

圖示出了OnMeasureItem的效果:

圖10 利用WM_MEASUREITEM消息美化界面

相應(yīng)的OnMeasureItem()實現(xiàn)如下:

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

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

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

3.3.6 NM_CUSTOMDRAW

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

可以反射NM_CUSTOMDRAW消息,如:

ON_NOTIFY_REFLECT(NM_CUSTOMDRAW, OnCustomDraw)

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

參數(shù):

pNMHDR 說到底只是一個指針,大多數(shù)情況下它指向一個NMHDR結(jié)構(gòu)對象,NMHDR結(jié)構(gòu)如下:

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

其中:

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

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

code 通知代碼

對于某些控件來說,pNMHDR則會解釋成其它內(nèi)容更豐富的結(jié)構(gòu)對象的指針,如:對于列表控件來說,pNMHDR常常指向一個NMCUSTOMDRAW對象,NMCUSTOMDRAW結(jié)構(gòu)如下:

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

hdr NMHDR對象

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

類型值 含義

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

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

CDDS_PREERASE 準(zhǔn)備開始擦除循環(huán)

CDDS_PREPAINT 準(zhǔn)備開始繪制循環(huán)

CDDS_ITEM 指定dwItemSpec, uItemState, lItemlParam參數(shù)有效

CDDS_ITEMPOSTERASE 列表項擦除結(jié)束

CDDS_ITEMPOSTPAINT 列表項繪制結(jié)束

CDDS_ITEMPREERASE 準(zhǔn)備開始列表項擦除

CDDS_ITEMPREPAINT 準(zhǔn)備開始列表項繪制

CDDS_SUBITEM 指定列表子項

表7 dwDrawStage的類型值與含義

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

rc指定了將被繪制的矩形區(qū)域。

dwItemSpec 列表項的索引

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

類型值 含義

CDIS_CHECKED 標(biāo)記狀態(tài)。

CDIS_DEFAULT 默認(rèn)狀態(tài)。

CDIS_DISABLED 禁止?fàn)顟B(tài)。

CDIS_FOCUS 焦點狀態(tài)。

CDIS_GRAYED 灰化狀態(tài)。

CDIS_SELECTED 選中狀態(tài)。

CDIS_HOTLIGHT 熱點狀態(tài)。

CDIS_INDETERMINATE 不定狀態(tài)。

CDIS_MARKED 標(biāo)注狀態(tài)。

表8 uItemState的類型值與含義

lItemlParam 當(dāng)前列表項的綁定數(shù)據(jù)

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

當(dāng)dwDrawStage為CDDS_PREPAINT,pResult含義如表9所示:

類型值 含義

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

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

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

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

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

當(dāng)dwDrawStage為CDDS_ITEMPREPAINT,pResult含義如表10所示:

類型值 含義

CDRF_NEWFONT 指定后續(xù)操作采用應(yīng)用中指定的新字體。

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

CDRF_SKIPDEFAULT 系統(tǒng)不必再繪制該子項。

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

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

圖12 利用NM_CUSTOMDRAW消息美化界面

對應(yīng)代碼如下:

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

注意到上例采取了3.1所推薦的第2種實現(xiàn)方法,派生了一個新類CCoolList。

3.4 使用MFC類的虛函數(shù)機(jī)制

修改Windows界面,除了從Windows消息機(jī)制下功夫,也可以從MFC類下功夫,這應(yīng)該得益于類的虛函數(shù)機(jī)制。為了防止諸如“面向?qū)ο蠹夹g(shù)”等術(shù)語在此泛濫,以下僅舉一段代碼作為例子:

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

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

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

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元素自繪函數(shù)

很顯然,位圖菜單都是通過這個DrawItem畫出來的。限于篇幅,在此不再附以例程。

    本站是提供個人知識管理的網(wǎng)絡(luò)存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點。請注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點擊一鍵舉報。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多