国产一级a片免费看高清,亚洲熟女中文字幕在线视频,黄三级高清在线播放,免费黄色视频在线看

打開APP
userphoto
未登錄

開通VIP,暢享免費(fèi)電子書等14項(xiàng)超值服

開通VIP
TN062:Windows控件消息反射

TN062Windows控件消息反射

TN062: Message Reflection for Windows Controls

本技術(shù)文檔解釋了消息反射,MFC 4.0的新特性,并指導(dǎo)讀者創(chuàng)建一個(gè)簡(jiǎn)單的、可重用的、使用了消息反射的控件。

本文并不討論適用于ActiveX控件(通常稱為OLE控件)的消息反射。請(qǐng)參看Visual C++ Programmer’s GuideActiveX Controls: Subclassing a Windows Control一文。

什么是消息反射?

Windows控件頻繁地向其父窗口發(fā)送消息。例如,很多控件發(fā)送控件顏色提醒消息(WM_CTLCOLOR或其變種)給其父窗口,通知父窗口提供畫刷,以重畫控件的背景。

4.0版本前的WindowsMFC中,父窗口,通常是一個(gè)對(duì)話框,負(fù)責(zé)處理這些消息。這意味著處理消息的代碼放置在父窗口類中,并且需要在任何需要處理這個(gè)消息的窗口中重復(fù)寫這些代碼。在這種情況下,每個(gè)對(duì)話框都必須為其內(nèi)部的控件定制背景色而處理提醒消息。若控件類可以自己處理其背景顏色,那么處理代碼的重用就會(huì)變得非常容易了。

MFC 4.0中,舊的機(jī)制仍將正常運(yùn)行,即父窗口可以處理提醒消息。但同時(shí),MFC 4.0提供了消息反射,允許這些提醒消息既可在子控件中處理又可在其父窗口中處理,使得代碼重用更加容易。以控件背景顏色為例,現(xiàn)在可以創(chuàng)建一個(gè)控件,自己來處理WM_CTLCOLOR的反射消息,一切都不用依靠其父窗口。(注意,消息反射是由MFC實(shí)現(xiàn)的,而非Windows,因此要使用消息反射,父窗口必須繼承于CWnd。

舊版本的MFC為一些消息提供了一些虛函數(shù),使得消息的處理與消息反射機(jī)制相似。例如自畫列表框(owner-drawn list boxes)的消息(WM_DRAWITEM之類)。新的消息反射機(jī)制是通用并且一致的。

消息映射向后兼容MFC 4.0之前的版本。

若在父窗口提供了某一個(gè)或是一組指定消息的處理函數(shù),它將覆蓋反射的消息處理函數(shù)。在自己的消息處理函數(shù)中不應(yīng)調(diào)用父窗口的處理函數(shù)。例如: 若在對(duì)話框處理WM_CTLCOLOR消息,則此處理函數(shù)將會(huì)覆蓋所有反射消息的處理函數(shù)。

若在父窗口類中提供了某一個(gè)或一組WM_NOTIFY消息,則消息處理函數(shù)僅在子窗口沒有使用ON_NOTIFY_REFLECT()處理反射消息時(shí)被調(diào)用。若在消息映射中使用ON_NOTIFY_REFLECT_EX(),消息句柄可能會(huì)或可能不會(huì)允許父窗口處理這些消息。若處理函數(shù)返回TRUE,則父窗口也會(huì)處理此消息,而返回FALSE,則不允許父窗口處理。注意,反射消息在提醒消息前被處理。

當(dāng)WM_NOTIFY被發(fā)送時(shí),首先反射給控件來處理。而其他消息被發(fā)送時(shí),父窗口將首先處理,然后子控件才會(huì)接收到反射的消息。要讓子控件處理這些反射的消息,需要一個(gè)消息處理函數(shù),及消息映射實(shí)體。

反射消息的消息映射宏與普通的提醒消息稍有不同:它在普通的名字后加上了_REFLECT。例如,要在父窗口處理WM_NOTIFY消息,需要在父窗口的消息映射中加上ON_NOTIFY。而要在子控件里處理反射消息,則需要在子控件里使用ON_NOTIFY_REFLECT宏。在一些情況下,參數(shù)也有可能不同。注意,ClassWizard一般都可以正確地添加反射消息及其函數(shù)體。

參看TN061ON_NOTIFYWM_NOTIFY消息了解WM_NOTIFY消息。

反射消息的消息映射及處理函數(shù)原型

要處理控件提醒消息的反射消息,使用下表列出的消息映射宏及函數(shù)原型。ClassWizard一般都可以正確地添加反射消息及其函數(shù)體。參看Visual C++ Programmer’s GuideDefining a Message Handler for a Reflected Message,以了解如何定義反射消息的處理函數(shù)。

要將消息名轉(zhuǎn)化為反射宏名,在消息名前面加上ON_,并在其后面加上_REFLECT即可。例如:WM_CTLCOLOR的反射宏名為ON_WM_CTLCOLOR_REFLECT。(要查看哪些消息可以被反射,將下表的宏作逆變換。)

這種命名規(guī)則的特例有以下三個(gè):

l        WM_COMMAND的反射宏為ON_CONTROL_REFLECT

l        WM_NOTIFY的反射宏為ON_NITIFY_REFLECT

l        ON_UPDATE_COMMAND_UI的反射宏為ON_UPDATE_COMMAND_UI_REFLECT

在上面三種特例下,必須指定處理函數(shù)名,而在其它情況下,必須使用標(biāo)準(zhǔn)的處理函數(shù)名。

函數(shù)參數(shù)及返回值的意義歸檔在其函數(shù)名,或函數(shù)名前加On下。例如CtlColor被歸檔在OnCtlColor中。一些反射消息的處理函數(shù)需要的參數(shù)比父窗口消息處理函數(shù)的更少。直接將本表中的名字與文檔中的形參名相對(duì)應(yīng)即可。

映射實(shí)體

函數(shù)原型

ON_CONTROL_REFLECT(wNotifyCode, memberFxn)

afx_msg void memberFxn();

ON_NOTIFY_REFLECT(wNotifyCode, memberFxn)

afx_msg void memberFxn(NMHDR * pNotifyStruct, LRESULT* result);

ON_UPDATE_COMMAND_UI_REFLECT(memberFxn)

afx_msg void memberFxn(CCmdUI* pCmdUI);

ON_WM_CTLCOLOR_REFLECT()

afx_msg HBRUSH CtlColor(CDC* pDC, UINT nCtlColor);

ON_WM_DRAWITEM_REFLECT()

afx_msg void DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct);

ON_WM_MEASUREITEM_REFLECT()

afx_msg void MeasureItem(LPMEASUREITEMSTRUCT lpMeasureItemStruct);

ON_WM_DELETEITEM_REFLECT()

afx_msg void DeleteItem(LPDELETEITEMSTRUCT lpDeleteItemStruct);

ON_WM_COMPAREITEM_REFLECT()

afx_msg int CompareItem(LPCOMPAREITEMSTRUCT lpCompareItemStruct);

ON_WM_CHARTOITEM_REFLECT()

afx_msg int CharToItem(UINT nKey, UINT nIndex);

ON_WM_VKEYTOITEM_REFLECT()

afx_msg int VKeyToItem(UINT nKey, UINT nIndex);

ON_WM_HSCROLL_REFLECT()

afx_msg void HScroll(UINT nSBCode, UINT nPos);

ON_WM_VSCROLL_REFLECT()

afx_msg void VScroll(UINT nSBCode, UINT nPos);

ON_WM_PARENTNOTIFY_REFLECT()

afx_msg void ParentNotify(UINT message, LPARAM lParam);

ON_NOTIFY_REFLECTON_CONTROL_REFLECT宏有以下變異體,允許其被多個(gè)對(duì)象處理(例如控件及其父窗口)。

映射實(shí)體

函數(shù)原型

ON_NOTIFY_REFLECT_EX(wNotifyCode, memberFxn)

afx_msg BOOL memberFxn(NMHDR * pNotifyStruct, LRESULT* result);

ON_CONTROL_REFLECT_EX(wNotifyCode, memberFxn)

afx_msg BOOL memberFxn();

處理反射消息: 一個(gè)重用控件的例子

本例創(chuàng)建了一個(gè)可重用的控件CYellowEdit。此控件與普通的文本框相似,只是它在黃色背景上顯示黑色的文字。很容易為CYellowEdit添加成員函數(shù),以使之顯示不同的背景顏色。

實(shí)現(xiàn)步驟如下:

1.      在工程中創(chuàng)建一個(gè)新的對(duì)話框。請(qǐng)參見Visual C++ User’s Guide以了解更多信息。

為開發(fā)一個(gè)可重用的控件,應(yīng)有一個(gè)應(yīng)用程序。若沒有現(xiàn)成的應(yīng)用程序,使用AppWizard創(chuàng)建一個(gè)基于對(duì)話框的應(yīng)用程序。

2.      加載工程后,使用ClassWizard創(chuàng)建一個(gè)繼承于CEdit的新類CYellowEdit。選定“Add to Component Gallery”復(fù)選框。

3.      CYellowEdit類里添加三個(gè)變量。前兩個(gè)變量為COLORREF類型,以存放文本顏色及背景顏色。第三個(gè)變量是一個(gè)CBrush對(duì)象,以存放背景畫刷。CBrush可以只創(chuàng)建一次,之后就直接引用,并且在CYellowEdit被銷毀的時(shí)候自動(dòng)銷毀。

4.      在構(gòu)造函數(shù)里初始化成員變量:

CYellowEdit::CYellowEdit()

{

    m_clrText = RGB(0, 0, 0);

    m_clrBkgnd = RGB(255, 255, 0);

    m_brBkgnd.CreateSolidBrush(m_clrBkgnd);

}

 

使用ClassWizard,在CYellowEdit里添加一個(gè)WM_CTLCOLOR反射消息的處理函數(shù)。注意,消息名前的等號(hào)表示此消息已被反射。這在Visual C++ Programmer’s GuideDefining a Message Handler for a Reflected Message有相應(yīng)描述。

ClassWizard將添加以下的消息映射宏及函數(shù):

ON_WM_CTLCOLOR_REFLECT()

 

// Note: other code will be in between….

 

HBRUSH CYellowEdit::CtlColor(CDC* pDC, UINT nCtlColor)

{

    // TODO: Change any attributes of the DC here

   

    // TODO: Return a non-NULL brush if the

    //    parent’s handler should not be called

    return NULL;

}

 

用下面的代碼替換函數(shù)體。這些代碼指定了文字顏色,文字背景顏色以及控件其余部分的背景顏色。

pDC->SetTextColor(m_clrText);    // text

pDC->SetBkColor(m_clrBkgnd);    // text bkgnd

return m_brBkgnd;                // ctl bkgnd

 

在對(duì)話框里創(chuàng)建一個(gè)文本框,按住CTRL鍵的同時(shí)雙擊文本框控件,以將其與一成員變量綁定。在Add Member Variable對(duì)話框中,輸入變量名,選擇控件,并選擇變量類型為CYellowEdit。不要忘了設(shè)置對(duì)話框的TAB順序。并且要在對(duì)話框的頭文件中包含CYellowEdit的頭文件。

編譯并運(yùn)行應(yīng)用程序,文本框?qū)⒂幸粋€(gè)黃色的背景。

現(xiàn)在可以使用Component GalleryCYellowEdit控件類添加到其它工程中去了。

本站僅提供存儲(chǔ)服務(wù),所有內(nèi)容均由用戶發(fā)布,如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊舉報(bào)。
打開APP,閱讀全文并永久保存 查看更多類似文章
猜你喜歡
類似文章
MFC消息機(jī)制
MFC消息映射詳解(整理轉(zhuǎn)載)
MFC常用消息-處理函數(shù)-映射
MFC 消息詳解
windows消息機(jī)制
第十二章 對(duì)話框和對(duì)話框類CDialog
更多類似文章 >>
生活服務(wù)
分享 收藏 導(dǎo)長(zhǎng)圖 關(guān)注 下載文章
綁定賬號(hào)成功
后續(xù)可登錄賬號(hào)暢享VIP特權(quán)!
如果VIP功能使用有故障,
可點(diǎn)擊這里聯(lián)系客服!

聯(lián)系客服