|
我们知道,C++Builder没有自画菜单,但可以调用API函数::SetMenuItemInfo()来改 8 s9 }, d0 D8 T. y& U2 ~& x3 c
变菜单类型,达到自画菜单的目的。下面的例子演示了如何使用自画菜单。当鼠标位于菜单
* t v- v: {% j; q" | Q2 _, e上拾,菜单项将凸出来。(黑体字为添加的代码)
& E: f' a8 M8 z$ M, h' H' f 6 d& ~3 J. p" O1 p$ F) W
//头文件
1 d5 M% K( ^1 q" m) N$ A2 g/ ^//------------------------------------------ 9 v+ F9 G }, Z% Y8 E. r* U' ^
#ifndef TestMenuH
. R- _4 T& G' w1 A( J. D#define TestMenuH
8 y3 a- `1 C+ J1 @* b9 `$ h//----------------------------------------- 6 j: e1 y# K. D, c
#include Classes.hpp
$ p( G6 y4 F, ?7 B8 l; d: q#include Controls.hpp $ p7 W- ?3 o' c
#include StdCtrls.hpp 3 v a2 p( _' U0 K& u/ X3 m3 n
#include Forms.hpp
8 g" x& C" H) w0 y7 w0 X#include Menus.hpp//--------------------
6 p" r: A4 Z+ w% l9 j* I2 _ . i: A* ~( p& B [
class TForm1 : public TForm
7 S4 ?: l- A4 u6 g! K0 B{ j; q7 A# w6 W$ Y9 v
__published: // IDE-managed Components b# I; r& k$ ?: p8 a8 g
TMainMenu *MainMenu1;
0 p' d/ x# J- N6 ?- Z3 V3 TTMenuItem *aaa1;
; C* \: E0 t+ wTMenuItem *aaaaaaaaa1;
3 l5 i; l. o7 P& E+ OTMenuItem *ccc1;
8 x& A; j5 ]5 {3 GTMenuItem *ddd1;
7 m6 b( J* g! w" |; l3 X# m2 DTMenuItem *eee1; & f! M/ A3 C5 ]2 A6 S0 p9 E: }
TMenuItem *ddsds1;
* m5 H3 j! H8 K; t* S/ Z- CTMenuItem *fcdfsss1; 8 Q& U7 ]% u6 R6 @% ^% \& d
TMenuItem *dddddddd1; . B8 l$ c3 h d# W9 i) V8 ^
void __fastcall FormCreate(TObject *Sender);
. _/ m- ~: w( ^! U5 Z) j+ Wprivate: // User declarations
/ A$ |( {1 n/ a+ q! W3 ivoid __fastcall Modify(TMenuItem *pMenuItem); ( j9 U. [' z& n# H6 W
protected : # K& Y8 i( f5 ^( b5 `0 ]
MESSAGE void __fastcall CNMeasureItem(TWMMeasureItem Msg);//增加响应消息
7 x% F, |& B N; `6 r4 JMESSAGE void __fastcall CNDrawItem(TWMDrawItem Msg); ' |$ e' k1 f, B4 P5 x, B$ r8 {8 r7 u. U
public: // User declarations 7 L% k! s% [6 [+ |
__fastcall TForm1(TComponent* Owner);
7 r0 S$ _' R E0 I+ W4 EBEGIN_MESSAGE_MAP//添加消息映射
: y* @0 |, z! ]- V$ n# Y' m J$ @VCL_MESSAGE_HANDLER(WM_MEASUREITEM, TWMMeasureItem, CNMeasureItem); " n2 G8 d _% V m5 q' F
VCL_MESSAGE_HANDLER( WM_DRAWITEM, TWMDrawItem, CNDrawItem);
, o0 N; p- U# {* ^2 jEND_MESSAGE_MAP(TForm);
8 k5 g6 K+ s; |' S/ c0 N7 X. X};
8 Q% S" p8 g" b//--------------------------------------------------------------------------- 2 I7 P# K! d- G' c, _
extern PACKAGE TForm1 *Form1;
/ ?7 M6 D( A& H5 w" D//--------------------------------------------------------------------------- / E& h2 Q& G* a: Y" T
#endif
* Q9 L" [" I: L
- c; w( J" P, ]: C. n! a4 v//实现文件
# E) [ s7 i' }& |: A//--------------------------------------------------------------------------- * F- a+ L0 M b1 ?
#include vcl.h - ~/ H& j: J. O' f" V$ O; ^
#pragma hdrstop
, g! o. o! I) H3 m ; Q& m. ~1 h7 s: @
#include TestMenu.h 2 d# \( ]8 B2 ~
//---------------------------------------------------------------------------
' N1 M4 x2 k9 D H; n3 x#pragma package(smart_init) 4 M) M0 Y1 B. b& C% M" @4 Y, X! X
#pragma resource *.dfm , P' r" n. @! _8 b
TForm1 *Form1;
$ ^7 q9 T1 e2 ?1 {. G//---------------------------------------------------------------------------
' L9 b7 z3 N3 c5 ^9 S__fastcall TForm1::TForm1(TComponent* Owner) ( _3 V( [# P! A+ R. `
: TForm(Owner)
5 H* L# ^9 W- u& g, b{ % B' T( Q$ r5 r. k2 f
} 7 n1 e: {$ j: K) F$ @' N
//--------------------------------------------------------------------------- 8 Y' a+ G3 [/ y8 { K' `; J
" e+ m' @, d, Svoid __fastcall TForm1::Modify(TMenuItem *pMenuItem) - t& X; M6 M; Z# K( \
{//修改缺省属性 & Y; V* e3 y/ E5 k, h
for(int i=0;ipMenuItem-Count;i++)
. [) a3 N9 V" a, j, h8 \{
f+ A" b5 N; z: Y' `) _MENUITEMINFO mii=
8 u6 X7 w- U& f6 u( U7 K) k{
: x: w6 z% Q) _2 } F B0 q$ N) @sizeof(MENUITEMINFO), , L1 x5 `3 R( ^+ X7 ^; b
MIIM_TYPE|MIIM_DATA ,//改变类型和数据 2 E5 x$ G4 o$ T- Z. y
MF_OWNERDRAW,0,0,0,0,0,DWORD(pMenuItem-Items-Handle),
3 a2 H5 U B+ S: A5 I: y//把菜单项的句柄赋给32位数据
- k" |0 E0 k5 E9 C0, $ ?6 S8 @2 |$ k8 ?* {1 H% O/ D
0,
- e6 X' G# c' f% n! `% a3 X};
5 G+ h0 j3 g2 V8 t6 H+ k. rif(pMenuItem-Items-Caption!=-)//如果不是间隔线
8 M3 m( ~- {/ Z4 f::SetMenuItemInfo(pMenuItem-Handle,i,TRUE,mii); 9 X# y- P! U/ x! s( C) k
if(pMenuItem-Items-Count)//如果含有子菜单
( X6 K2 k+ g& I' B0 _Modify(pMenuItem-Items); , S9 C n+ A- T- g% i
} 5 u5 G: l: Z& S$ U. F
# |( e+ T K. N, i( R1 H, @
}
# z) e. Z4 E$ r+ dvoid __fastcall TForm1::FormCreate(TObject *Sender) ' o- q$ V3 m D7 U: H( q
{
, q& e8 P2 u. Y. Tfor(int i=0;iMainMenu1-Items-Count;i++)
4 r) y) b" @2 r. ?/ ^8 k1 @4 V{
+ ]) s% D j8 \! w- ` x1 S& }Modify(MainMenu1-Items-Items); j [0 o- ?) f J$ {
} * r& X7 ~8 K0 [5 a: f/ x
DrawMenuBar(Handle); 8 Y# v; Z7 i9 h( ~4 j' k% M& M
}
$ j4 O( |: R; |) k! _0 ]6 i0 O//--------------------------------------------------------------------------- : V' f. C: F2 ^3 g
void __fastcall TForm1::CNMeasureItem(TWMMeasureItem Msg) 4 P2 r. `9 ]7 ]+ f( T% Q8 n0 s
{//设置菜单大小
, i0 w5 X: V" [! eTMenuItem *pItem=MainMenu1-FindItem(Msg.MeasureItemStruct-itemData,fkHandle); 5 G3 R5 e; {# \# g' q
Msg.MeasureItemStruct-itemWidth =pItem-Caption.Length()*8+40;
/ Y \, E) H% s2 ]# x VMsg.MeasureItemStruct-itemHeight = 20;
& {8 Q9 j7 S. x9 C: y' P% i8 w, e}
( Q! |0 }8 Y, S" g8 O1 ~( L$ V8 Xvoid __fastcall TForm1::CNDrawItem(TWMDrawItem Msg) , N' ^' c" M8 Z) j* b
{//画出菜单 0 c( c4 M; y) r1 W5 [! _
TMenuItem *pItem=MainMenu1-FindItem(Msg.DrawItemStruct-itemData,fkHandle); % S6 c. l: f! L
TCanvas *pCanvas=new TCanvas; / Y/ m% H$ J% B! x
pCanvas-Handle=Msg.DrawItemStruct-hDC;
: Y3 n$ H0 ~2 G0 Y1 |RECT r=Msg.DrawItemStruct-rcItem;
. h% M5 ^ a$ _9 W5 C6 LpCanvas-Brush-Color=clBtnFace;
! Y' v8 c( b! A6 m0 cRECT r1=r;
; D$ }/ ]* ]* i/ I. er1.right+=1; ) ~$ X# F2 u* D/ u
r1.bottom+=1;
" u! O* |) K M1 |" H0 Br1.top-=1;
8 C6 B9 k' O* k8 }) zr1.left-=1;
/ W! U0 i" `' `pCanvas-FillRect(r);
0 } P% s) n* U& u' `1 a::SetBkMode(pCanvas-Handle,TRANSPARENT); 7 _1 H7 R2 T( d
pCanvas-TextOut(r.left+10,r.top+2,pItem-Caption);
5 O+ Q) C- }4 T ?0 k6 ]( @r.right-=1;
: p; e/ t* X2 X7 F, J; F+ N8 pr.bottom-=1; ' D4 }% L: s- ?$ l
if(Msg.DrawItemStruct-itemAction == ODA_SELECT
7 g" I" T7 C. \1 z6 w0 _; |! oMsg.DrawItemStruct-itemStateODS_SELECTED ) 1 n5 s8 Y9 \& V% g6 J) C W
{
1 r+ C$ i' T9 }pCanvas-Pen-Color=(TColor)(RGB(255,255,255));
+ s, m! X$ i, ]3 J6 dpCanvas-MoveTo(r.right,r.top);
9 ~+ e7 [5 [8 h, GpCanvas-LineTo(r.left,r.top); * }3 H* m1 j; R
pCanvas-LineTo(r.left,r.bottom); ) Y- D$ D' `6 o- k# w) m
pCanvas-Pen-Color=(TColor)(RGB(128,128,128)); 6 L" v6 P f9 z, D6 Y1 i3 ~1 b# T! A) T
pCanvas-LineTo(r.right,r.bottom); 8 X. G9 \4 k4 w- L: M, Z% O; E
pCanvas-LineTo(r.right,r.top);
' n. x3 X$ |$ D( V1 c m7 U2 q8 V} & m* p8 t1 Y% l: L$ {
: F3 A# b6 }: U- d" D} |