首页  编辑  

win98开始风格菜单

Tags: /超级猛料/VCL/Menu.菜单/   Date Created:

1.新建一个PopupMenu1.设置OwnerDraw:=True;

2.添加一个菜单项m1.设置m1.Caption:='';

 m1.Enabled:=False;

3.添加一些你需要的菜单项m2,m3,m4,…….

 其中设置m2.Break:=mbBreak;

4.在m1的DrawItem中:

procedure TForm1.m1DrawItem(Sender: TObject; ACanvas: TCanvas;

 ARect: TRect; Selected: Boolean);

var

 i:word;

 dy,y:real;

 lf:TLogFont;

 tf:TFont;

begin

 //画渐进色背景

 dy:=(ARect.Bottom - ARect.Top)/256;

 y:=0;

 for i:=255 downto 0 do

 begin

   Acanvas.brush.color:=RGB(255-i,255-i,255);

   Acanvas.fillrect(rect(0,round(y),ARect.Right - ARect.Left,round(y+dy)));

   y:=y+dy;

 end;

 //写字

 With ACanvas do

   Begin

     Brush.Style:=bsClear;

     Font.Name:='宋体';

     Font.Size:=12;

     Font.Color:=clred;

     tf:=TFont.Create;

     tf.Assign(Font);

     GetObject(tf.Handle,sizeof(lf),@lf);

     lf.lfEscapement:=900;

     tf.Handle:=CreateFontIndirect(lf);

     Font.Assign(tf);

     tf.Free;

     TextOut(ARect.Left +2,ARect.Bottom -2,'弹出菜单');

   End;

end;

5.在m1的MeasureItem中:

procedure TForm1.m1MeasureItem(Sender: TObject; ACanvas: TCanvas;

 var Width, Height: Integer);

begin

/////////

 Width:= 10;

 Height:= (PopupMenu1.Items.Count - 1) * 19;

end;

***********************************************

1、设置TPopupMenu的OwnerDraw为True;

2、设置TPopupMenu的Images

3、设置TMenuItem的OnMeasureItem和OnDrawItem分别指向两个例程。

这是以前我写的程序的一段代码,与大家分享(如果有什么问题,请呼我OICQ:6113690,或者写信给我,我可以写一个完整的例子):

procedure TfrmMain.pmTrayPopup(Sender: TObject);

begin

 pmTray.Tag := 1;  //对于左边的位图保证只绘制一次

end;

procedure TfrmMain.MenuMeasureItem(Sender: TObject; ACanvas: TCanvas;

 var Width, Height: Integer);

begin

 if (Sender as TMenuItem).IsLine then

   Height := 4 //分隔条

 else

   Height := Canvas.TextHeight('高') + 6;

 //const BMWidth = 位图宽度

 Inc(Width, BMWidth + 7); //为左边的位图保留一些空间

end;

procedure TfrmMain.MenuDrawItem(Sender: TObject; ACanvas: TCanvas;

 ARect: TRect; Selected: Boolean);

var ABitmap: TBitmap;

   Item: TMenuItem;

   Rc: TRect;

   nLeft, nTop: Integer;

   Ico: HICON;

begin

 Item := Sender as TMenuItem;

 ABitmap := TBitmap.Create;

 try

   //对于左边的位图保证只绘制一次

   if (pmTray.Tag = 1) and (Item.MenuIndex = 0) then

   begin

     pmTray.Tag := 0;

     ABitmap.LoadFromResourceID(hInstance, PostMan); //左边图形的ResourceID

     CopyRect(Rc, ACanvas.ClipRect);

     Rc.Left := BMWidth + 2;

     CopyRect(Rc, ACanvas.ClipRect);

     Rc.Right := Rc.Left + BMWidth + 2;

     //用图形左下的颜色填充矩形

     ACanvas.Brush.Color := ABitmap.Canvas.Pixels[0, ABitmap.Height - 1];

     ACanvas.FillRect(Rc);

     //绘制一个凹下的矩形框

     Frame3D(ACanvas, Rc, clBtnShadow, clBtnHighlight, 1);

     ACanvas.Draw(Rc.Left, Rc.Top, ABitmap);

     //绘制Application图标

     Ico := LoadImage(hInstance, PChar(szMainIcon), IMAGE_ICON, 16, 16,

                      LR_DEFAULTCOLOR);

     nLeft := (BMWidth - 16) div 2 + 1;

     DrawIconEx(ACanvas.Handle, nLeft, Rc.Bottom - nLeft - 16,

                Ico, 16, 16, 0, 0, DI_NORMAL);

     DestroyIcon(Ico);

     ACanvas.Brush.Color := clBtnFace;

   end;

   CopyRect(Rc, ARect);

   Inc(Rc.Left, BMWidth + 2);

   nTop := Grade + Ord(Selected);

   //绘制背景图形

   ABitmap.LoadFromResourceID(hInstance, nTop);

   ACanvas.CopyRect(Rc, ABitmap.Canvas, Rect(0, 0, ABitmap.Width, ABitmap.Height));

   if Item.IsLine then //绘制菜单分隔条

   begin

     nTop := (ARect.Bottom + ARect.Top) div 2 - 1;

     ACanvas.Pen.Color := clBtnShadow;

     ACanvas.MoveTo(BMWidth + 3, nTop);

     ACanvas.LineTo(ARect.Right, nTop);

     ACanvas.Pen.Color := clBtnHighlight;

     ACanvas.MoveTo(BMWidth + 3, nTop + 1);

     ACanvas.LineTo(ARect.Right, nTop + 1);

   end else

   begin

     nTop :=  (Rc.Bottom + Rc.Top - imglstState.Height) div 2;

     nLeft := Rc.Left + (Rc.Bottom - Rc.Top - imglstState.Width) div 2 + 2;

     if Selected then //绘制被选择菜单的外观

     begin

       with Rc do

       Right := Left + Bottom - Top;

       DrawEdge(ACanvas.Handle, Rc, BDR_RAISEDINNER, BF_RECT);

       Inc(Rc.Left, Rc.Bottom - Rc.Top + 1);

       Rc.Right := ARect.Right;

       DrawEdge(ACanvas.Handle, Rc, BDR_SUNKENOUTER, BF_RECT);

     end;

     //绘制菜单前面的小图形,一个TImageList

     imglstState.Draw(ACanvas, nLeft - 1, nTop, Item.ImageIndex, Item.Enabled);

     CopyRect(Rc, ARect);

     InflateRect(Rc, -1, -1);

     Inc(Rc.Left, BMWidth + ARect.Bottom - ARect.Top + 6);

     ACanvas.Brush.Style := bsClear;

     if not Item.Enabled then

     begin

       OffsetRect(Rc, 1, 1);

       ACanvas.Font.Color := clBtnHighlight;

     end else

     with ACanvas.Font do

     if Selected then Color := clRed else Color := clBtnText;

     ACanvas.Brush.Style := bsClear;

     if Item.Enabled or (not Selected) then

     DrawText(ACanvas.Handle, PChar(Item.Caption), Length(Item.Caption), Rc,

              DT_LEFT or DT_VCENTER or DT_SINGLELINE or DT_END_ELLIPSIS);

     if not Item.Enabled then

     begin

       OffsetRect(Rc, -1, -1);

       ACanvas.Font.Color := clBtnShadow;

       DrawText(ACanvas.Handle, PChar(Item.Caption), Length(Item.Caption), Rc,

                DT_LEFT or DT_VCENTER or DT_SINGLELINE or DT_END_ELLIPSIS);

     end;    

   end;

 finally

   ABitmap.Free;

 end;    

end;

*******************************

收集的,也用过了,借花献佛:)

const

   BarWidth = 23;                          // 类似于开始菜单的popmenu的宽度

   BarSpace = 3;

type

 TFormMain = class(TForm)

 ......

 ......

 private

   { Private declarations }

   function CreateRotatedFont(F: TFont; Angle: Integer): hFont;

   procedure ExpandItemWidth(Sender: TObject; ACanvas: TCanvas; var Width, Height: Integer);

   procedure AdvancedDrawItem(Sender: TObject; ACanvas: TCanvas; ARect: TRect; State: TOwnerDrawState);

 public

   { Public declarations }

   PopupImage: TBitmap;  { icon in the bar }

   PopupHeight: Integer; { holds the popumenu height }

   PopupBitmap: TBitmap; { buffer for the bar }

   Drawn: Boolean;      { tells us if buffer has been drawn }

end;

//////////////////////////////////////////////////////////////////////////////////////////////

// 生成类似于开始菜单的popmenu

procedure TFormmain.ExpandItemWidth(Sender: TObject; ACanvas: TCanvas; var Width, Height: Integer);

begin

 Inc(Width, BarWidth);        // make space for graphical bar

 // way to calculate total height of menu to PopupHeight variable which was reset at OnPopup event

 if TMenuItem(Sender).Visible then PopupHeight := PopupHeight + Height;

end;

procedure TFormmain.AdvancedDrawItem(Sender: TObject; ACanvas: TCanvas; ARect: TRect; State: TOwnerDrawState);

const

 VerticalText = '静态页面生成系统';

 clStart: TColor = clBlue;

 clEnd: TColor = clBlack;

var

 i, iTmp: Integer;

 r: TRect;

 rc1, rc2, gc1, gc2, bc1, bc2: Byte;

 ColorStart, ColorEnd: Longint;

 MenuItem: TMenuItem;

begin

 MenuItem := TMenuItem(Sender);

 { we need to remove draw event so DrawMenuItem won't generate infinite loop! (Recursive) }

 MenuItem.OnAdvancedDrawItem := nil;

 { align rect where item is draw so that vcl will leave bar for us }

 r := ARect;

 Dec(r.Right, BarWidth);                              // remove bar width

 OffsetRect(r, BarWidth, 2);

 DrawMenuItem(MenuItem, ACanvas, r, State);            // draw item and restore event back

 MenuItem.OnAdvancedDrawItem := AdvancedDrawItem;

 PopupBitmap.Height := PopupHeight;

 PopupBitmap.Width := BarWidth - BarSpace;

 with PopupBitmap.Canvas do

   if not Drawn then

   begin                                              // ... first draw phase ... }

     Brush.Style := bsSolid;

     if (clStart = clEnd) then                        // same color, just one fillrect required

     begin

       Brush.Color := clStart;

       FillRect(Rect(0, ARect.Top, BarWidth - BarSpace, ARect.Bottom));

     end

     else                                              //draw smooth gradient bar part for this item

     begin

       // this way we can use windows color constants e.g. clBtnFace. Those constant don't keep the RGB values

       ColorStart := ColorToRGB(clStart);

       ColorEnd := ColorToRGB(clEnd);

       // get the color components here so they are faster to access inside the loop

       rc1 := GetRValue(ColorStart);

       gc1 := GetGValue(ColorStart);

       bc1 := GetBValue(ColorStart);

       rc2 := GetRValue(ColorEnd);

       gc2 := GetGValue(ColorEnd);

       bc2 := GetBValue(ColorEnd);

       // make sure that division by zero doesn't happen

       if PopupHeight <> 0 then

         for i := 0 to (ARect.Bottom - ARect.Top) do

         begin

           Brush.Color := RGB(

             (rc1 + (((rc2 - rc1) * (ARect.Top + i)) div PopupHeight)),

             (gc1 + (((gc2 - gc1) * (ARect.Top + i)) div PopupHeight)),

             (bc1 + (((bc2 - bc1) * (ARect.Top + i)) div PopupHeight)));

           FillRect(Rect(0, ARect.Top + i, BarWidth - BarSpace, ARect.Top + i + 1));

         end;

     end;

     with Font do

     begin

       Name := 'Tahoma';

       Size := 9;

       Color := clWhite;

       Style := [fsBold];

       iTmp := Handle; { store old }

       Handle := CreateRotatedFont(Font, 90);

     end;

     Brush.Style := bsClear;

     r := Rect(ARect.Left, ARect.Top, ARect.Right, ARect.Bottom + 1);

     ExtTextOut(Handle, 1, PopupHeight - PopupImage.Height - 15, ETO_CLIPPED, @r, PChar(VerticalText), Length(VerticalText), nil);

     DeleteObject(Font.Handle);                        // delete created font and restore old handle

     Font.Handle := iTmp;

     if PopupHeight = ARect.Bottom then

     begin                                            // draw bitmap

       Drawn := True;

       Draw(0, PopupHeight - PopupImage.Height - 6, PopupImage);

     end;

     { draw the double buffered bar now }

     r := Rect(0, 0, PopupBitmap.Width, ARect.Bottom);

     ACanvas.CopyRect(r, PopupBitmap.Canvas, r);

   end

   else                                                // draw from double buffer

   begin

     r := Rect(0, ARect.Top, PopupBitmap.Width, ARect.Bottom);

     ACanvas.CopyRect(r, PopupBitmap.Canvas, r);

   end;

 { end with }

end;

function TFormmain.CreateRotatedFont(F: TFont; Angle: Integer): hFont;

var LF : TLogFont;

begin

 FillChar(LF, SizeOf(LF), #0);

 with LF do

 begin

   lfHeight := F.Height;

   lfWidth := 0;

   lfEscapement := Angle*10;

   lfOrientation := 0;

   if fsBold in F.Style then lfWeight := FW_BOLD

   else lfWeight := FW_NORMAL;

   lfItalic := Byte(fsItalic in F.Style);

   lfUnderline := Byte(fsUnderline in F.Style);

   lfStrikeOut := Byte(fsStrikeOut in F.Style);

   lfCharSet := DEFAULT_CHARSET;

   StrPCopy(lfFaceName, F.Name);

   lfQuality := DEFAULT_QUALITY;

   lfOutPrecision := OUT_DEFAULT_PRECIS;

   lfClipPrecision := CLIP_DEFAULT_PRECIS;

   case F.Pitch of

     fpVariable: lfPitchAndFamily := VARIABLE_PITCH;

     fpFixed: lfPitchAndFamily := FIXED_PITCH;

   else

     lfPitchAndFamily := DEFAULT_PITCH;

   end;

 end;

 Result := CreateFontIndirect(LF);

end;

//                        popmenu弹出事件                            //

procedure TFormMain.PopupMenuIconPopup(Sender: TObject);

var i:integer;

begin

   Drawn := False;

   PopupHeight := 0;

   with TPopupMenu(Sender) do

   if (Items.Count > 0) then

       for i := 0 to Items.Count-1 do

       begin

           Items[i].OnMeasureItem := ExpandItemWidth;

           Items[i].OnAdvancedDrawItem := AdvancedDrawItem;

       end;

end;

// end of menu create like start

////////////////////////////////////////////////////////////////////////////////////////////