菜單(Menu)是程序界面的重要架構部件自從有了可視化編程工具使用其中的菜單編輯器就可以方便快捷的編輯設計菜單但要想制作出個性化的菜單哪怕對菜單項的任何改變如改變菜單的字體類型大小等只使用菜單編輯器是無法完成了可視化編程工具Visual 也是如此本文的主要內容就是介紹利用Visual Basic Net手工繪制個性化菜單的實現方法
一.簡介Net Frame Work SDK 為在VBNet繪制菜單提供的工具
Net Frame Work SDK為Visual Basic Net實現個性化菜單提供了許多工具其中最重要是二個事件及其參數DrawItem事件和其中的DrawItemEventArgs參數MeasureItem事件和其中的MeasureItemEventArgs參數
DrawItem事件和其中的DrawItemEventArgs參數
DrawItem事件是當菜單項的OwnerDraw屬性設置為True並且發出繪制菜單項的請求時才發生個性化菜單制作的處理方法就是在此事件中完成的在DrawItem事件處理程序中將接收一個 DrawItemEventArgs類型的參數它包含與此事件相關的數據這些數據對繪制菜單是很重要的表是DrawItemEventArgs類型參數提供特定於此事件的信息
屬性 說明
BackColor 獲取所繪制的項的背景色
Bounds 獲取表示所繪制項的邊界的矩形
Font 獲取分配給所繪制項的字體
ForeColor 獲取所繪制項的前景色
Graphics 獲取要在其上繪制項的圖形表面
Index 獲取所繪制項的索引值
State 獲取所繪制項的狀態
表DrawItemEventArgs類型參數提供DrawItem事件特定的信息
MeasureItem事件和其中的MeasureItemEventArgs參數
觸發MeasureItem事件必須將菜單項的OwnerDraw屬性設置為True個性化菜單制作可通過此事件來獲取設定菜單項的大小等MeasureItem事件處理程序中接收一個MeasureItemEventArgs類型的參數此參數對獲取設定菜單項的大小是非常重要的表是MeasureItemEventArgs類型參數提供MeasureItem事件的特定信息
屬性 說明
Graphics 獲取要測量的Graphics對象
Index 獲取設置需要有高度和寬度的項索引
ItemHeight 獲取設置由Index指定的項高度
ItemWidth 獲取設置由Index指定的項
表是MeasureItemEventArgs類型參數提供MeasureItem事件的特定信息
二.本文介紹程序的設計調試運行的軟件環境
()微軟公司視窗服務器版
()Visual Studio Net正式版Net Framework SDK版本號
三.循序漸進繪制自己的菜單
為了加深理解我們用菜單編輯器設計一個簡單的菜單然後在此基礎上加上個性化定制重新繪制個性化的菜單以下步驟就是利用Visual Studio的菜單編輯器制作一個簡單的菜單
啟動Visual Studio Net
選擇菜單【文件】|【新建】|【項目】後彈出【新建項目】對話框
將【項目類型】設置為【Visual Basic項目】
將【模板】設置為【Windows應用程序】
在【名稱】文本框中輸入【Visual Basic Net編程之DIY自己畫菜單】
在【位置】的文本框中輸入【E:\項目】然後單擊【確定】按鈕這樣在E:\VSNET項目目錄中就產生了名稱為Visual Basic Net編程之DIY自己畫菜單的文件夾並在裡面創建了名稱為Visual Basic Net編程之DIY自己畫菜單的項目文件
把Visual Studio Net的當前窗口切換到【Formvb(設計)】窗口並從【工具箱】中的【Windows窗體組件】選項卡中往Form窗體中拖入下列組件一個MainMenu組件名稱為MainMenu
選中MainMenu組件單擊鼠標右鍵在彈出的菜單中選擇編輯菜單並按照圖所示界面設計菜單
圖
【Visual Basic
Net編程之DIY
自己畫菜單】項目設計界面之一
此時保存上述步驟並單擊快捷鍵F則得到圖所示界面
圖
【Visual Basic
Net編程之DIY
自己畫菜單】運行界面之一
這樣通過菜單編輯器就完成了一個非常普通的菜單下面就對此菜單進行改造在改造之前要先設定項目中的三個MenuItem類實例的OwnerDraw屬性值為True因為只有此屬性值為True才會觸發繪制菜單時所需要的DrawItem事件和MeasureItem事件之後再在上面項目的基礎上執行下一步操作
把Visual 的當前窗口切換到FormVB的代碼編輯窗口並在InitializeComponent過程之後添加下列代碼下列代碼是繪制文件菜單項其作用是改變文件菜單項的字體大小和菜單項的其具體的繪制方法請參考下列代碼中的注釋
Private Sub MenuItem_DrawItem ( ByVal sender As Object ByVal e As SystemWindowsFormsDrawItemEventArgs ) Handles MenuItemDrawItem
Dim rfBound As RectangleF = New RectangleF ( eBoundsX eBoundsY eBoundsWidth eBoundsHeight )
根據DrawItemEventArgs參數獲得菜單項矩形區域並存儲到RectangleF類型實例中
Dim rfBound As Rectangle = New Rectangle ( eBoundsX eBoundsY eBoundsWidth eBoundsHeight )
根據DrawItemEventArgs參數獲得菜單項矩形區域並存儲到Rectangle類型實例中
Rectangle類型實例和RectangleF類型實例差不多但在後面代碼中繪制菜單的函數是有區別的
eGraphicsFillRectangle(New SolidBrush(ColorLightGreen) rfBound)
以LightGreen色彩填充MenuItem菜單項對應的矩形區域
Dim s As MenuItem = CType ( sender MenuItem )
Dim s As String = sText
獲得MenuItem菜單項的名稱
Dim sfTemp As StringFormat = New StringFormat ( )
sfTempAlignment = StringAlignmentCenter
設定要畫的菜單名稱的對齊方式中間對齊
eGraphicsDrawString ( s New Font ( 宋體 FontStyleBold ) New SolidBrush ( ColorBlack ) rfBound sfTemp )
以中間對齊方式指定字體大小在指定的矩形區域重畫菜單
If eState = ( DrawItemStateNoAccelerator Or DrawItemStateSelected ) Then
根據菜單項的當前繪制狀態來繪制菜單項
eGraphicsFillRectangle ( New SolidBrush ( ColorLightYellow ) rfBound )
對菜單項所在的矩形區域進行色彩填充
eGraphicsDrawString ( s New Font ( 宋體 FontStyleBold ) New SolidBrush ( ColorBlack ) rfBound sfTemp )
對菜單項名稱繪制
End If
eDrawFocusRectangle ( )
在 DrawItemEventArgs參數得到矩形范圍內繪制聚焦框
eGraphicsDrawRectangle ( New Pen ( New SolidBrush ( ColorBlack ) ) rfBound )
對菜單項的矩形區域繪制矩形框
End Sub
操作完成後保存修改此時再單擊快捷鍵F運行程序可得到如圖所示的界面
圖【Visual Basic Net編程之DIY自己畫菜單】運行界面之二
可見繪制的文件菜單項並沒有完全顯示出來並且後面的菜單項也沒有顯示這是因為菜單項的顯示區域並沒有設定而缺省的空間又不能完全顯示造成的設定菜單項的顯示區域大小是通過MeasureItem事件來完成的具體操作是在MenuItem的DrawItem事件後添加下列代碼下列代碼是是定義MenuItem的MeasureItem事件在此事件中設定菜單項的寬度(當然也可以設定高度等)
Private Sub MenuItem_MeasureItem ( ByVal sender As Object ByVal e As SystemWindowsFormsMeasureItemEventArgs ) Handles MenuItemMeasureItem
eItemWidth =
設定菜單項的寬度
End Sub
保存上述修改後單擊快捷鍵F運行程序可得到圖所示界面
圖【Visual Basic Net編程之DIY自己畫菜單】運行界面之三
可見文件菜單項就算繪制出來了由於其他菜單項沒有繪制處理所以也未顯示其他菜單項的繪制方法和文件菜單項的繪制方法基本相似以下是在上述完成的基礎上對其他菜單項進行繪制從而得到圖所示菜單的具體實現步驟
圖【Visual Basic Net編程之DIY自己畫菜單】運行界面之四
在FormVB中的MenuItem的MeasureItem事件處理程序之後添加下列代碼下列代碼是定義MenuItem的DrawItem事件其功能是對新建菜單項重新繪制
Private Sub MenuItem_DrawItem ( ByVal sender As Object ByVal e As SystemWindowsFormsDrawItemEventArgs ) Handles MenuItemDrawItem
Dim rfBound As RectangleF = New RectangleF ( eBoundsX eBoundsY eBoundsWidth eBoundsHeight )
根據DrawItemEventArgs參數獲得菜單項矩形區域並存儲到RectangleF類型實例中
Dim rfBound As Rectangle = New Rectangle ( eBoundsX eBoundsY eBoundsWidth eBoundsHeight )
根據DrawItemEventArgs參數獲得菜單項矩形區域並存儲到Rectangle類型實例中
Rectangle類型實例和RectangleF類型實例差不多但在後面代碼中繪制菜單的函數是有區別的
eGraphicsFillRectangle ( New SolidBrush ( ColorLightGray ) rfBound )
Dim s As MenuItem = CType ( sender MenuItem )
Dim s As String = sText
獲得菜單項對應的文本名稱
Dim sfTemp As StringFormat = New StringFormat ( )
sfTempAlignment = StringAlignmentCenter
設定文本在矩形區域的對齊方式
sfTempLineAlignment = StringAlignmentCenter
Dim rcText As RectangleF = rfBound
rcTextWidth =
eGraphicsDrawString ( s New Font ( 宋體 ) New SolidBrush ( ColorBlue ) rcText sfTemp )
eGraphicsDrawRectangle ( New Pen ( New SolidBrush ( ColorLightGray ) ) rfBound )
If eState = ( DrawItemStateNoAccelerator Or DrawItemStateSelected ) Then
eGraphicsFillRectangle ( New SolidBrush ( ColorLightYellow ) rfBound )
eGraphicsDrawString ( s New Font ( 宋體 FontStyleBold Or FontStyleUnderline ) New SolidBrush ( ColorRed ) rcText sfTemp )
eGraphicsDrawRectangle ( New Pen ( New SolidBrush ( ColorBlack ) ) rfBound )
eDrawFocusRectangle ( )
End If
End Sub
MenuItem的DrawItem事件處理代碼之後添加下列代碼下列代碼是定義MenuItem的MeasureItem事件在此事件中實現設定新建菜單項的長度和高度
Private Sub MenuItem_MeasureItem ( ByVal sender As Object ByVal e As SystemWindowsFormsMeasureItemEventArgs ) Handles MenuItemMeasureItem
eItemWidth =
設定菜單項的寬度
eItemHeight =
設定菜單項的高度
End Sub
在完成上述操作步驟後再在MenuItem的MeasureItem事件處理程序之後添加下列代碼下列代碼是定義MenuItem的DrawItem事件其功能是對打開菜單項重新繪制
Private Sub MenuItem_DrawItem ( ByVal sender As Object ByVal e As SystemWindowsFormsDrawItemEventArgs ) Handles MenuItemDrawItem
Dim rfBound As RectangleF = New RectangleF ( eBoundsX eBoundsY eBoundsWidth eBoundsHeight )
根據DrawItemEventArgs參數獲得菜單項矩形區域並存儲到RectangleF類型實例中
Dim rfBound As Rectangle = New Rectangle ( eBoundsX eBoundsY eBoundsWidth eBoundsHeight )
根據DrawItemEventArgs參數獲得菜單項矩形區域並存儲到Rectangle類型實例中
Rectangle類型實例和RectangleF類型實例差不多但在後面代碼中繪制菜單的函數是有區別的
Dim s As MenuItem = CType ( sender MenuItem )
Dim s As String = sText
Dim sfTemp As StringFormat = New StringFormat ( )
sfTempAlignment = StringAlignmentCenter
sfTempLineAlignment = StringAlignmentCenter
Dim rcText As RectangleF = rfBound
rcTextWidth =
eGraphicsDrawString ( s New Font ( Veranda ) New SolidBrush ( ColorBlue ) rcText sfTemp )
eGraphicsDrawRectangle ( New Pen ( New SolidBrush ( ColorLightGray ) ) rfBound )
If eState = ( DrawItemStateNoAccelerator Or DrawItemStateSelected ) Then
eGraphicsFillRectangle ( New SolidBrush ( ColorLightYellow ) rfBound )
eGraphicsDrawString ( s New Font ( Veranda FontStyleBold Or FontStyleUnderline ) New SolidBrush ( ColorRed ) rcText sfTemp )
eGraphicsDrawRectangle ( New Pen ( New SolidBrush ( ColorBlack ) ) rfBound )
eDrawFocusRectangle ( )
End If
End Sub
MenuItem的DrawItem事件處理代碼之後添加下列代碼下列代碼是定義MenuItem的MeasureItem事件在此事件中實現設定新建菜單項的長度和高度
Private Sub MenuItem_MeasureItem ( ByVal sender As Object ByVal e As SystemWindowsFormsMeasureItemEventArgs ) Handles MenuItemMeasureItem
eItemWidth =
設定菜單項的寬度
eItemHeight =
設定菜單項的高度
End Sub
在上述步驟都正確完成後本文介紹的手工繪制菜單就完成此時單擊快捷鍵F運行
程序就可以得到圖所示的運行界面
四.總結
Visual 中實現繪制菜單最重要的是掌握DrawItem事件和MeasureItem事件用法及其繪制菜單時所要使用到的各種圖形圖象方法如繪制名稱色彩填充等當然在繪制菜單時首先把菜單項的OwnerDraw屬性設定為True因為這是觸發DrawItem事件和MeasureItem事件的前提本文實現的菜單雖不美觀但本文介紹的方法卻是很實用的在上述項目的基礎上進行一定的修改如再調用其他的繪制方法一定可以完成一個更美觀的菜單來
From:http://tw.wingwit.com/Article/program/net/201311/13385.html