久久99精品久久久久久琪琪,久久人人爽人人爽人人片亞洲,熟妇人妻无码中文字幕,亚洲精品无码久久久久久久

MFC繪制自定義按鈕大全

時(shí)間:2019-05-15 10:52:53下載本文作者:會(huì)員上傳
簡(jiǎn)介:寫(xiě)寫(xiě)幫文庫(kù)小編為你整理了多篇相關(guān)的《MFC繪制自定義按鈕大全》,但愿對(duì)你工作學(xué)習(xí)有幫助,當(dāng)然你在寫(xiě)寫(xiě)幫文庫(kù)還可以找到更多《MFC繪制自定義按鈕大全》。

第一篇:MFC繪制自定義按鈕大全

VC++ MFC界面技巧--按鈕

★ 5--2--1 圖標(biāo)按鈕

圖標(biāo)按鈕可謂是按鈕控件使用圖像最簡(jiǎn)單的方式,除此之外圖標(biāo)按鈕的優(yōu)點(diǎn)還在于顯示在按鈕上的圖標(biāo)能夠使用透明色,因而不必再去為處理非矩形圖像在按鈕顏色發(fā)生變化時(shí)邊緣顏色的處理而費(fèi)心。不過(guò)也正是使用圖標(biāo)導(dǎo)致了圖標(biāo)按鈕的天生弱點(diǎn)。圖標(biāo)太小了,僅僅才 32×32 像素大小,在有的場(chǎng)合僅靠使用這么小的圖像就有些顯得力不從心了。

在講圖標(biāo)按鈕如何使用之前,先得告訴讀者句柄的概念。句柄是什么?很多教科書(shū)上都這樣定義:句柄是一個(gè)用于代表對(duì)象的 32 位整型值。不過(guò)這對(duì)于很多初學(xué)者而言,并不是太好理解。其實(shí)也可以將未賦值的句柄理解為一個(gè)指向“空白”(void *)的指針,事實(shí)上也如此,在 Winnt.h 中,句柄就是如此被聲明的:typedef void *HANDLE;當(dāng)句柄被賦值之后,它就成為指向某個(gè)特定位置的指針,即代表了某個(gè)特定的對(duì)象。之所以在現(xiàn)在提及句柄,是因?yàn)榫浔?Windows 編程中的一個(gè)關(guān)鍵性概念。盡管在前面除第三章外的內(nèi)容中很少涉及它,不過(guò)在下面的學(xué)習(xí)中我們將會(huì)很頻繁的使用到句柄。

技術(shù)概要:

使用圖標(biāo)按鈕很簡(jiǎn)單,大的步驟僅僅就三步:

①.從外部導(dǎo)入一個(gè)圖標(biāo)或自己創(chuàng)建一個(gè)圖標(biāo)作為資源。②.從資源中載入所要使用的圖標(biāo)。③.在要使用圖標(biāo)的按鈕上設(shè)置圖標(biāo)。

具體實(shí)現(xiàn):

■第一步導(dǎo)入圖標(biāo)沒(méi)有什么特別之處,同前面 2.2 節(jié)中使用靜態(tài)圖像控件導(dǎo)入位圖是非常類(lèi)似的。無(wú)非就是使用 Insert 菜單上的 Resource 命令,導(dǎo)入或創(chuàng)建一個(gè)圖標(biāo)即可。

■第二步載入圖標(biāo)就涉及到一些細(xì)節(jié)問(wèn)題了。使用函數(shù) LoadIcon()載入圖標(biāo)。因?yàn)長(zhǎng)oadIcon()是類(lèi) CWinApp 的成員函數(shù),同時(shí)函數(shù) LoadIcon()返回所載入圖標(biāo)的句柄。所以我們采用以下方法來(lái)調(diào)用函數(shù) LoadIcon(): h_Icon = AfxGetApp()-> LoadIcon(IDI_Icon);當(dāng)然,在該語(yǔ)句之前還必須要有對(duì)圖標(biāo)句柄 h_Icon 的定義: HICON h_Icon;

■第三步為按鈕設(shè)置圖標(biāo)了,這通過(guò)調(diào)用函數(shù) SetIcon()來(lái)實(shí)現(xiàn)。同時(shí)不要忘記,還須在使用圖標(biāo)的按鈕的 Properties 設(shè)置中設(shè)置 Icon 屬性,指明該按鈕是一個(gè)圖標(biāo)按鈕。因?yàn)楹瘮?shù) SetIcon()為類(lèi) CButton 的成員函數(shù),可以通過(guò)兩種方法來(lái)調(diào)用該函數(shù)。一是通過(guò) CButton 類(lèi)對(duì)象來(lái)調(diào)用 SetIcon(),如下面代碼:

m_BtonIcon.SetIcon(h_Icon);// m_BtonIcon 為一個(gè) CButton 類(lèi)對(duì)象。

二是先由函數(shù) GetDlgItem()獲得一個(gè)指向 CWnd 對(duì)象的指針,再通過(guò)強(qiáng)制類(lèi)型轉(zhuǎn)換將該指針轉(zhuǎn)換為一個(gè)指向 CButton 類(lèi)對(duì)象的指針。進(jìn)而通過(guò)該指針來(lái)調(diào)用函數(shù) SetIcon()。具體實(shí)現(xiàn)代碼如下:

CWnd *pWnd = GetDlgItem(IDC_RADIO2);

CButton *pBton =(CButton *)pWnd;pBton-> SetIcon(h_Icon2);既然有第一種較為簡(jiǎn)便的方法為按鈕設(shè)置圖標(biāo),為何還要提及第二種方法呢?因?yàn)椴⒉皇窃谌魏吻闆r下都會(huì)有 CButton 類(lèi)對(duì)象的,例如對(duì)于一組單選按鈕。只能為它們定義一個(gè) CButton 類(lèi)對(duì)象,如果使用該對(duì)象來(lái)調(diào)用函數(shù) SetIcon(),則只能在設(shè)置了 Group 屬性的那個(gè)單選按鈕上設(shè)置圖標(biāo)。所以要達(dá)到在一組單選按鈕中分別設(shè)置不同圖標(biāo)的目的,就只有使用第二種方法。

盡管在現(xiàn)在的 Windows 編程中,資源句柄數(shù)多得相對(duì)于我們而言幾乎是無(wú)限的,但最好在使用完資源句柄后及時(shí)的把它們刪除掉。上面所講述的方法不僅適用于 Push Button,而且同樣適用于 Radio Button、Check Box 和 Group Box。

★ 5--2--2 位圖按鈕

圖標(biāo)按鈕雖有著種種優(yōu)點(diǎn),但它能顯示的圖像實(shí)在是太小了。在有的場(chǎng)合顯然就不適用了。位圖按鈕可以在按鈕表面顯示一幅位圖而不再是一個(gè)小小的圖標(biāo)。但是因?yàn)樵谖粓D中不能使用透明色,因而當(dāng)顯示的位圖不為矩形時(shí),就得為位圖中非矩形部分的背景色動(dòng)一番腦筋了。因?yàn)榇嬖谥脩?hù)改變按鈕表面顏色,也就是位圖背景色的可能性。可以用透明位圖的技術(shù)來(lái)解決這一難題,這將在后面 5.7 實(shí)現(xiàn)具有透明性的位圖中講述。

技術(shù)概要:

位圖按鈕的使用的大致步驟同圖標(biāo)按鈕基本相似,也是以下三個(gè)步驟: ① 從外部導(dǎo)入一個(gè)位圖或自己創(chuàng)建一個(gè)位圖作為資源。② 從資源中載入所要使用的位圖。③ 在要使用位圖的按鈕上設(shè)置位圖。

具體實(shí)現(xiàn):

■第一步從外部導(dǎo)入一個(gè)位圖作為資源同使用圖標(biāo)按鈕時(shí)是完全一致的,在此就不詳細(xì)講述了。

■第二步中,利用函數(shù) LoadBitmap()從資源中載入位圖。函數(shù) LoadBitmap()為一個(gè) API 函數(shù),定義如下: HBITMAP LoadBitmap(HINSTANCE hInstance, // handle of application instance LPCTSTR lpBitmapName // address of bitmap resource name);所以,為達(dá)到載入位圖的目的,不僅要定義一個(gè)位圖句柄 hBitmap: HBITMAP hBitmap;而且還要定義一個(gè)應(yīng)用程序?qū)嵗浔?hInstance;: HINSTANCE hInstance;并調(diào)用函數(shù) AfxGetInstanceHandle()以獲得當(dāng)前的應(yīng)用程序?qū)嵗浔a如下: hInstance = ::AfxGetInstanceHandle();只有在聲明并獲得了當(dāng)前的應(yīng)用程序句柄后,才能使用以下語(yǔ)句載入位圖: hBitmap = ::LoadBitmap(hInstance,“BMP1”);注意,在函數(shù) LoadBitmap()中的第二個(gè)參數(shù)為資源名,而非資源 ID。因?yàn)橘Y源名是一個(gè)字符串,而資源 ID 則是一個(gè)整型量。所以在創(chuàng)建或?qū)胛粓D后,為該位圖資源命名時(shí)要加上雙引號(hào)以表示這是一個(gè)資源名。如右圖 5-2:

■在第三步中,為要使用位

圖的按鈕設(shè)置位圖,方法與圖標(biāo)按鈕完全相同。首先是要在使用位圖的按鈕的 Properties 設(shè)置中設(shè)置 Bitmap 屬性,指明該按鈕是一個(gè)位圖按鈕。然后再調(diào)用 CButton 類(lèi)函數(shù) SetBitmap()為按鈕設(shè)置位圖。代碼如下:

// m_BtonBmp 為一個(gè) CButton 類(lèi)對(duì)象。m_BtonBmp.SetBitmap(hBitmap);或

pWnd = GetDlgItem(IDC_Check);pBton =(CButton *)pWnd;pBton-> SetBitmap(hBitmap);

同圖標(biāo)按鈕一樣,使用位圖不局限于 Push Button,而且同樣適用于 Radio Button、Check Box 和 Group Box。同時(shí),最好在使用完位圖句柄后及時(shí)的將它刪除掉。

★ 5--2--3 CBitmapButton 類(lèi)位圖按鈕

前面所講述的圖標(biāo)及位圖按鈕最大的不足在于,無(wú)論當(dāng)按鈕控件處于何種狀態(tài),按鈕上所顯示的圖案總是一成不變的,相比之下那些隨著操作而實(shí)時(shí)改變圖案的按鈕就具有更加生動(dòng)的效果。MFC 庫(kù)為我們捉供了一個(gè)這樣的類(lèi) CBitmapButton。利用這個(gè)類(lèi),我們可以為一個(gè)按鈕設(shè)計(jì)四幅不同位圖、分別用于正常狀態(tài)、按下?tīng)顟B(tài)、獲得輸入焦點(diǎn)和無(wú)效時(shí)。這樣,隨著按鈕狀態(tài)的改變,位圖也隨之切換,這樣就使按鈕呈現(xiàn)出很強(qiáng)的動(dòng)感效果。令人高興的是,類(lèi) CBitmapButton 將很多操作的細(xì)節(jié)都封裝了起來(lái),因而我們能夠很方便的達(dá)到上述目的。由于以上原因,CBitmapButton 類(lèi)位圖按鈕有著比圖標(biāo)按鈕和位圖按鈕更為廣闊的使用范圍。在一般情況下,都將 CBitmapButton 類(lèi)位圖按鈕稱(chēng)作是位圖按鈕,而將真正的位圖按鈕給忽略了。

CBitmapButton 類(lèi)位圖按鈕的缺點(diǎn)同位圖按鈕是一致的,都是在對(duì)透明色的處理上。還有一個(gè)比較嚴(yán)重的問(wèn)題是 CBitmapButton 類(lèi)位圖按鈕是將位圖按原始大小繪制在按鈕上,而不是隨按鈕大小而縮放位圖。這在平時(shí)不會(huì)導(dǎo)致任何問(wèn)題,但若是在 Windows 中更改了顯示字體的大小,則對(duì)話(huà)框及上面的按鈕控件大小也隨之改變,但位圖按鈕上的位圖卻保持原有大小不變,這樣就會(huì)在外觀上造成嚴(yán)重的問(wèn)題。盡管有以上問(wèn)題的存在,CBitmapButton 類(lèi)位圖按鈕還是具有很大的實(shí)用價(jià)值,因?yàn)楦冻龊苌俚拇a就可以得到生動(dòng)形象的圖形效果。、下面就講述 CBitmapButton 類(lèi)位圖按鈕的使用方法(以下均簡(jiǎn)稱(chēng)為位圖按鈕)。絕大數(shù)情況下,使用位圖按鈕只需四個(gè)步驟:

● 第一步:在要使用位圖的按鈕的 Properties 設(shè)置中設(shè)置 Owner Draw 屬性

● 第二步:創(chuàng)建或從外部導(dǎo)入至少一幅至多四幅位圖。位圖按鈕所使用的位圖顏色最多可達(dá) 256 色,但對(duì)于 256 色的位圖不能通過(guò)剪貼的的方式來(lái)創(chuàng)建。而必須使用導(dǎo)入的方式來(lái)創(chuàng)建。若該按鈕控件的 Caption(標(biāo)題)為 BmpBton,則將這四幅位圖的 ID 分別設(shè)定為 “BMPBTONU”、“BMPBTOND”、“BMPBTONF”、“BMPBTONX

”分別對(duì)應(yīng)于按鈕的正常狀態(tài)、按下?tīng)顟B(tài)、獲得輸入焦點(diǎn)狀態(tài)和無(wú)效狀態(tài)。注意,只有在正常狀態(tài)顯示的位圖是必須的,其它狀態(tài)的位圖都是可選的;還有就是代表位圖的 ID 都必須加上雙引號(hào)并且大寫(xiě)(如下圖 5-3)。實(shí)際上,加上雙引號(hào)就表示該資源是以字符串常量來(lái)標(biāo)識(shí)。

● 第三步:在使用位圖按鈕的類(lèi)的類(lèi)定義文件中聲明 CBitmapButton 類(lèi)對(duì)象:CBitmapButton m_BtonSet;

● 第四步:在對(duì)話(huà)框的 OnInitDialog()函數(shù)中通過(guò) CBitmapButton 類(lèi)對(duì)象調(diào)用函數(shù) AutoLoad()自動(dòng)加載位圖: m_BtonSet.AutoLoad(IDC_BtonSet,this);

經(jīng)過(guò)以上四個(gè)步驟,一個(gè)位圖按鈕就創(chuàng)建好了。在運(yùn)行中,CBitmapButton 類(lèi)會(huì)自動(dòng)根據(jù)按鈕的狀態(tài)顯示對(duì)應(yīng)的位圖。利用位圖按鈕技術(shù),再加上一點(diǎn)鼠標(biāo)感應(yīng)技術(shù),就很容易做出像網(wǎng)頁(yè)按鈕那樣的在鼠標(biāo)經(jīng)過(guò)時(shí)加亮的動(dòng)態(tài)效果。也能輕易的實(shí)現(xiàn)像 Word 中那樣的平面按鈕。這些將在后面的章節(jié)中講述。

需要說(shuō)明的是,CBitmapButton 類(lèi)位圖按鈕僅限于在 Push Button 使用。在默寫(xiě)情況下,我們可能需要?jiǎng)討B(tài)創(chuàng)建位圖按鈕,在動(dòng)態(tài)創(chuàng)建位圖按鈕時(shí),不能使用函數(shù) AutoLoad()加載位圖,而要使用函數(shù) LoadBitmaps()來(lái)加載位圖。動(dòng)態(tài)創(chuàng)建位圖按鈕主要有以下幾個(gè)步驟: ●第一步:為要?jiǎng)?chuàng)建的控件分配一個(gè) ID 值。●第二步:定義一個(gè) CBitmapButton 類(lèi)對(duì)象。

●第三步:由該對(duì)象調(diào)用函數(shù) Create()創(chuàng)建位圖按鈕,并調(diào)用函數(shù) LoadBitmap()加載位圖。在調(diào)用函數(shù) SizeToContent()調(diào)整按鈕控件的大小以適應(yīng)位圖。● 第四步:加入對(duì)新創(chuàng)建按鈕的消息處理。第三步實(shí)現(xiàn)代碼如下:

m_BmpBtonExit.Create(“EXIT”,BS_PUSHBUTTON|WS_VISIBLE|BS_OWNERDRAW, rcBtonExit,this,IDOK);m_BmpBtonExit.LoadBitmaps(“EXITU”,“EXITD”);

★ 5--2--4 按鈕的自繪制

前面講述的三種在按鈕上顯示圖像的方法或多或少的存在著不足之處,圖標(biāo)按鈕太小,位圖按鈕無(wú)法設(shè)置透明色,CBitmapButton 類(lèi)位圖按鈕位圖大小不能隨按鈕控件變化。使用按鈕的自繪制技術(shù)是解決以上問(wèn)題的最佳途徑。當(dāng)然,按鈕的自繪制技術(shù)的作用不僅僅局限于按鈕表面顯示圖像,利用它可以充分發(fā)揮自己的創(chuàng)造力從而創(chuàng)建出各式各樣的按鈕控件。例如動(dòng)畫(huà)按鈕等。如果說(shuō)利用按鈕自繪制技術(shù)在按鈕上顯示圖像唯一有一點(diǎn)不足的話(huà),那就是實(shí)現(xiàn)略為復(fù)雜了一些。但利用按鈕自繪制技術(shù),在配合以 DIB 文件讀取技術(shù),就完全能夠?qū)崿F(xiàn)象 Winamp 中那樣的 Skin 技術(shù)。

概念解釋?zhuān)?/p>

先解釋一下什么叫做按鈕的自繪制,準(zhǔn)確的說(shuō)應(yīng)該是控件的自繪制技術(shù)。Windows 能夠向控件的父窗口發(fā)送消息以讓父窗口定制控件的外觀和行為。MFC 則更近了一步,它能夠譯解

自繪制參數(shù)并將消息發(fā)回控件本身。因?yàn)槔L制控件的代碼實(shí)在控件類(lèi)中實(shí)現(xiàn),而不是在擁有控件的窗口中,因而稱(chēng)為“自繪制”。除按鈕控件可以自繪制外,列表框、組合框以及菜單都支持自繪制。

在基于對(duì)話(huà)框的應(yīng)用程序框架的基礎(chǔ)上創(chuàng)建一個(gè)自繪制的按鈕,主要有以下步驟: ■ 第一步:

在對(duì)話(huà)框上放置一個(gè)按鈕,并在其 Properties 中設(shè)置 Owner Draw 屬性。■ 第二步:

用 ClassWizard 從 CButton 類(lèi)中派生出一個(gè)新類(lèi)。進(jìn)入 ClassWizard,點(diǎn)擊 Message Maps 標(biāo)簽下的 New 按鈕,在彈出的菜單中選擇 New 命令進(jìn)入 New Class 對(duì)話(huà)框。在 New Class 對(duì)話(huà)框中填入新創(chuàng)建類(lèi)的名稱(chēng) CownerDrawBton,以及選擇所創(chuàng)建類(lèi)的父類(lèi)為 CButton(如下圖 5-4):

■ 第三步:

為新創(chuàng)建的 COwnerDrawBton 類(lèi)增加一個(gè)成員函數(shù) DrawItem()。在 WorkSpace 窗口中的 Class View 標(biāo)簽下,右鍵單擊類(lèi) COwnerDrawBton,在隨后的菜單中選擇 Add Virtual Funtion?命令(如左下圖 5-5)進(jìn)入 New Virtual Override for class COwnerDrawBton 對(duì)話(huà)框(如右下圖 5-6),在該對(duì)話(huà)框的 New Virtual Function 欄中選擇函數(shù) DrawItem,再點(diǎn)擊 Add and Edit 按鈕就超越了函數(shù) DrawItem,并進(jìn)入其內(nèi)部處于待編輯狀態(tài)。

概念解釋?zhuān)?/p>

函數(shù) DrawItem():該函數(shù)在當(dāng)自繪制按鈕的外觀需要重繪時(shí)調(diào)用。其定義如下: virtual void DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct);參數(shù) lpDrawItemStruct 為指向結(jié)構(gòu) DRAWITEMSTRUCT 的一個(gè)長(zhǎng)指針。結(jié)構(gòu)DRAWITEMSTRUCT 定義如下:

typedef struct tagDRAWITEMSTRUCT { UINT CtlType;UINT CtlID;UINT itemID;UINT itemAction;UINT itemState;HWND hwndItem;HDC hDC;RECT rcItem;DWORD itemData;} DRAWITEMSTRUCT;該結(jié)構(gòu)中部分成員變量作用如下:

CtlType:表示控件類(lèi)型,當(dāng)為常量 ODT_BUTTON 表示為自繪制按鈕。CtlID :表示控件的 ID。ItemAction:繪制動(dòng)作。

ItemState:在當(dāng)前繪制動(dòng)作完成后,確定控件所處狀態(tài)。HwndItem:控件窗口的句柄。HDC:設(shè)備環(huán)境句柄。

RcItem:確定自繪制控件大小的矩形。

通過(guò)DRAWITEMSTRUCT結(jié)構(gòu)中的各成員變量,就可以為控件的自繪制提供必要的條件。

■ 第四步:

利用 ClassWizard 中定義一個(gè) COwnerDrawBton 類(lèi)對(duì)象 m_BtonOD(如下圖 5-7):注意在 VC++ 中,必須采用這種方式來(lái)定義對(duì)象 m_BtonOD,如果是在類(lèi)定義文件中手工定義該對(duì)象的話(huà),則不會(huì)執(zhí)行超越的虛函數(shù) DrawItem()。同樣,如果是不定義該對(duì)象的話(huà),則不會(huì)執(zhí)行函數(shù)DrawItem()。

■ 第五步:

向函數(shù) DrawItem()中加入以下代碼:

void COwnerDrawBton::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct){ // TODO: Add your code to draw the specified item CDC *pDC;CRect rcBton;CDC dcMem;

BITMAP s_

Bmp;CBitmap m_Bitmap;CBitmap *pOldBitmap;

pDC = CDC::FromHandle(lpDrawItemStruct-> hDC);// 將設(shè)備環(huán)境句柄轉(zhuǎn)換為指向設(shè)備環(huán)境的指針

rcBton = lpDrawItemStruct-> rcItem;// 獲取按鈕控件大小

m_Bitmap.LoadBitmap(IDB_Bmp);// 載入位圖

dcMem.CreateCompatibleDC(pDC);// 創(chuàng)建于內(nèi)存設(shè)備環(huán)境相兼容的設(shè)備環(huán)境

pOldBitmap = dcMem.SelectObject(&m_Bitmap);// 將位圖對(duì)象選入到內(nèi)存設(shè)備環(huán)境中

m_Bitmap.GetBitmap(&s_Bmp);// 獲取位圖信息

pDC-> StretchBlt(rcBton.left,rcBton.top,rcBton.Width(),rcBton.Height(), &dcMem,0,0,s_Bmp.bmWidth,s_Bmp.bmHeight,SRCCOPY);// 將位圖從內(nèi)存設(shè)備環(huán)境拷貝到顯示設(shè)備環(huán)境

dcMem.SelectObject(pOldBitmap);// 刪除剛才選入到內(nèi)存設(shè)備環(huán)境的位圖對(duì)象 }

在上面的代碼只是為了說(shuō)明如何進(jìn)行按鈕控件的自繪制,它距實(shí)用要求還有一段距離。因?yàn)樵趯?duì)話(huà)框上每個(gè)自繪制的按鈕控件都會(huì)調(diào)用 DrawItem()函數(shù)。所以在 DrawItem()函數(shù)內(nèi)部,還必須根據(jù)結(jié)構(gòu) DRAWITEMSTRUCT 的成員變量 CtlID 來(lái)區(qū)分不同的按鈕控件,進(jìn)而再采取不同的操作。同時(shí)還需根據(jù)按鈕控件的不同狀態(tài),進(jìn)行不同的操作。

在上一節(jié)中講述的 CBitmapButton 類(lèi)實(shí)際上也是通過(guò)對(duì)按鈕控件進(jìn)行自繪制而實(shí)現(xiàn)的。但是在向按鈕上繪制圖像時(shí)它是采用函數(shù) BitBlt(),而不是使用函數(shù) StretchBlt(),因而造成 CBitmapButton 類(lèi)位圖按鈕上的位圖大小不會(huì)隨控件大小改變而改變。根據(jù)這一原理,我們自己創(chuàng)建一個(gè)與 CBitmapButton 作用和使用方法相似類(lèi) CBmpBton,它也可以使用四幅不同的位圖來(lái)表示按鈕不同的狀態(tài),位圖的命名原則同 CBitmapButton 完全一致。不同的是,它無(wú)需使用諸如 AutoLoad()一類(lèi)的函數(shù)來(lái)加載位圖。的其他部分同上面的 COwnerDrawBton 完全一致,只不過(guò)是函數(shù) DrawItem()的實(shí)現(xiàn)不同,下面就是類(lèi) CBmpBton 的 DrawItem()函數(shù)的實(shí)現(xiàn)代碼:

void CBmpBton::DrawItem(LPDRAWITEMSTRUCT lpDIS){ CRect rcBton;CDC *pDC;

UINT action;UINT CtrID;CString strCaption;

CBitmap m_Bitmap;CBitmap *pOldBitmap;CDC dcMem;BITMAP s_Bmp;

rcBton.CopyRect(&lpDIS-> rcItem);pDC = CDC::FromHandle(lpDIS-> hDC);state = lpDIS-> itemState;action = lpDIS-> itemAction;CtrID = lpDIS-> CtlID;

GetWindowText(strCaption);// GetDlgItemText(CtrID,strCaption);

dcMem.CreateCompatibleDC(pDC);

if(state == 16){ if(m_Bitmap.LoadBitmap(strCaption + _T(“F”))){ pOldBitmap = dcMem.SelectObject(&m_Bitmap);m_Bitmap.GetBitmap(&s_Bmp);pDC-> StretchBlt(rcBton.left,rcBton.top,rcBton.Width(),rcBton.Height(), &dcMem,0,0,s_Bmp.bmWidth,s_Bmp.bmHeight,SRCCOPY);} else { if(m_Bitmap.LoadBitmap(strCaption + _T(“U”))){ pOldBitmap = dcMem.SelectObject(&m_Bitmap);m_Bitmap.GetBitmap(&s_Bmp);pDC->StretchBlt(rcBton.left,rcBton.top,rcBton.Width(),rcBton.Height(), &dcMem,0,0,s_Bmp.bmWidth,s_Bmp.bmHeight,SRCCOPY);} else { TRACE(“必須載入一副位圖”);} } } else if(state == 4){ if(m_Bitmap.LoadBitmap(strCaption + _T(“X”))){ pOldBitmap = dcMem.SelectObject(&m_Bitmap);m_Bitmap.GetBitmap(&s_Bmp);pDC-> StretchBlt(rcBton.left,rcBton.top,rcBton.Width(),rcBton.Height(), &dcMem,0,0,s_Bmp.bmWidth,s_Bmp.bmHeight,SRCCOPY);} } else if(state & ODS_SELECTED){ if(m_Bitmap.LoadBitmap(strCaption + _T(“D”))){ pOldBitmap = dcMem.SelectObject(&m_Bitmap);m_Bitmap.GetBitmap(&s_Bmp);pDC-> StretchBlt(rcBton.left,rcBton.top,rcBton.Width(),rcBton.Height(), &dcMem,0,0,s_Bmp.bmWidth,s_Bmp.bmHeight,SRCCOPY);} } else { if(m_Bitmap.LoadBitmap(strCaption + _T(“U”))){ pOldBitmap = dcMem.SelectObject(&m_Bitmap);m_Bitmap.GetBitmap(&s_Bmp);pDC-> StretchBlt(rcBton.left,rcBton.top,rcBton.Width(),rcBton.Height(), &dcMem,0,0,s_Bmp.bmWidth,s_Bmp.bmHeight,SRCCOPY);} else { TRACE(“必須載入一副位圖 U”);} }

dcMem.SelectObject(pOldBitmap);} ★ 5--4--1 在對(duì)話(huà)框上使用圖像

本節(jié)的知識(shí),在前面的內(nèi)容中其實(shí)已基本涉及到了,現(xiàn)就總結(jié)歸納一下。在對(duì)話(huà)框上使用圖像,可采用以下幾種方法:

① 使用靜態(tài)圖像控件。采用這種方式時(shí),既可以在對(duì)話(huà)框上顯示小幅圖像作為裝飾,又可在必要時(shí)顯示整幅圖像作為對(duì)話(huà)框的背景。但在設(shè)計(jì)對(duì)話(huà)框時(shí)要首先象對(duì)話(huà)框上加入靜態(tài)圖像控件,否則其它控件就會(huì)被所顯示的圖形遮擋。這是在對(duì)話(huà)框上使用圖像最簡(jiǎn)單的方法。② 使用 CBitmapButton 類(lèi)位圖按鈕在對(duì)話(huà)框上顯示圖像。一般很少采用這種方式來(lái)顯示圖案。但在某些特殊情況下時(shí),例如要求對(duì)鼠標(biāo)指針的移動(dòng)具有感應(yīng)功能時(shí),這是最簡(jiǎn)單易行的方法。示例可見(jiàn) P112 5—2—3 CBitmapButton 類(lèi)位圖按鈕。③ 重載對(duì)話(huà)框的 OnPaint()函數(shù)。在 OnPaint()函數(shù)中進(jìn)行所需的繪圖操作。這通常是在對(duì)話(huà)框上顯示作為背景的位圖的最好方式,不會(huì)出現(xiàn)背景圖案將對(duì)話(huà)框上的其它控件遮擋住的情況。同使用 CBitmapButton 類(lèi)位圖按鈕一樣,利用這種方法能夠?qū)崿F(xiàn)像“金山詞霸”那樣有限的 Skin 效果。示例可見(jiàn) P108 5—5—1 從資源中讀取位圖。

④ 使用 Microsoft Forms 2.0 Image ActiveX 控件。這是在對(duì)話(huà)框上顯示真彩色圖像最簡(jiǎn)單的方式。但也不要認(rèn)為這種方法盡善盡美,使用該方法有可能在這臺(tái)機(jī)器上顯示的圖像精美絕倫,而在那臺(tái)機(jī)器上就一塌糊涂。

在上述的方法中,只有最后兩種具有顯示真彩色圖像的能力,使用方法④并不是太可靠;使用方法③因?yàn)樯婕暗?DIB 文件的讀取又顯得略為復(fù)雜。實(shí)際上,并不是只有采用真彩色圖像才能取得華麗的界面效果,而且大量的采用真彩色圖像會(huì)導(dǎo)致程序過(guò)于龐大。一種很好解決方法是使用經(jīng)過(guò)色彩抖動(dòng)的 256 色圖像來(lái)代替真彩色圖像。作為對(duì)讀者的一個(gè)建議,抓圖工具 HyperSnap-DX 其實(shí)是進(jìn)行色彩抖動(dòng)及圖像縮放的一個(gè)極好工具。

第二篇:MFC實(shí)踐總結(jié)

mfc編程實(shí)驗(yàn)總結(jié)報(bào)告 知識(shí)總結(jié)+個(gè)人心得 2011年暑期mfc編程實(shí)驗(yàn)報(bào)告 mfc編程實(shí)驗(yàn)個(gè)人總結(jié)報(bào)告

一、mfc類(lèi)、函數(shù)等知識(shí)小結(jié):

1、settimer(1, m_intlevel, null);在mfc程序中settimer被封裝在cwnd類(lèi)中,調(diào)用就不用指定窗口句柄了于是settimer函數(shù)的原型變?yōu)椋? uint settimer(uint nidevent,uint nelapse,void(callback export *lpfntimer)(hwnd,uint ,yint ,dword))當(dāng)使用settimer函數(shù)的時(shí)候,就會(huì)生成一個(gè)計(jì)時(shí)器。函數(shù)中nidevent指的是計(jì)時(shí)器的標(biāo)識(shí),也就是名字。nelapse指的是時(shí)間間隔,也就是每隔多長(zhǎng)時(shí)間觸發(fā)一次事件。第三個(gè)參數(shù)是一個(gè)回調(diào)函數(shù),在這個(gè)函數(shù)里,放入你想要做的事情的代碼,你可以將它設(shè)定為null,也就是使用系統(tǒng)默認(rèn)的回調(diào)函數(shù),系統(tǒng)默認(rèn)認(rèn)的是ontime函數(shù)。這個(gè)函數(shù)怎么生成的呢?你需要在需要計(jì)時(shí)器的類(lèi)的生成ontime函數(shù):在classwizard里,選擇需要計(jì)時(shí)器的類(lèi),添加wm_time消息映射,就自動(dòng)生成ontime函數(shù)了。然后在函數(shù)里添加代碼,讓代碼實(shí)現(xiàn)功能。每隔一段時(shí)間就會(huì)自動(dòng)執(zhí)行一次。例: settimer(1,1000,null);1:計(jì)時(shí)器的名稱(chēng);

1000:時(shí)間間隔,單位是毫秒; null:使用ontime函數(shù)。

當(dāng)不需要計(jì)時(shí)器的時(shí)候調(diào)用killtimer(nidevent);例如:killtimer(1);killtimer(1);

2、typedef struct{};(1)struct{ int x;int y;}test1;好,定義了 結(jié)構(gòu) test1,test1.x 和 test1.y 可以在語(yǔ)句里用了。(2)struct test {int x;int y;}test1;定義了結(jié)構(gòu) test1,test1.x 和 test1.y 可以在語(yǔ)句里用了。

與(1)比,省寫(xiě) 了 test(3)typedef struct test {int x;int y;}text1,text2;此處時(shí)說(shuō)了這種結(jié)構(gòu)體(類(lèi)型)別名 叫 text1 或叫 text2,而不是定義了結(jié)構(gòu)體變量.真正在語(yǔ)句里用,還要寫(xiě): text1 test1;//定義結(jié)構(gòu)體變量

然后好用 test1.x test1.y 或?qū)?text2 test1;//定義結(jié)構(gòu)體變量

然后好用 test1.x test1.y

3、invalidate();//讓客戶(hù)區(qū)無(wú)效,即時(shí)重新繪制客戶(hù)區(qū) void invalidate(bool berase = true);該函數(shù)的作用是使整個(gè)窗口客戶(hù)區(qū)無(wú)效。窗口的客戶(hù)區(qū)無(wú)效意味著需要重繪,例如,如果一個(gè)被其它窗口遮住的窗口變成了前臺(tái)窗口,那么原來(lái)被遮住的部分就是無(wú)效的,需要重繪。這時(shí)windows會(huì)在應(yīng)用程序的消息隊(duì)列中放置wm_paint消息。mfc為窗口類(lèi)提供了wm_paint的消息處理函數(shù)onpaint,onpaint負(fù)責(zé)重繪窗口。視圖類(lèi)有一些例外,在視圖類(lèi)的onpaint函數(shù)中調(diào)用了ondraw函數(shù),實(shí)際的重繪工作由ondraw來(lái)完成。參數(shù)berase為true時(shí),重繪區(qū)域內(nèi)的背景將被擦除,否則,背景將保持不變。

4、cdc::rectangle(左上x(chóng),左上y,右下x,右下y);使用該函數(shù)畫(huà)一個(gè)矩形,可以用當(dāng)前的畫(huà)筆畫(huà)矩形輪廓,用當(dāng)前畫(huà)刷進(jìn)行填充。

函數(shù)原型:bool rectangle(hdc hdc, int nleftrect, int ntoprect, int nrightrect, int nbottomrect);

hdc:設(shè)備環(huán)境句柄。

nleftrect:指定矩形左上角的邏輯x坐標(biāo)。ntoprect:指定矩形左上角的邏輯y坐標(biāo)。nrightrect:指定矩形右下角的邏輯x坐標(biāo)。nbottomrect:指定矩形右下角的邏輯y坐標(biāo)。

5、cbrush:: cbrush//畫(huà)刷類(lèi) eg:cbrush brushstick(rgb(127, 127, 127));四種構(gòu)造函數(shù): cbrush();cbrush(colorref crcolor);cbrush(int nindex, colorref crcolor);cbrush(cbitmap* pbitmap);參數(shù)說(shuō)明: crcolor指定畫(huà)刷的前景色(rgb方式)。如果畫(huà)刷是陰影線(xiàn)型的,則指定陰影線(xiàn)的顏色。nindex指定畫(huà)刷陰影線(xiàn)采用的風(fēng)格,取值如下: hs_bdiagonal45度的向下影線(xiàn)(從左到右)hs_cross水平和垂直方向以網(wǎng)格線(xiàn)作出陰影 hs_diagcross 45度的網(wǎng)格線(xiàn)陰影 hs_fdiagonal 45度的向上陰影線(xiàn)(從左到右)

hs_horizontal 水平的陰影線(xiàn) hs_vertical 垂直的陰影線(xiàn) pbitmap指向cbitmap對(duì)象的指針,該對(duì)象指定了畫(huà)刷要繪制的位

圖。

構(gòu)造函數(shù)說(shuō)明:

6、messagebox(game over!);messagebox(null,text,title,button);參數(shù)title:string類(lèi)型,指定消息對(duì)話(huà)框的標(biāo)題。text:指定消息對(duì)話(huà)框中顯示的消息,該參數(shù)可以是數(shù)值數(shù)據(jù)類(lèi)型、字符串或boolean值。icon:icon枚舉類(lèi)型,可選項(xiàng),指定要在該對(duì)話(huà)框左側(cè)顯示的圖標(biāo)。button:button枚舉類(lèi)型,可選項(xiàng),指定顯示在該對(duì)話(huà)框底部的按鈕。default:數(shù)值型,可選項(xiàng),指定作為缺省按鈕的按鈕編號(hào),按鈕編號(hào)自左向右依次計(jì)數(shù),缺省值為1,如果該參數(shù)指定的編號(hào)超過(guò)了顯示的按鈕個(gè)數(shù),那么messagebox()函數(shù)將使用缺省值返回值integer。函數(shù)執(zhí)行成功時(shí)返回用戶(hù)選擇的按鈕編號(hào)(例如1、2、3等),發(fā)生錯(cuò)誤時(shí)返回-1。如果任何參數(shù)的值為null,messagebox()函數(shù)返回null。

函數(shù)原型:

messagebox.show(text,title,messageboxbuttons,messageboxicon ,messageboxdefaultbuttons)參數(shù)說(shuō)明:

(1)text:必選項(xiàng),消息框的正文。

(2)title:可選項(xiàng),消息框的標(biāo)題。(3)messageboxbuttons:可選項(xiàng),消息框的按鈕設(shè)置,默認(rèn)只顯示【確定】按鈕。ok――確定 okcancel――確定和取消 abortretryignore――終止、重試和忽略 yesnocancel――是、否和取消 yesno――是和否 retrycancel――重試和取消

(4)messageboxicon:對(duì)話(huà)框中顯示的圖標(biāo)樣式,默認(rèn)不顯示任何圖標(biāo)。

question――問(wèn)號(hào) information、asterisk――i號(hào) error、stop、hand――錯(cuò)誤號(hào) warning、exclamation――!號(hào) none――不顯示任何圖標(biāo)

(5)messageboxdefaultbuttons:可選項(xiàng),對(duì)話(huà)框中默認(rèn)選中的按鈕設(shè)置。

defaultbutton1――第1個(gè)button是默認(rèn)按鈕 defaultbutton2――第2個(gè)button是默認(rèn)按鈕 defaultbutton3――第3個(gè)button是默認(rèn)按鈕

7、memcpy(拷貝目的地,拷貝對(duì)象,拷貝長(zhǎng)度);包含在頭文件#include

函數(shù)原型:

extern void *memcpy(void *destin, void *source, unsigned n);功能:

由source指向地址為起始地址的連續(xù)n個(gè)字節(jié)的數(shù)據(jù)復(fù)制到以destin指向地址為起始地址的空間內(nèi)。eg: int a=5,b=9;memcpy(a,b,sizeof(a));//將b按位拷給a;說(shuō)明:

1.source和destin所指內(nèi)存區(qū)域不能重疊,函數(shù)返回指向destin的指針。2.與strcpy相比,memcpy并不是遇到

主站蜘蛛池模板: 日本国产一区二区三区在线观看| 国产精品久久久久久久久绿色| 欧美高清一区三区在线专区| 久久天天婷婷五月俺也去| 国产l精品国产亚洲区久久| 18黑白丝水手服自慰喷水网站| 中文字幕人成无码免费视频| 99热爱久久99热爱九九热爱| 丰满少妇人妻hd高清果冻传媒| 亚洲色婷婷久久精品av蜜桃久久| 国产精品色婷婷亚洲综合看片| 国产永久免费观看的黄网站| 久久99精品国产免费观观| 国产高清av首播原创麻豆| 国产97色在线 | 免| 苍井空一区二区波多野结衣av| 成人小说亚洲一区二区三区| 欲色天天网综合久久| 久久精品国产精品国产精品污| 成人精品一区二区三区中文字幕| 亚洲aⅴ无码国精品中文字慕| 亚洲日本中文字幕乱码中文| 国产三级久久久精品麻豆三级| 久久婷婷五月综合国产尤物app| 无码h片在线观看网站| 99蜜桃在线观看免费视频网站| 亚洲一二三无人区分别是哪| 人妻无码久久一区二区三区免费| 手机国产丰满乱子伦免费视频| 综合伊人久久在| 狠狠躁天天躁无码中文字幕| 曰本丰满熟妇xxxx性| 精品免费一区二区在线| 激情国产一区二区三区四区小说| 蜜臀av久久国产午夜福利软件| 欧美熟妇xxxxx欧美老妇不卡| 大地资源中文第三页| 丰满熟妇乱子伦| 不卡一卡二卡三乱码免费网站| 一本色道久久综合亚洲精品| 亚洲中文有码字幕日本|