Private Declare Function GetMenu Lib "user32" (ByVal hwnd As Long) As Long
Private Declare Function GetSubMenu Lib "user32" (ByVal hMenu As Long, ByVal nPos As Long) As Long
Private Declare Function SetMenuItemBitmaps Lib "user32" (ByVal hMenu As Long, ByVal nPosition As Long, ByVal wFlags As Long, ByVal hBitmapUnchecked As Long, ByVal hBitmapChecked As Long) As Long
我们先来声明API函数,本例中用到的三个函数声明如下:
Private Declare Function GetMenu Lib "user32" (ByVal hwnd As Long) As Long
Private Declare Function GetSubMenu Lib "user32" (ByVal hMenu As Long, ByVal nPos As Long) As Long
Private Declare Function SetMenuItemBitmaps Lib "user32" (ByVal hMenu As Long, ByVal nPosition As Long, ByVal wFlags As Long, ByVal hBitmapUnchecked As Long, ByVal hBitmapChecked As Long) As Long
下面的这段代码将Picture1的图形作为菜单项。
首先建立一个模块,并加入下面的语句。
Declare Function GetMenu Lib "user32" _
(ByVal hwnd As Long) As Long
Declare Function GetSubMenu Lib "user32" _
(ByVal hMenu As Long, ByVal nPos As Long) As Long
Declare Function GetMenuItemID Lib "user32" _
(ByVal hMenu As Long, ByVal nPos As Long) As Long
Declare Function SetMenuItemBitmaps Lib "user32" _
(ByVal hMenu As Long, ByVal nPosition As Long, _
ByVal wFlags As Long, ByVal hBitmapUnchecked As Long, _
ByVal hBitmapChecked As Long) As Long
Public Const MF_BITMAP = &H4&
Type MENUITEMINFO
cbSize As Long
fMask As Long
fType As Long
fState As Long
wID As Long
hSubMenu As Long
hbmpChecked As Long
hbmpUnchecked As Long
dwItemData As Long
dwTypeData As String
cch As Long
End Type
Declare Function GetMenuItemCount Lib "user32" _
(ByVal hMenu As Long) As Long
Declare Function GetMenuItemInfo Lib "user32" _
Alias "GetMenuItemInfoA" (ByVal hMenu As Long, _
ByVal un As Long, ByVal b As Boolean, _
lpMenuItemInfo As MENUITEMINFO) As Boolean
Public Const MIIM_ID = &H2
Public Const MIIM_TYPE = &H10
Public Const MFT_STRING = &H0&
将下面的代码加入一个按钮的Click事件:
Private Sub Command1_Click()
' 获得你的菜单的句柄
hMenu& = GetMenu(Form1.hwnd)
' 获得第一个子菜单的句柄
hSubMenu& = GetSubMenu(hMenu&, 0)
' 获得第一个菜单项
hID& = GetMenuItemID(hSubMenu&, 0)
'加入位图
SetMenuItemBitmaps hMenu&, hID&, MF_BITMAP, _
Picture1.Picture, _
Picture1.Picture
End Sub
上面的代码使菜单项为图片,如果你只希望菜单项的左边有一个小位图,而右边仍为文字。可以先在Picture1绘制图片,在利用Picture1.Print加上文字,然后用Picture1.Picture加入菜单项。
在Visual Basic中开始一个新的工程,采用缺省的方法建立Form1。
创建一个新的模块,采用缺省的方法建立Module1.Bas。
将如下的声明语句和常量添加到Module1.Bas模块中:
Option Explicit
Declare Function GetMenu Lib "user32" (ByVal hwnd As Long) As Long
Declare Function GetSubMenu Lib "user32" (ByVal hMenu As Long,
ByVal nPos As Long) As Long
Declare Function GetMenuItemID Lib "user32" (ByVal hMenu As Long,
ByVal nPos As Long) As Long
Declare Function ModifyMenu Lib "user32" Alias "ModifyMenuA"
(ByVal hMenu As Long,ByVal nPosition As Long, ByVal wFlags As Long,
ByVal wIDNewItem As Long, ByVal lpString As Any) As Long
Declare Function CreateCompatibleDC Lib "gdi32" (ByVal hdc As Long) As
Long
Declare Function DeleteDC Lib "gdi32" (ByVal hdc As Long) As Long
Declare Function CreateCompatibleBitmap Lib "gdi32"
(ByVal hdc As Long, ByVal nWidth As Long, ByVal nHeight As Long) As Long
Declare Function SelectObject Lib "gdi32" (ByVal hdc As Long,
ByVal hObject As Long) As Long
Declare Function BitBlt Lib "gdi32" (ByVal hDestDC As Long, ByVal x As
Long,
ByVal y As Long, ByVal nWidth As Long, ByVal nHeight As Long, ByVal
hSrcDC
As Long, ByVal xSrc As Long, ByVal ySrc As Long, ByVal dwRop As Long) As
Long
Public Const SRCCOPY = &HCC0020
Public Const MF_BYPOSITION = &H400&
Public Const MF_BITMAP = &H4&
注意上面的声明语句需要书写在一行内。
在Form1上添加4个图形框控件,将它们的Name属性设置为Picture1,将它们的
Index属性依次设置为0,1,2,3,将它们的AutoRedrew属性设置为True,将它们
的AutoResize属性设置为Ture,以及将它们的Visable属性设置为False。
将上面的4个图形框控件的Picture属性依次设置为Face1.ico,Face2.ico,Face3.
ico,Face4.ico。
在Form1上添加第一个菜单项,将它的标题设置为“[&F]文件”,名称设置为
mnuFile。在其下添加一个子菜单项,将它的标题设置为“[&E]退出”,名称设置
为mnuExit。
在Form1上添加第二个菜单项,将它的标题设置为“[&A]脸谱”,名称设置为
mnuFace。在其下添加4个子菜单项,分别将改4个子菜单项的名称设置为“[N]正常”
,“[&S]微笑”,“ [&L]大笑”,以及“[&O]悲伤”。将它们的名称设置为“
mnuFaceSel”,并相应将这4个子菜单项的索引设置为0,1,2,3。
将如下的代码添加到Form1的Form_Load事件中:
Private Sub Form_Load()
Dim nLoopCtr As Integer
Dim lResult As Long
Dim hTempDC As Long
Dim nWidth As Integer
Dim nHeight As Integer
Dim lTempID As Long
Dim hMenuID As Long
Dim lItemCount As Long
Dim hBitmap As Long
nWidth = Picture1(nLoopCtr).Width \ Screen.TwipsPerPixelX
nHeight = Picture1(nLoopCtr).Height \ Screen.TwipsPerPixelY
hMenuID = GetSubMenu(GetMenu((Me.hwnd)), 1)
hTempDC = CreateCompatibleDC(Picture1(nLoopCtr).hdc)
For nLoopCtr = 0 To 3
hBitmap = CreateCompatibleBitmap(Picture1(nLoopCtr).hdc, nWidth,
nHeight)
lTempID = SelectObject(hTempDC, hBitmap)
lResult = BitBlt(hTempDC, 0, 0, nWidth, nHeight, (Picture1(
nLoopCtr).hdc), 0, 0, SRCCOPY)
lTempID = SelectObject(hTempDC, lTempID)
nuFaceSel(nLoopCtr).Caption = ""
lResult = ModifyMenu(hMenuID, nLoopCtr, MF_BYPOSITION Or
MF_BITMAP,
GetMenuItemID(hMenuID, nLoopCtr), hBitmap)
Next nLoopCtr
lResult = DeleteDC(hTempDC)
End Sub
将如下的代码添加到“退出”子菜单的单击事件中:
Private Sub mnuExit_Click(Index As Integer)
Select Case Index
Case 0
Unload Me
End Select
End Sub
运行该样例程序,单击“脸谱”菜单,则会看到由4个脸谱图标所形成的位图子菜
单项,如图1所示。单击“文件”\“退出”菜单可退出应用程序。
'-------------------------------------------------
' 让菜单中出现图标一法
'-------------------------------------------------
' 洪恩在线 求知无限
'-------------------------------------------------
'程序应用三个API函数实现了在菜单项中加入小图标
'GetMenu、GetSubMenu、SetMenuItemBitmaps
'-------------------------------------------------
Option Explicit
'【VB声明】
' Private Declare Function GetMenu Lib "user32" (ByVal hwnd As Long) As Long
'【说明】
' 取得窗口中一个菜单的句柄
'【返回值】
' Long,依附于指定窗口的一个菜单的句柄(如果有菜单);否则返回零
'【参数表】
' hwnd ----------- Long,窗口句柄。对于vb,这应该是一个窗体句柄。注意可能不是子窗口的句柄
Private Declare Function GetMenu Lib "user32" _
(ByVal hwnd As Long) As Long
'-------------------------------------------------
'【VB声明】
' Private Declare Function GetSubMenu Lib "user32" (ByVal hMenu As Long, ByVal nPos As Long) As Long
'【说明】
' 取得一个弹出式菜单的句柄,它位于菜单中指定的位置
'【返回值】
' Long,位于指定位置的弹出式菜单的句柄(如果有的话);否则返回零
'【参数表】
' hMenu ---------- Long,菜单的句柄
' nPos ----------- Long,条目在菜单中的位置。第一个条目的编号为0
Private Declare Function GetSubMenu Lib "user32" _
(ByVal hMenu As Long, ByVal nPos As Long) As Long
'-------------------------------------------------
'【VB声明】
' Private Declare Function SetMenuItemBitmaps Lib "user32" (ByVal hMenu As Long, ByVal nPosition As Long, ByVal wFlags As Long, ByVal hBitmapUnchecked As Long, ByVal hBitmapChecked As Long) As Long
' hBitmapChecked - Long,复选时为菜单条目显示的一幅位图的句柄。可设为零,表示复选时不显示任何标志。如两个位图句柄的值都是零,则为这个条目恢复使用默认复选位图
Private Declare Function SetMenuItemBitmaps Lib "user32" _
(ByVal hMenu As Long, ByVal nPosition As Long, ByVal wFlags As Long, _
ByVal hBitmapUnchecked As Long, ByVal hBitmapChecked As Long) As Long
'-------------------------------------------------
Const MF_BYPOSITION = &H400&
Private Sub Form_Load()
Dim mHandle As Long, lRet As Long, sHandle As Long, sHandle2 As Long
'取得菜单的句柄并赋值给mHandle
mHandle = GetMenu(hwnd)
'取得mHandle句柄所指菜单的第一个弹出式菜单(文件&F)的句柄并赋值给sHandle
sHandle = GetSubMenu(mHandle, 0)
'将弹出式菜单的第0-4项加上图片,为什么跳过2呢?因为2是分割线
lRet = SetMenuItemBitmaps(sHandle, 0, MF_BYPOSITION, imOpen.Picture, imSave.Picture)
lRet = SetMenuItemBitmaps(sHandle, 1, MF_BYPOSITION, imSave.Picture, imSave.Picture)
lRet = SetMenuItemBitmaps(sHandle, 3, MF_BYPOSITION, imPrint.Picture, imPrint.Picture)
lRet = SetMenuItemBitmaps(sHandle, 4, MF_BYPOSITION, imPrintSetup.Picture, imPrintSetup.Picture)
'取得mHandle句柄所指菜单的第二个弹出式菜单(编辑&E)的句柄并赋值给sHandle
sHandle = GetSubMenu(mHandle, 1)
'取得sHandle句柄所指菜单的第一个次级菜单(次级菜单&S)的句柄并赋值给sHandle2
sHandle2 = GetSubMenu(sHandle, 0)
'将次级菜单中的第1项加上图片
lRet = SetMenuItemBitmaps(sHandle2, 0, MF_BYPOSITION, imCopy.Picture, imCopy.Picture)
'提示:在SetMenuItemBitmaps()我们把后两项设为相同的图片,如果设为不同的两张图片会有什么效果呢?
' 原来这两张图片分别表示复选和撤消复选时的状态,你只须在菜单项被点击的函数中加入以下语句:
' Private Sub mnuOpen_Click()
' If mnuOpen.Checked = True Then
' mnuOpen.Checked = False
' Else: mnuOpen.Checked = True
' End If
' End Sub
' 然后在SetMenuItemBitmaps()我们把后两项设为不同的图片即可,有兴趣的话试一试。
End Sub