用Delphi製作個性化的選單 (轉)

worldblog發表於2007-12-12
用Delphi製作個性化的選單 (轉)[@more@] 

 :namespace prefix = o ns = "urn:schemas--com::office" />


用製作個性化的選單

gocn.com">


在應用編寫中,使用個性化的選單可以美化介面,展示個性風彩。例如3721網站推出的《3721特快》應用程式中的選單就是一例。從其的角度來說它僅是一個自繪式選單而已。本文就使用Delphi製作這樣的個性化選單作出說明(本文以Delphi4.0為例),製作一個可以有背景圖、滑鼠在上移動選擇時的背景色有漸變色效果的彩色選單。


一、關於Delphi中的自繪式選單


要將Delphi的選單(TMainMenu 或TPopupMenu)(Component)設為自繪式,有兩種不同的情況:
  ① 如果選單上沒有圖示(即,沒有設定其Images屬性),則必須將選單控制元件的OwnerDraw屬性設為True,選單為自繪式。
  ② 選單上有圖示(即,已設定其Images屬性),選單為自繪式。


在此,我們必須首先把準備將其製作成有個性特徵的選單設為自繪式。


二、關於背景的重繪


通常Windows程式的標準選單,在其被下拉或彈出時,滑鼠在上移動時出現的選擇條背景是一單一的顏色,現在我們要將其重繪為有漸變色效果的背景,另外如果要在其背景上繪製圖形(您見過這樣的選單嗎?),則應先繪圖、後繪漸變的背景。這些繪製工作的完成只需簡單使用Delphi提供的畫布(Canvas)。


三、關於重繪圖示


如果選單上有圖示,則最好為各選單項指定ImageIndex號,而不要使用其Bitmap屬性。這樣在為各選單項指定了ImageIndex索引號後,可以直接用其TImageList的Draw方法在同一個畫布上繪製相應的圖示。


四、關於重繪選單文字


  在重繪選單時,為了不破壞其背景,應將文字的背景設為透明,這要用到一個Windows SetBkMode(),其在C++中定義的原形如下:
  int SetBkMode(


  HDC hdc, 


  int iBkMode   // flag specifying background mode


  );


  其中:hdc – 是繪圖裝置控制程式碼,在Delphi中可為Tcanvas的Handle屬性;


  iBkMode – 指定的背景模式識別符號,有OPAQUE 和TRANSPARENT兩個
   常量取值,取TRANSPARENT時,為透明模式。


設定了背景模式後,可以使用TCanvas的TextOut方法繪製選單文字。


五、響應自繪式選單的OnDrawItem事件
  為選單項的OnDrawItem事件新增程式碼,完成想要完成的重繪工作,如下所示(M_Item1_1是選單項名稱):


 


procedure TForm1.M_Item1_1DrawItem(Sender: T; ACanvas: TCanvas;


   ARect: TRect; ed: Boolean);


  begin


   //自定義過程--重繪選單項


   DrawItem(TMenuItem(Sender), ACanvas, ARect,Selected);


  end;


六、二個示例


㈠ 以下是實現上述個性化選單的自定義過程DrawItem的一個示例的程式碼。但需作如下說明:


①  在其Delphi工程的主視窗上有一個TCoolBar控制元件CoolBar1,其上又放了一個TToolBar控制元件,並且TCoolBar的Bitmap屬性不為空(即為其指定了圖象)。


②  主視窗上有一個TPopupMenu 控制元件PopupMenu1、一個TImageList控制元件ImageList1,其PopupMenu1的Images屬性等於ImageList1。


③  TToolBar的Transparent屬性為True,並且上面的工具按鈕的MenuItem屬性分別與相應的選單項相關聯(注意,這是用工具條、工具按鈕和彈出式選單製作主選單的方法,應將工具按鈕的Grouped屬性全部設為True)。


程式碼如下:


procedure TForm1.DrawItem(Item:TMenuItem; ACanvas: TCanvas; ARect: TRect;


  Selected: Boolean);


var


  dc,y,i,j,xb,xe:integer;


begin


  //設定字型和其前景色


  ACanvas.Font := Screen.IconFont;


  SetBkMode(ACanvas.Handle,TRANSPARENT);  //設背景為透明


 


  //根椐選單寬度計算漸變背景色的填充色增量;當選單寬度大於256時沒有漸變較果


  dc:=ACanvas.ClipRect.Right-ACanvas.ClipRect.Left;


  dc:=(256 div dc);


  dc:=dc*256;


 


  //計算漸變背景色的填充起點


  xb:=ARect.Left + ImageList1.Width+2;


 


  //計算漸變背景色的填充終點


  xe:=ARect.Right-xb;


 


  //繪製背景圖


  ACanvas.StretchDraw(Rect(0,0,ACanvas.ClipRect.Right,ACanvas.ClipRect.Bottom),


  CoolBar1.Bitmap);//非平輔方式繪製


 


  //繪製選單項文字


  for j:=0 to Item.Parent.Count -1 do


  begin


  y:=19*j+4;


  ACanvas.TextOut(ARect.Left+20,y,Item.Parent.Items[j].Caption);//front color is black font


  end;


 


  //繪製當前選擇的選單項


  if Selected then begin


  for i:=0 to  xe do begin


  ACanvas.Brush.Color := $002222FF+i*dc;  //背景的填充色,$002222FF為起始色


  ACanvas.FillRect(Rect(xb,ARect.Top,xb+1,ARect.Bottom));


  inc(xb);


  end;


  ImageList1.Draw(ACanvas,ARect.Left+1,ARect.Top+1,0,true);  //在左邊繪製圖示


  ACanvas.Font.Color:=clWhite;  //被選中時的字型前景色是白色


  SetBkMode(ACanvas.Handle,TRANSPARENT);  //必須重設背景模式為透明


  ACanvas.TextOut(ARect.Left+20,ARect.Top+4,Item.Caption);//front color,which is white font


  end;


end;


在各選單項的OnDrawItem事件處(如五所示)均呼叫此過程,執行程式可以看到一個有背景圖、所選選單項左邊有一個圖示且背景色是由紅到黃漸變的選單。


㈡ 以下是實現上述個性化選單的自定義過程DrawItem的另一個示例的程式碼。為一個有圖示的彈出式選單,不作過多的說明了。


procedure TForm1.DrawItem(Item:TMenuItem; ACanvas: TCanvas; ARect: TRect; Selected: Boolean);


var


  i,xb:integer;


begin


  //設定字型和其前景色


  ACanvas.Font := Screen.IconFont;


  ACanvas.Brush.Color := clBtnFace;


  ACanvas.FillRect(ARect);


  ACanvas.TextOut(ARect.Left+20,ARect.Top+4,Item.Caption);


 


  if Selected then begin


  //繪製當前選擇的選單項


  xb:=0;


  for i:=0 to ARect.Right do begin


  ACanvas.Brush.Color :=clTeal+i*$100;//gradient back color


  ACanvas.FillRect(Rect(xb,ARect.Top,xb+1,ARect.Bottom));


  inc(xb);


  end;


  ACanvas.Font.Color:=clWhite;//被選中時的字型前景色是白色


  SetBkMode(ACanvas.Handle,TRANSPARENT);


  ACanvas.TextOut(ARect.Left+20,ARect.Top+4,Item.Caption);


  end;


  ImageList1.Draw(ACanvas,ARect.Left+1,ARect.Top+1,Item.ImageIndex,true);//繪製左邊的圖示


end;


同理,應在各選單項的OnDrawItem事件處均呼叫此過程。



七、小結


使用自繪式選單,對整個選單進行全面的重繪,可以任其想象發揮,繪出五顏六色的個性化選單,極大地豐富程式介面。
  此外,用此方法雖然簡單但較率較低,不適合做要求較高的。高階的做法是全部使用WindowsAPI和訊息。
  需要示例示的,請到留言,一定給你。


來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/10752043/viewspace-992264/,如需轉載,請註明出處,否則將追究法律責任。

相關文章