★ 5--2--1 圖標按鈕
圖標按鈕可謂是按鈕控件使用圖像最簡單的方式,除此之外圖標按鈕的優點還在于顯示在按鈕上的圖標能夠使用透明色,因而不必再去為處理非矩形圖像在按鈕顏色發生變化時邊緣顏色的處理而費心。不過也正是使用圖標導致了圖標按鈕的天生弱點。圖標太小了,僅僅才 32×32 像素大小,在有的場合僅靠使用這么小的圖像就有些顯得力不從心了。
在講圖標按鈕如何使用之前,先得告訴讀者句柄的概念。句柄是什么?很多教科書上都這樣定義:句柄是一個用于代表對象的 32 位整型值。不過這對于很多初學者而言,并不是太好理解。其實也可以將未賦值的句柄理解為一個指向“空白”(void *)的指針,事實上也如此,在 Winnt.h 中,句柄就是如此被聲明的: void *; 當句柄被賦值之后,它就成為指向某個特定位置的指針,即代表了某個特定的對象。之所以在現在提及句柄,是因為句柄是 編程中的一個關鍵性概念。盡管在前面除第三章外的內容中很少涉及它,不過在下面的學習中我們將會很頻繁的使用到句柄。
技術概要:
使用圖標按鈕很簡單,大的步驟僅僅就三步:
①.從外部導入一個圖標或自己創建一個圖標作為資源。
②.從資源中載入所要使用的圖標。
③.在要使用圖標的按鈕上設置圖標。
具體實現:
■第一步導入圖標沒有什么特別之處,同前面 2.2 節中使用靜態圖像控件導入位圖是非常類似的。無非就是使用 菜單上的 命令,導入或創建一個圖標即可。
■第二步載入圖標就涉及到一些細節問題了。使用函數 () 載入圖標。因為() 是類 的成員函數,同時函數 () 返回所載入圖標的句柄。所以我們采用以下方法來調用函數 ():
= () -> ();
當然,在該語句之前還必須要有對圖標句柄 的定義:
HICON ;
■第三步為按鈕設置圖標了,這通過調用函數 () 來實現。同時不要忘記,還須在使用圖標的按鈕的 設置中設置 Icon 屬性,指明該按鈕是一個圖標按鈕。因為函數 () 為類 的成員函數,可以通過兩種方法來調用該函數。一是通過 類對象來調用 (),如下面代碼:
.(); // 為一個 類對象。
二是先由函數 () 獲得一個指向 CWnd 對象的指針,再通過強制類型轉換將該指針轉換為一個指向 類對象的指針。進而通過該指針來調用函數 ()。具體實現代碼如下:
CWnd *pWnd = ();
*pBton = ( *) pWnd;
pBton -> ();
既然有第一種較為簡便的方法為按鈕設置圖標,為何還要提及第二種方法呢?因為并不是在任何情況下都會有 類對象的,例如對于一組單選按鈕。只能為它們定義一個 類對象,如果使用該對象來調用函數 (),則只能在設置了 Group 屬性的那個單選按鈕上設置圖標。所以要達到在一組單選按鈕中分別設置不同圖標的目的,就只有使用第二種方法。
盡管在現在的 編程中,資源句柄數多得相對于我們而言幾乎是無限的,但最好在使用完資源句柄后及時的把它們刪除掉。上面所講述的方法不僅適用于 Push ,而且同樣適用于 Radio 、Check Box 和 Group Box。
★ 5--2--2 位圖按鈕
圖標按鈕雖有著種種優點,但它能顯示的圖像實在是太小了。在有的場合顯然就不適用了。位圖按鈕可以在按鈕表面顯示一幅位圖而不再是一個小小的圖標。但是因為在位圖中不能使用透明色,因而當顯示的位圖不為矩形時,就得為位圖中非矩形部分的背景色動一番腦筋了。因為存在著用戶改變按鈕表面顏色,也就是位圖背景色的可能性。可以用透明位圖的技術來解決這一難題,這將在后面 5.7 實現具有透明性的位圖中講述。
技術概要:
位圖按鈕的使用的大致步驟同圖標按鈕基本相似,也是以下三個步驟:
① 從外部導入一個位圖或自己創建一個位圖作為資源。
② 從資源中載入所要使用的位圖。
③ 在要使用位圖的按鈕上設置位圖。
具體實現:
■第一步從外部導入一個位圖作為資源同使用圖標按鈕時是完全一致的,在此就不詳細講述了。
■第二步中,利用函數 () 從資源中載入位圖。函數 () 為一個 API 函數,定義如下:
(
, // of
// of name
);
所以,為達到載入位圖的目的,不僅要定義一個位圖句柄 :
;
而且還要定義一個應用程序實例句柄 ;:
;
并調用函數 () 以獲得當前的應用程序實例句柄,代碼如下:
= ::();
只有在聲明并獲得了當前的應用程序句柄后,才能使用以下語句載入位圖:
= ::(,"BMP1");
注意,在函數 () 中的第二個參數為資源名,而非資源 ID。因為資源名是一個字符串,而資源 ID 則是一個整型量。所以在創建或導入位圖后,為該位圖資源命名時要加上雙引號以表示這是一個資源名。如右圖 5-2:
■在第三步中,為要使用位圖的按鈕設置位圖,方法與圖標按鈕完全相同。首先是要在使用位圖的按鈕的 設置中設置 屬性,指明該按鈕是一個位圖按鈕。然后再調用 類函數 () 為按鈕設置位圖。代碼如下:
// 為一個 類對象。
.();
或
pWnd = ();
pBton = ( *) pWnd;
pBton -> ();
同圖標按鈕一樣,使用位圖不局限于 Push ,而且同樣適用于 Radio 、Check Box 和 Group Box。同時,最好在使用完位圖句柄后及時的將它刪除掉。
★ 5--2--3 類位圖按鈕
前面所講述的圖標及位圖按鈕最大的不足在于,無論當按鈕控件處于何種狀態,按鈕上所顯示的圖案總是一成不變的,相比之下那些隨著操作而實時改變圖案的按鈕就具有更加生動的效果。MFC 庫為我們捉供了一個這樣的類 。利用這個類,我們可以為一個按鈕設計四幅不同位圖、分別用于正常狀態、按下狀態、獲得輸入焦點和無效時。這樣,隨著按鈕狀態的改變人物圖標小按鈕矢量圖,位圖也隨之切換,這樣就使按鈕呈現出很強的動感效果。令人高興的是,類 將很多操作的細節都封裝了起來,因而我們能夠很方便的達到上述目的。由于以上原因, 類位圖按鈕有著比圖標按鈕和位圖按鈕更為廣闊的使用范圍。在一般情況下,都將 類位圖按鈕稱作是位圖按鈕,而將真正的位圖按鈕給忽略了。
類位圖按鈕的缺點同位圖按鈕是一致的,都是在對透明色的處理上。還有一個比較嚴重的問題是 類位圖按鈕是將位圖按原始大小繪制在按鈕上,而不是隨按鈕大小而縮放位圖。這在平時不會導致任何問題,但若是在 中更改了顯示字體的大小,則對話框及上面的按鈕控件大小也隨之改變,但位圖按鈕上的位圖卻保持原有大小不變,這樣就會在外觀上造成嚴重的問題。盡管有以上問題的存在, 類位圖按鈕還是具有很大的實用價值,因為付出很少的代碼就可以得到生動形象的圖形效果。、下面就講述 類位圖按鈕的使用方法(以下均簡稱為位圖按鈕)。
絕大數情況下,使用位圖按鈕只需四個步驟:
● 第一步:在要使用位圖的按鈕的 設置中設置 Owner Draw 屬性
● 第二步:創建或從外部導入至少一幅至多四幅位圖。位圖按鈕所使用的位圖顏色最多可達 256 色,但對于 256 色的位圖不能通過剪貼的的方式來創建。而必須使用導入的方式來創建。若該按鈕控件的 (標題)為 ,則將這四幅位圖的 ID 分別設定為 “”、“”、“”、“”分別對應于按鈕的正常狀態、按下狀態、獲得輸入焦點狀態和無效狀態。注意,只有在正常狀態顯示的位圖是必須的,其它狀態的位圖都是可選的;還有就是代表位圖的 ID 都必須加上雙引號并且大寫(如下圖 5-3)。實際上,加上雙引號就表示該資源是以字符串常量來標識。
● 第三步:在使用位圖按鈕的類的類定義文件中聲明 類對象: ;
● 第四步:在對話框的 () 函數中通過 類對象調用函數 () 自動加載位圖: .(,this);
經過以上四個步驟,一個位圖按鈕就創建好了。在運行中人物圖標小按鈕矢量圖, 類會自動根據按鈕的狀態顯示對應的位圖。利用位圖按鈕技術,再加上一點鼠標感應技術,就很容易做出像網頁按鈕那樣的在鼠標經過時加亮的動態效果。也能輕易的實現像 Word 中那樣的平面按鈕。這些將在后面的章節中講述。
需要說明的是, 類位圖按鈕僅限于在 Push 使用。在默寫情況下,我們可能需要動態創建位圖按鈕,在動態創建位圖按鈕時,不能使用函數 () 加載位圖,而要使用函數 () 來加載位圖。動態創建位圖按鈕主要有以下幾個步驟:
●第一步:為要創建的控件分配一個 ID 值。
●第二步:定義一個 類對象。
●第三步:由該對象調用函數 () 創建位圖按鈕,并調用函數 () 加載位圖。在調用函數 () 調整按鈕控件的大小以適應位圖。
● 第四步:加入對新創建按鈕的消息處理。