?? 10.3 顏色對話框.txt
字號:
10.3 顏色對話框
顏色對話框類似于Windows提供的畫圖程序中,選擇【顏色\編輯顏色...】菜單項后出現的對話框,
如圖 10.12所示。利用顏色對話框,可以讓用戶選擇一種顏色,程序隨后按照此顏色創建繪圖所需
的畫筆。
如圖 10.12所示的顏色對話框看起來比較復雜。實際上, MFC為我們提供了一個類: CColorDialog,
可以很方便地創建這樣的一個顏色對話框。該類的派生層次結構如圖 10.13所示。由此,可以知道
顏色對話框也是一個對話框。
" ‘ I 373
第10
.盯
;"顏色基本'色咂}
自定義'色電):
廣廣廣「廣廣廣廣
「rrrr廣廣廣
| 穆.)i;自定義MtM!.仰自~ I 融|純色也】礎ω~.(\!):~
黯 l一旦」事蛐自定增ê.f&I I
圖 10.12畫圖程序提供的顏色對話框
圖 10.13 CColorDiaJog類的派生層次結構圖
CColorDialog類的構造方法如下所示:
CColorDialog(clrlnit = 0 , DWORD dwFlags = 0 , CWnd* pParentWnd = NULL);
該構造函數具有三個參數,含義分別如下所述:
. clrlnit
指定默認的顏色選擇。默認是黑色。
. dwFlags
指定一組標記,用來定制顏色對話框的功能和它的外觀。
. pP缸entWnd指向顏色對話框父窗口或擁有者窗口的指針。為了在 Graphic程序中增加顏色對話框
的顯示,首先為該程序增加一個菜單項,當用
戶選擇此菜單項時,程序將顯示顏色對話框。將這個新菜單項放置在己有的"繪圖"子菜單下,并將
其E設置為IDM_COLOR, Caption設置為顏色。接著為其增加一個命令響應,井選擇 CGraphicView
類對此菜單項命令做出響應。然后在此響應函數中添加顯示顏色對話框的代碼,結果如例 10-12所
示。
~IJ 10-12
void CGraphicView: :OnColor()
CColorDialog dlg ;
dlg . DoModal() ;
運行 Graphic程序,選擇【繪圖飛顏色】菜單項,即可以看到出現了一個顏色對話框,并且可以看
到在該對話框左邊顏色塊的黑色塊上有一個黑色的邊框,說明默認選擇的是黑色,這和我們剛才在
畫圖程序中所看到的顏色對話框是一樣的。
下一步要做的事情就是應該將用戶選擇的顏色保存下來。 CColorDialog類有一個 CHOOSECOLOR結構
體類型的成員變量 : ID_cc oCHOOSECOLOR結構體的定義如例 10-13所示。
例 10-13
typedef struct { DWORD lStructSize; HWND hwndOwner ;
HWNDh工 nstance ;
COLORREF rgbResult ;
COLORREF *lpCustColors;
DWORD Flags ;
LPARAM lCustData;
LPCCHOOKPROC lpfnHook;
LPCTSTR lpTemplateName;
} CHOOSECOLOR,女 LPCHOOSECOLOR ;
當用戶單擊顏色對話框上的【 OK】按鈕后,這個結構體中的 rgbResult變量就保存了用戶選擇的顏
色。因此,在程序中通過這個變量就可以獲得用戶選擇的顏色。.
在Graphic程序中,為了保存用戶選擇的顏色,為 CGraphicView類再增加一個 COLORREF類型的私有
成員變量 : ffi_clr,井在 CGraphicView類的構造函數中將其初始化為紅色,即添加下面這行代碼:
ffi_clr=RGB(255 , O, O) ;
然后在 OnColor函數中進行判斷,如果用戶單擊的是【 OK】按鈕,那么就將用戶選擇的顏色保存下
來。修改后的代碼如例 10-14所示。
例 10-14
戶」在
void CGraphicView: :OnColor()
--TIA -l=ld dD14o
ci{ DK αdqd
O(ODroa=o---gM;o
d a 14
L
m_clr=dlg .m_cc . rgbResult;
當用戶選擇顏色后,隨后進行的繪圖操作都應用此顏色來繪制,也就說應該按此顏色創建繪圖用的
畫筆。所以,修改 CGraphicView類 OnLButtonUp函數中己有的創建畫筆的代碼,將用戶當前選擇的
顏色(即 ffi clr變量)傳遞給 CPen構造函數的第三個參數。另外,還需要修改該函數中繪制點圖形
的代碼,應該用用戶當前選擇的顏色來設置像素點的
"‘I 375
第10
顏色,修改后的OnLButtonUp代碼如例 10-15所示,其中加灰的代碼為進行了修改的代碼。
例 10-15
void CGraphicView :: OnLButtonUp(UINT nFlags , CPoint poi口t)
/ / TODO : Add your message handler code here and/ or call default CClientDC dc(this); CPen
pen(m_nLineStyle,m_nLineWidth, m_clr); dc . SelectObject(&pen) ; CBrush *pBrush=CBrush: :
FromHandle( (HBRUSH)GetStockObject(NULL_BRUSH)); dc . SelectObject(pBrush);
switch(m_nOraνI'ype)
{
case 1:
dc.SetPixel(point,m_c工r) ;
break;
case 2:
dc . MoveTo(m-ptOrigin);
dc . LineTo(point) ;
break;
case 3:
dc . Rectangle(CRect(m-ptOrigin,point)) ;
break;
case 4:
dc . Ellipse(CRect(m-ptOrigin , point)) ;
break;
}
CView: :OnLButtonUp(nFlags , point);
運行Graphic程序,單擊【繪圖飛顏色】菜單項,打開顏色對話框,選擇某種顏色,然后進行繪圖操
作,可以發現這時所繪制的圖形邊框的顏色就是剛才選擇的顏色。
但是當再次打開顏色對話框時,它默認選擇的仍是黑色,而不是剛才選擇的顏色。這時,我們自然
就會想到應該像上面的處理一樣,將用戶選擇的顏色(即 CGraphicView類的 mJlr變量保存的顏色
值〉設置回顏色對話框對象,因此,修改 CGraphicView類的 OnColor函數,添加如例10-16所示代
碼中加灰顯示的那行代碼。
例10-16
vo工d CGraph工cView: :OnColor ( )
CColorDialog dlg; dlg .m_cc .rgbResult=m_clr;
if(工OOK==dlg .DoModal())
m_clr=dlg.m_cc . rgbResult;
376 I ~~~
VC++深λ詳解
再次運行Graphic程序,先選擇一種顏色,然后進行圖形的繪制,可是當再次打開顏色對話框時,將
會發現結果仍不對,默認選中的顏色仍是黑色。
實際上,如果想要設置顏色對話框初始選擇的顏色,則需要設置該對話框的 CC RGBINIT標記,這個
標記可以在創建顏色對話框時通過其構造函數的第二個參數來設置,也可以在該對話框創建之后,
設置其m cc成員變量的Flags成員。這里,采用后一種方法,修改CGraphicView類的OnColor函數,
添加如例 10-17所示代碼中加灰顯示的那行代碼。
例 10-17
void CGraphicView: :OnColor()
CCol orDialog dlg ;
dlg.m_cc.Flags=CC_RGB工NIT;
dlg .m_cc .rgbResult=m_clr;
if (IDOK==dlg.DoModal())
.
m_clr=dlg.m_cc .rgbResult;
再次運行Graphic程序,選擇【給圖\顏色】菜單項,出現一個非法操作提示對話框,如圖 10.14所
示。[電a牛二~二itLTJDEbwiibmry j咽··E
Debt啕Asser蝕111 Failed!
何咱酬:O:\VC++瀕入·理I\CHAPTERI叭,G;-制削減明I\G;-砸在劇@同e: clgclr.cpp Lir晴:73
For時ormat陽、 onhc酬YOtWPI'(9'am can CeI ose eI\眉錮,蝕m faiUe,餌"世回響劇aI C++doan
帽、tatb.on眉目!f1:s.
{防@篤篤 Retryto由戰唱。胃部lPkat陽、〉
旦巳J_旦ι」
圖 10.14非法操作提示對話框
實際上,當在創建CColorDialog對象dlg時,它的數據成員m cc中的F1ags成員已經具有了一些初始
的默認標記。當我們將CC RGBINIT標記直接賦給Flags成員時,就相當于將F1ags成員初始默認的標
記都去掉了。
如果讀者認為這種解釋不太可信,可以構造一個 CString對象,然后利用該對象的 Fonnat函數將初
始的F1ags成員的值格式化,并用 MessageBox顯示輸出,記住輸出的數值。然后在VC++編輯窗口中,
在CC RGBINIT符號上單擊鼠標右鍵,從彈出的快捷菜單中選擇【GoToDe白創onOfCC RGB時π】菜單項,
定位到該符號的定義處 CCOMMDLG.H文件中),可以看到F1ags成員可能取的值 (代碼如例 10-18所
示,并且F1ags的取值可以通過或操作對這些數值進行組合),然后與剛才MessageBox顯示的數值比
對一下,就可以
‘...... 1377
第 10
知道Flags的取值了。
11IJ 10-18
#define CC RGBINIT OxOOOOOOOl
#define CC FULLOPEN Ox00000002
#define CC PREVENTFULLOPEN Ox00000004
#define CC SHOWHELP Ox00000008
#define CC_ENABLEHOOK Ox00000010
#define CC ENABLETEMPLATE Ox00000020
#define CC ENABLETEMPLATEHANDLE Ox00000040 #if(WINVER >= Ox0400) #define CC SOL工 DCOLOR
Ox00000080 #define CC ANYCOLOR Ox00000100 #endif /* WINVER >= Ox0400 */
為了進一步驗證 Flags的初始取值,可以根據得到的數值,再換成相應的符號值,井賦給Flags成員,
再運行程序,看看顏色對話框是否能夠正確地顯示就可以驗證這一點了。
小技巧:在 VC I I開發環境中,同時按下 Ctrl鍵和 Tab鍵,就可以切換到
E
下一個窗口。
.
通過上述分析,可以知道,這里不能給 Flags標記直接賦值,應利用或操作 (1)將 CC RGBINIT標記
與 Flags先前的標記組合起來,即修改后的代碼如下所示 :
dlg.m_cc.Flags 1= CC_RGBIN工 T;
再次運行 Graphic程序,打開顏色對話框,可以看到初始選擇的就是紅色。接著,選擇其他某種顏
色并關閉該對話框。然后再打開顏色對話框,這時就可以看到現在選中的是先前選擇的顏色了。
另外. Flags成員的取值還有一個常用標記: CC_FULLOPEN.該標記的作用就是讓顏色對話框完全展
開。將上面那條代碼修改為:
dlg.m_cc.Flags 1= CC_RGBINIT 1 CC_FULLOPEN;
再次運行 Graphic程序,打開顏色對話框,這時可以看到這個顏色對話框處于完全展開的狀態。
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -