|
我们知道,C++Builder没有自画菜单,但可以调用API函数::SetMenuItemInfo()来改 " A8 [) V+ k: r& M- p
变菜单类型,达到自画菜单的目的。下面的例子演示了如何使用自画菜单。当鼠标位于菜单 & ?7 s, x: B/ x% e9 p0 \
上拾,菜单项将凸出来。(黑体字为添加的代码)
2 l' b- ^' L# f' D% r( c: b& J1 P
8 |6 s3 y, l7 O//头文件
9 G. u3 C( k6 G* g8 B//------------------------------------------
: \5 h! F3 e" p#ifndef TestMenuH + i* F, H0 l. }: O$ W; d2 a
#define TestMenuH
0 w0 ]8 i( O% R: n l5 d* k//-----------------------------------------
: o/ ]3 e6 }8 \#include Classes.hpp : a0 \8 j( b/ g! I
#include Controls.hpp
: U. Q, o5 s4 W: j7 P' N/ i#include StdCtrls.hpp . P* B8 l# z/ y: e; {
#include Forms.hpp
8 [2 a9 Z2 x+ N: ?( i+ y# ?#include Menus.hpp//-------------------- / e' B. w; }1 [5 ]3 @5 X" h+ x
- e* b7 _6 f5 c% W
class TForm1 : public TForm 6 z# ?1 E o3 ?
{ 3 r$ D: l0 p6 z1 m
__published: // IDE-managed Components
0 S) a7 B0 D. \: k9 B4 R0 X1 kTMainMenu *MainMenu1; : n% G. V; k* N! g3 B( m
TMenuItem *aaa1;
# s) X! B9 Y5 F. F \. n ^TMenuItem *aaaaaaaaa1;
& ^2 t/ B" l8 s* I9 tTMenuItem *ccc1; 2 a3 B/ T$ [$ |* h. U' E+ f W7 O
TMenuItem *ddd1; 3 `5 w' K! w( {) o9 ^& s
TMenuItem *eee1; * ]+ l5 p6 k7 @( W' F
TMenuItem *ddsds1;
7 V0 ^! v. b. _4 t/ Y* [TMenuItem *fcdfsss1;
1 u: T- N4 d' T$ Z: R# h4 BTMenuItem *dddddddd1;
2 c7 ~. D$ l Qvoid __fastcall FormCreate(TObject *Sender); ' f& L1 A, W X, s' x
private: // User declarations ( \7 D8 z2 L% g: r/ ?7 T1 h
void __fastcall Modify(TMenuItem *pMenuItem); " [7 m3 M( m/ F* D/ a& j" Y @
protected :
: W$ b6 c5 L- N( mMESSAGE void __fastcall CNMeasureItem(TWMMeasureItem Msg);//增加响应消息
- M5 ?0 P2 d$ m, U; [" r4 u# ^MESSAGE void __fastcall CNDrawItem(TWMDrawItem Msg); , t! A% u$ I& c! y* g4 W5 H
public: // User declarations $ T0 V$ X$ \; I7 r
__fastcall TForm1(TComponent* Owner); % Y4 F6 H! J3 w: B
BEGIN_MESSAGE_MAP//添加消息映射 3 p& o4 Z- A. v" G
VCL_MESSAGE_HANDLER(WM_MEASUREITEM, TWMMeasureItem, CNMeasureItem); ( g! x1 e" Y7 A3 T' _+ t
VCL_MESSAGE_HANDLER( WM_DRAWITEM, TWMDrawItem, CNDrawItem); - S3 v1 O. L3 X* b5 F% B6 n
END_MESSAGE_MAP(TForm);
! k! i% t# m4 l}; 3 o4 j$ U8 w) ]4 J2 U1 Z! u+ Z" h/ h
//---------------------------------------------------------------------------
: |# Y% p6 Y) R8 R2 j* Iextern PACKAGE TForm1 *Form1; + Q8 e) _; q2 y# S# @ H( ~1 c
//--------------------------------------------------------------------------- 4 m+ q. U# Y. f* {2 R
#endif ( O/ {# S1 }# E; T; p
, G( I) m( W7 {2 W8 b//实现文件
, Q u3 j" Y) U R- B) @//---------------------------------------------------------------------------
% W+ s- d1 O* c1 N#include vcl.h 4 \4 o" A" W) b( N x' ]( x: g, T
#pragma hdrstop 7 ^2 r0 f' F. s& x8 V
4 {* h6 i: X9 m: N. h#include TestMenu.h
7 ~: ~; Y4 f5 i" D5 e, Y5 y; K" J- e//---------------------------------------------------------------------------
' c9 ]2 y0 H5 U" M N d6 l' v#pragma package(smart_init) 7 |: v- K7 ]9 @& Q7 ^
#pragma resource *.dfm
( ]5 a/ |2 T P5 [% E4 YTForm1 *Form1;
) V1 ?1 b& x+ K5 ?//--------------------------------------------------------------------------- 0 d/ h4 D/ `1 @3 Y' \. \ y
__fastcall TForm1::TForm1(TComponent* Owner)
+ T3 ~. X. T _: ~( V# k: TForm(Owner)
# \" s6 R% z7 G4 q! W{ 7 P* \$ [6 v2 `! i. ]# z, ~
}
$ }' R+ |; S1 G" O" Y* L$ D+ b+ M5 C//---------------------------------------------------------------------------
2 ^2 r0 \; C5 }3 ~/ {0 o ! I0 q4 z) E+ t
void __fastcall TForm1::Modify(TMenuItem *pMenuItem) * l" u* ~7 y' A6 [9 {9 e7 k
{//修改缺省属性 4 D! h! a' S1 d; q9 u8 Z
for(int i=0;ipMenuItem-Count;i++) + ]2 _9 `* z, P, p1 \* O$ z: n
{ # }6 O) x7 u" k0 K# u; r6 [ x
MENUITEMINFO mii=
! G0 g- _3 u d{ 4 _. X6 _0 _, A! \9 e% ^
sizeof(MENUITEMINFO),
/ t/ { L8 ^* o; @* y6 dMIIM_TYPE|MIIM_DATA ,//改变类型和数据 : R: a. R u7 e5 E
MF_OWNERDRAW,0,0,0,0,0,DWORD(pMenuItem-Items-Handle), * ^1 B" g2 ]. X% d2 h+ N
//把菜单项的句柄赋给32位数据
9 b) v* F! o N- @1 V0,
7 m& _& t: z2 c9 a( R3 [0, ; @' B# N1 o$ z: l. l' M) g" x+ V
}; ; H+ D# P. t/ @$ U4 Z& }4 G
if(pMenuItem-Items-Caption!=-)//如果不是间隔线 ; c! | s- X1 L. w
::SetMenuItemInfo(pMenuItem-Handle,i,TRUE,mii);
, N( Y! f0 i1 b( K, F! q2 f+ r6 hif(pMenuItem-Items-Count)//如果含有子菜单
% [$ b# y U8 b0 C* W4 CModify(pMenuItem-Items);
7 Y5 h7 K: m f2 a/ k1 H}
9 i+ y* l4 d# L: H* ] / Q# W. e+ Z/ i/ i ^) r
} + o& m. |- p: Q+ y+ o( d, G" Y
void __fastcall TForm1::FormCreate(TObject *Sender)
" J$ l' n2 O& j; ]+ J Q( @{ ! x7 }& g; z3 t2 }0 W
for(int i=0;iMainMenu1-Items-Count;i++) 7 e' M8 V/ a& L0 \( g
{ : w% m9 l% c. R n$ n) ^/ b5 v
Modify(MainMenu1-Items-Items);
1 i/ \, s4 a1 `9 c} # n$ [2 o: s' F. n
DrawMenuBar(Handle); " U( Z# H# c5 |
} & m3 a; y7 p6 A$ d
//---------------------------------------------------------------------------
6 Q! Q6 E a* Q/ x' yvoid __fastcall TForm1::CNMeasureItem(TWMMeasureItem Msg)
) C& s9 @( F- y. Q$ M$ t7 G4 ?{//设置菜单大小 ; l: n7 [% n/ D& [2 S0 [( c
TMenuItem *pItem=MainMenu1-FindItem(Msg.MeasureItemStruct-itemData,fkHandle); : G, Q7 L Z/ R P% ^+ q
Msg.MeasureItemStruct-itemWidth =pItem-Caption.Length()*8+40; ; v6 E3 v n$ t4 H+ I3 U& u
Msg.MeasureItemStruct-itemHeight = 20; 2 i9 l! Y1 v- z+ ? t
}
! U3 s3 L+ Y; U0 hvoid __fastcall TForm1::CNDrawItem(TWMDrawItem Msg) 0 g' {4 b+ r& o4 o
{//画出菜单 + [9 D6 `6 k) y" U4 C, h- X$ b4 P
TMenuItem *pItem=MainMenu1-FindItem(Msg.DrawItemStruct-itemData,fkHandle);
3 q" P8 b I' c V, `! p# j, VTCanvas *pCanvas=new TCanvas;
5 I* H- u! i, `: Q7 a' Q( N- wpCanvas-Handle=Msg.DrawItemStruct-hDC;
* z) @4 E+ K( ARECT r=Msg.DrawItemStruct-rcItem;
- ~% P+ h3 ]1 t2 h8 J; i, ]5 w ?) g5 ^pCanvas-Brush-Color=clBtnFace; 5 {; e3 V! |3 |3 f f m5 ^
RECT r1=r; 5 K" k1 p% C$ d# b+ _
r1.right+=1;
; a+ B- P% ~7 l( u6 f; \1 y* Dr1.bottom+=1; & g" A' w: p- s+ S! b$ L
r1.top-=1; * v: J7 H6 E) R" v$ Y
r1.left-=1;
! ~, i6 i/ Q& HpCanvas-FillRect(r); 4 Z9 n* M6 L+ \* U! D
::SetBkMode(pCanvas-Handle,TRANSPARENT);
. {: c1 u& _' J6 l4 P( b# dpCanvas-TextOut(r.left+10,r.top+2,pItem-Caption);
% V( {) ?" N; g+ Z1 rr.right-=1; $ w H- I# R7 L* Y! S8 s
r.bottom-=1;
: c9 Z. B* J; C; D7 x# fif(Msg.DrawItemStruct-itemAction == ODA_SELECT 0 G! t# d+ I; s7 ~3 j$ F7 ~% ?
Msg.DrawItemStruct-itemStateODS_SELECTED )
) N$ `4 i' c% C4 a% p) o{
$ r! W% [$ C( Y& D3 u. BpCanvas-Pen-Color=(TColor)(RGB(255,255,255)); . w6 ?7 ^2 j/ P& R0 _
pCanvas-MoveTo(r.right,r.top); 1 i4 F$ w7 e: Q+ m
pCanvas-LineTo(r.left,r.top);
' ?# ^6 u% w5 t5 W+ C# vpCanvas-LineTo(r.left,r.bottom);
/ X7 u* H- M1 m2 z/ QpCanvas-Pen-Color=(TColor)(RGB(128,128,128));
: Q3 e6 M7 ]! m- ^/ L" ^5 SpCanvas-LineTo(r.right,r.bottom); * B* T+ u4 O' I# a' ^" G
pCanvas-LineTo(r.right,r.top); + W9 p5 b1 n0 [: K1 C
} : Z8 n9 [6 Y r8 g; V: S3 |
8 `! N6 T7 R. n2 k2 F
} |