|
我们知道,C++Builder没有自画菜单,但可以调用API函数::SetMenuItemInfo()来改 5 |1 W5 M1 r1 z
变菜单类型,达到自画菜单的目的。下面的例子演示了如何使用自画菜单。当鼠标位于菜单 7 r5 K, ~! [+ I0 f1 \( j# E
上拾,菜单项将凸出来。(黑体字为添加的代码)
9 Q' Z6 e# I e. V; H0 e6 D( x( ] z9 P ( f: q7 m$ O8 i0 `+ M; S+ A6 d3 ~8 n
//头文件 8 M( K; f% A' V& r6 U6 ?
//------------------------------------------ + O9 @7 r# M/ p
#ifndef TestMenuH $ u) d/ {) ?4 z
#define TestMenuH ' Q& b! y- f1 R# s0 N& f8 s% x A
//----------------------------------------- " G5 ]4 d7 [2 i2 S" W" M
#include Classes.hpp
- ~& a n/ V9 C" Z5 G Q1 K#include Controls.hpp + d3 k9 N) T/ g; S, l
#include StdCtrls.hpp
, R! h6 T2 s( c0 z% y* v#include Forms.hpp
6 c5 L1 w4 z! S' J- K2 c#include Menus.hpp//--------------------
$ S' n! Q0 N% m5 V6 W3 g, Y6 v
6 p7 c2 X1 A6 K: kclass TForm1 : public TForm
6 N, a0 {2 M: _: A6 y% q3 ?# u{ ' j! F" u: J8 g: F Z$ S, V
__published: // IDE-managed Components
t- S" }9 ^7 V) l! u& `TMainMenu *MainMenu1; 0 V J/ K A- `! f" C" {7 Y6 k% a
TMenuItem *aaa1;
! z$ w% }# ]. _0 f2 a& OTMenuItem *aaaaaaaaa1; - R3 X6 \% P1 c3 d3 n9 i1 g
TMenuItem *ccc1;
2 U' a$ d7 a4 h/ |: m7 cTMenuItem *ddd1; 0 N5 j( F8 N$ h! T) E
TMenuItem *eee1;
# i2 `4 T9 q+ j) l0 Q- uTMenuItem *ddsds1; # Y" }' ]1 E- J8 k. `
TMenuItem *fcdfsss1;
9 [, T+ w" {' E+ O3 ZTMenuItem *dddddddd1;
. e# @% t4 H* P3 rvoid __fastcall FormCreate(TObject *Sender); 2 e0 D( N! ]* T2 `# _
private: // User declarations 0 B$ U: p" y7 p0 G$ j$ p
void __fastcall Modify(TMenuItem *pMenuItem);
% K @4 k3 [) E- s6 j B# i' Vprotected :
4 d" }; ?9 T7 v% S( r" AMESSAGE void __fastcall CNMeasureItem(TWMMeasureItem Msg);//增加响应消息
9 K. N! g H2 IMESSAGE void __fastcall CNDrawItem(TWMDrawItem Msg);
/ n ~* B4 q; \, [. b1 ?- {2 ?public: // User declarations
9 A$ B3 R1 }1 |* J3 m! k; z__fastcall TForm1(TComponent* Owner); , Z/ C( A1 g# J/ W
BEGIN_MESSAGE_MAP//添加消息映射
# @% _1 Q7 m% k- V. ]) [3 xVCL_MESSAGE_HANDLER(WM_MEASUREITEM, TWMMeasureItem, CNMeasureItem); , G: k `8 _" y/ N
VCL_MESSAGE_HANDLER( WM_DRAWITEM, TWMDrawItem, CNDrawItem);
) B5 j, M( K% [) G; YEND_MESSAGE_MAP(TForm); % v6 ]5 n: l& Q' D
}; 4 e) _# j; f# L1 T
//---------------------------------------------------------------------------
8 {- m8 D; n$ I8 j a3 Gextern PACKAGE TForm1 *Form1; % k, `; w B& D b; ~
//--------------------------------------------------------------------------- 6 b$ |& }" j5 N0 T$ Y, v2 [) w
#endif
! V' g5 k+ I! l# X
* v3 i8 ^1 R& u1 Z2 H* c//实现文件
& T4 o4 n* v+ x5 f3 a, W6 c//---------------------------------------------------------------------------
% j3 s X- F+ {, P. J3 |#include vcl.h
% n w/ T2 m% i#pragma hdrstop
$ j* E3 O8 E) J! e* B* \- Q0 A: Z 2 i0 u/ `/ R# _
#include TestMenu.h
* P! M2 {7 c2 P! s9 I/ N: Y//--------------------------------------------------------------------------- H8 x5 C3 ]2 g5 s% O. ]" O1 }# b
#pragma package(smart_init)
- r" U7 X8 }6 |2 `, ]& J#pragma resource *.dfm , R; ]% c7 ]$ Y& F1 ]
TForm1 *Form1;
) `5 _* D8 K4 [1 V: C//---------------------------------------------------------------------------
- \8 F" c& ^8 T; u7 U4 i# S0 Y& W* ^3 Q__fastcall TForm1::TForm1(TComponent* Owner) + K% `3 S: `& c% D
: TForm(Owner)
: ?' V% r9 ]- v0 N6 q{ ! M7 \" C) H" v5 S% k6 L
}
9 n; l, g. @) G2 |//---------------------------------------------------------------------------
4 `$ ^1 }; n: E, ]- M' m1 f g- m3 a- W6 c9 o ~( J% j" d, m$ ^
void __fastcall TForm1::Modify(TMenuItem *pMenuItem) 2 J) I; j2 O2 m) l
{//修改缺省属性 $ g' g4 Q) ]5 C0 }3 w+ c
for(int i=0;ipMenuItem-Count;i++) 3 |, Q7 _2 J$ }7 F5 G3 a: P- W
{
( w) | u/ X, o9 G: r8 vMENUITEMINFO mii= 2 t; |' d5 [ y& G
{
6 `0 @* i1 V8 N7 Dsizeof(MENUITEMINFO), 0 z* p1 X- x8 ?1 Q7 c4 E- n* E0 s
MIIM_TYPE|MIIM_DATA ,//改变类型和数据
/ F8 O1 y( X4 T9 hMF_OWNERDRAW,0,0,0,0,0,DWORD(pMenuItem-Items-Handle), 3 h& S$ ]" f- d, G& Y
//把菜单项的句柄赋给32位数据
2 {0 Y& h* Y6 J0, 5 }9 A3 D. X* H5 ~0 o# a; h
0,
& a9 E, J' D9 d# p}; + [% A8 m F" A. c
if(pMenuItem-Items-Caption!=-)//如果不是间隔线 ' @2 P" }0 W: B. l
::SetMenuItemInfo(pMenuItem-Handle,i,TRUE,mii);
- ^. w* d5 I4 Q. [' v$ Kif(pMenuItem-Items-Count)//如果含有子菜单 . o: v( ?7 M; L( M
Modify(pMenuItem-Items); 7 g4 u8 B+ J2 O& ~
} 3 _7 S. J1 d4 R9 f" @0 P6 l
! _4 M* p/ a( O2 u& K) n% V
} , n: ]7 w$ r, k8 g
void __fastcall TForm1::FormCreate(TObject *Sender)
8 u* H, O+ w, _# ]{ + w3 V: ^: ^" K! X
for(int i=0;iMainMenu1-Items-Count;i++)
1 k$ q+ y0 d1 J3 Q% p- Y{ 9 a1 _7 S+ N0 p3 h/ H. Y
Modify(MainMenu1-Items-Items); ! A* w" b. ^1 u6 T/ b7 r- ~
} + r6 ~6 Z6 L3 w, e
DrawMenuBar(Handle);
+ S0 u8 J: X) H" L0 t} * T( W( e' L' h
//---------------------------------------------------------------------------
. {2 v* l w4 j' ~void __fastcall TForm1::CNMeasureItem(TWMMeasureItem Msg)
3 X) @2 u' `/ M- V( i. H4 j2 n+ l{//设置菜单大小 ; @+ Z1 F# g4 K z
TMenuItem *pItem=MainMenu1-FindItem(Msg.MeasureItemStruct-itemData,fkHandle); . `* j6 v5 d( \+ q* F- M* f
Msg.MeasureItemStruct-itemWidth =pItem-Caption.Length()*8+40;
3 U; `: a1 c5 u2 o2 ?0 n$ {* ]Msg.MeasureItemStruct-itemHeight = 20;
: Y5 ]5 Q) Q$ Y}
4 ?$ Q- \3 [% a+ E9 ]( xvoid __fastcall TForm1::CNDrawItem(TWMDrawItem Msg)
9 m/ I3 h c1 F$ \{//画出菜单
: J1 }9 m: W+ \' _2 O: z6 p$ tTMenuItem *pItem=MainMenu1-FindItem(Msg.DrawItemStruct-itemData,fkHandle); 5 i: V9 c2 Y2 I# B# B, X
TCanvas *pCanvas=new TCanvas; 7 {) z1 i/ `& V6 P# V z& _
pCanvas-Handle=Msg.DrawItemStruct-hDC;
+ B9 Y& U7 X/ ?( nRECT r=Msg.DrawItemStruct-rcItem;
m S9 o7 z9 R7 r1 e( i& s; k) mpCanvas-Brush-Color=clBtnFace; & k# ^5 O' D9 y
RECT r1=r;
; [- k2 m6 Q% u3 k% p* l4 ], m. _r1.right+=1; . V1 ]. a6 F8 b
r1.bottom+=1;
1 R- l. v" `+ Br1.top-=1; ! {) R5 L$ r1 a: [- y* V2 e. Y
r1.left-=1;
( A) M3 h) I, @5 A3 e, s% |" {$ cpCanvas-FillRect(r);
; x. t* A7 b9 S( \, u: t::SetBkMode(pCanvas-Handle,TRANSPARENT);
& h# |+ f$ R. d) lpCanvas-TextOut(r.left+10,r.top+2,pItem-Caption);
3 D+ g- F6 I1 d4 w" a; T1 n" s# ~; Rr.right-=1; . |& T7 h/ M. k" T& A* x
r.bottom-=1;
6 ^7 R4 v* G" Mif(Msg.DrawItemStruct-itemAction == ODA_SELECT
) o6 i8 @6 k9 [2 ]5 K' IMsg.DrawItemStruct-itemStateODS_SELECTED ) 3 R' J; |) |; R+ C; p1 x3 G: G
{
% O7 Q% @& S% L, tpCanvas-Pen-Color=(TColor)(RGB(255,255,255)); ' T" N$ @* A0 \# x5 L7 o6 h+ A
pCanvas-MoveTo(r.right,r.top); 2 z" d+ F( M$ r& @+ y9 S4 Z0 \+ R: ?7 y
pCanvas-LineTo(r.left,r.top); & X0 ^( w' t3 Y+ u+ {0 Q$ X
pCanvas-LineTo(r.left,r.bottom);
/ y( {' I% s5 u) q0 ^pCanvas-Pen-Color=(TColor)(RGB(128,128,128));
9 X! F W, E. j! q* N* w apCanvas-LineTo(r.right,r.bottom);
6 w, @4 g% Z( f( }pCanvas-LineTo(r.right,r.top); u) ^7 n) d! H% \) Y+ x5 V
} ( o) E$ N+ P Y; k$ q) t
0 q2 B/ n4 Z: f0 _) N% h} |