添加菜单/自定义菜单/弹出式菜单(转集)

 'Module_menu 文件是添加菜单有关的东西,原先最开始会出自动关了程序

'后来又找了个源码,原来是那个MF_STRING,MF_SEPARATOR得用地址表示,不出错了,可是没看到效果

'最后比较幸运找到了HUSTSOFT的演示代码,才看到,原来第二次的已经可以,不过那是加在窗口上的系统菜单。而这个源码里面还包括了,窗口内菜单的自定义。


''本代码,集了三次找到的源码,有些代码没删,有些要写到FORM_LOAD的删了,保留了第一次的~2008-10-18
'-------------------------------------------------


''Form_load中的代码
    'AddMenu Me
    'SysMenuHwnd = GetSystemMenu(Me.hwnd, 0)
    'Call AppendMenu(SysMenuHwnd, MF_SEPARATOR, 8000, vbNullString)
    'Call AppendMenu(SysMenuHwnd, MF_STRING, 8001, "关于本程序(&A)")
    'Call AppendMenu(SysMenuHwnd, MF_SEPARATOR, 8002, vbNullString)
    'Call AppendMenu(SysMenuHwnd, MF_STRING, 8003, "恢复系统菜单(&R)")

    'Dim mSysMenu As Long
    'Dim mMenu As Long
    'Dim mSubMenu As Long
   
    'mSysMenu = GetSystemMenu(Me.hwnd, False)
    'AppendMenu mSysMenu, MF_SEPARATOR, 0, "-" '因为本工程名字也是AppendMenu,所以只好改函数名了
    'AppendMenu mSysMenu, MF_STRING, mAddItemId, "VB广场"
   
    'mMenu = GetMenu(Me.hwnd)
    'mSubMenu = GetSubMenu(mMenu, 0)
    'AppendMenu mSubMenu, MF_SEPARATOR, 0, "-"
    'AppendMenu mSubMenu, MF_STRING, mFileId, "文件"
    'AppendMenu mSubMenu, MF_STRING + MF_GRAYED + MF_CHECKED, mSaveId, "保存"

'-------------------------------------------------

'以下是第四次集到的,主要是增加了图标的设置功能,某个单项的操作
'API的集体声明及说明请从http://www.vbgood.com/上查找


'【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

'【说明】
'  设置一幅特定位图,令其在指定的菜单条目中使用,代替标准的复选符号(√)。位图的大小必须与菜单复选符号的正确大小相符,这个正确大小可以由GetMenuCheckMarkDimensions函数获得

'【返回值】
'  Long,非零表示成功,零表示失败。会设置GetLastError

'【备注】
'  使用的位图可能由多个条目共享。一旦不再需要,位图必须由应用程序清除,因为windows不能自动对它进行清除

'【参数表】
'  hMenu ----------  Long,菜单句柄

'  nPosition ------  Long,欲设置位图的一个菜单条目的标识符。如在wFlags参数中指定了MF_BYCOMMAND,这个参数就代表欲改变的菜单条目的命令ID。如设置的是MF_BYPOSITION,这个参数就代表菜单条目在菜单中的位置(第一个条目的位置为零)

'  wFlags ---------  Long,常数MF_BYCOMMAND或MF_BYPOSITION,取决于nPosition参数

'  hBitmapUnchecked -  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
'-------------------------------------------------

 

  1. '菜单API函数声明
  2. Public Declare Function AppendMenu Lib "user32" Alias "AppendMenuA" (ByVal hMenu As LongByVal wFlags As LongByVal wIDNewItem As LongByVal lpNewItem As Any) As Long
  3. Public Declare Function ModifyMenu& Lib "user32" Alias "ModifyMenuA" (ByVal hMenu As LongByVal nPosition As LongByVal wFlags As LongByVal wIDNewItem As LongByVal lpString As String)
  4. Public Declare Function ModifyMenuBynum& Lib "user32" Alias "ModifyMenuA" (ByVal hMenu As LongByVal nPosition As LongByVal wFlags As LongByVal wIDNewItem As LongByVal lpString As Long)
  5. Public Declare Function DrawMenuBar Lib "user32" (ByVal hwnd As LongAs Long
  6. ''
  7. Public Declare Function GetSystemMenu Lib "user32" (ByVal hwnd As LongByVal bRevert As LongAs Long
  8. Public Declare Function GetMenu Lib "user32" (ByVal hwnd As LongAs Long
  9. Public Declare Function GetSubMenu Lib "user32" (ByVal hMenu As LongByVal nPos As LongAs Long
  10. ''创建菜单
  11. Public Declare Function CreateMenu Lib "user32" () As Long
  12. Public Declare Function CreatePopupMenu Lib "user32" () As Long                            '弹出菜单
  13. Public Declare Function InsertMenu Lib "user32" Alias "InsertMenuA" (ByVal hMenu As LongByVal nPosition As LongByVal wFlags As LongByVal wIDNewItem As LongByVal lpNewItem As Any) As Long
  14. Public Declare Function DestroyMenu Lib "user32" (ByVal hMenu As LongAs Long  '释放菜单
  15. '在屏幕的任意地方显示一个弹出式菜单
  16. Public Declare Function TrackPopupMenu& Lib "user32" (ByVal hMenu As LongByVal wFlags As LongByVal x As LongByVal y As LongByVal nReserved As LongByVal hwnd As Long, lprc As RECT)
  17. Public Declare Function TrackPopupMenuBynum& Lib "user32" Alias "TrackPopupMenu" (ByVal hMenu As LongByVal wFlags As LongByVal x As LongByVal y As LongByVal nReserved As LongByVal hwnd As LongByVal lprc As Long)
  18. '有关窗口函数的API函数声明
  19. Public Declare Function GetWindowLong Lib "user32" Alias "GetWindowLongA" (ByVal hwnd As LongByVal nIndex As LongAs Long
  20. Public Declare Function SetWindowLong Lib "user32" Alias "SetWindowLongA" (ByVal hwnd As LongByVal nIndex As LongByVal dwNewLong As LongAs Long
  21. Public Declare Function CallWindowProc Lib "user32" Alias "CallWindowProcA" (ByVal lpPrevWndFunc As LongByVal hwnd As LongByVal Msg As LongByVal wParam As LongByVal lParam As LongAs Long
  22. Public Declare Function DefWindowProc Lib "user32" Alias "DefWindowProcA" (ByVal hwnd As LongByVal wMsg As LongByVal wParam As LongByVal lParam As LongAs Long
  23. ''取单个项ID,设置位图
  24. Public Declare Function GetMenuItemID Lib "user32" (ByVal hMenu As LongByVal nPos As LongAs Long
  25. Public Declare Function SetMenuItemBitmaps Lib "user32" (ByVal hMenu As LongByVal nPosition As LongByVal wFlags As LongByVal hBitmapUnchecked As LongByVal hBitmapChecked As LongAs Long
  26. Public Declare Function GetMenuItemCount Lib "user32" (ByVal hMenu As LongAs Long
  27. Public Declare Function GetMenuItemInfo Lib "user32" Alias "GetMenuItemInfoA" (ByVal hMenu As LongByVal un As LongByVal b As Boolean, lpMenuItemInfo As MENUITEMINFO) As Boolean
  28. '菜单API函数常数声明
    Public Const MF_BYCOMMAND = &H0
    Public Const MF_GRAYED = &H1&
    Public Const MF_DISABLED = &H2&
    Public Const MF_BITMAP = &H4&
    Public Const MF_CHECKED = &H8&
    Public Const MF_POPUP = &H10&
  29. Public Const MF_BYPOSITION = &H400&
    ' 为菜单加一条分隔线
    Public Const MF_SEPARATOR = &H800&
    ' 单击控制框产生此消息
    Public Const MF_STRING = &H0&
  30. ' 在菜单中加一个字符串
    Public Const GWL_WNDPROC = (-4)
  31. ' 常数声明
    Public Const WM_COMMAND = &H111
    Public Const WM_SYSCOMMAND = &H112
    Public Const WM_NCLBUTTONDOWN = &HA1
    Public Const WM_NCRBUTTONDOWN = &HA4
    Public Const WM_USER As Long = &H1000  '用户ID
  32. Public Const MIIM_ID = &H2
    Public Const MIIM_TYPE = &H10
  33. ''消息
    Public Const HTSYSMENU = 3
    Public Const HTCAPTION = 2
  34. ''自定义菜单项的标识号偏移量
    Public Const IDM_SEPARATOR = 1
    Public Const IDM_MYABOUT = 2
  35. ''其他变量
    Dim sHwnd As Long
    Dim OldProc As Long
    Dim mHwnd   As Long
  36. ' API函数声明
  37. Public Declare Function ShellExecute Lib "shell32.dll" Alias "ShellExecuteA" (ByVal hwnd As LongByVal lpOperation As StringByVal lpFile As StringByVal lpParameters As StringByVal lpDirectory As StringByVal nShowCmd As LongAs Long
  38. ' 全局变量
  39. Public OldWindowProc As Long
  40. ' 保存默认的窗口函数地址
  41. Public SysMenuHwnd As Long
  42. ' 保存系统菜单句柄
  43. Type MENUITEMINFO
  44.     cbSize As Long
  45.     fMask As Long
  46.     fType As Long
  47.     fState As Long
  48.     wID As Long
  49.     hSubMenu As Long
  50.     hbmpChecked As Long
  51.     hbmpUnchecked As Long
  52.     dwItemData As Long
  53.     dwTypeData As String
  54.     cch As Long
  55. End Type
  56. Type RECT
  57.     Left As Long
  58.     Top As Long
  59.     Right As Long
  60.     Bottom As Long
  61. End Type
  62. ''接着可向标准模块添加下面两个过程:
  63. '置换窗口函数过程
  64. Public Sub AddMenu(frm As Form)
  65.     sHwnd = frm.hwnd
  66.     OldProc = SetWindowLong(frm.hwnd, GWL_WNDPROC, AddressOf AddCallBack)
  67. End Sub
  68. ''释放自定义窗口函数过程
  69. Public Sub Release()
  70.     SetWindowLong sHwnd, GWL_WNDPROC, OldProc
  71. End Sub
  72. ''最后向标准模块中添加一自定义窗口函数过程:
  73. Public Function AddCallBack(ByVal hwnd As LongByVal wMsg As LongByVal wParam As LongByVal lParam As LongAs Long
  74.     Select Case wMsg
  75.     Case WM_SYSCOMMAND '这个是主菜单上的消息
  76.             AddCallBack = DefWindowProc(hwnd, wMsg, wParam, lParam)
  77.     Case WM_COMMAND '这个是子菜单的消息
  78.         'Debug.Print wParam - WM_USER, urls(wParam - WM_USER)
  79.         If wParam > WM_USER And wParam < WM_USER + &H1000 Then '自定义菜单
  80.             'MsgBox urls(wParam - WM_USER)
  81.             MDIForm_Main.openForm urls(wParam - WM_USER)
  82.         Else '其它菜单项交换系统处理
  83.             'Debug.Print wParam, WM_USER
  84.             AddCallBack = CallWindowProc(OldProc, hwnd, wMsg, wParam, lParam)
  85.         End If
  86.     Case Else
  87.         AddCallBack = CallWindowProc(OldProc, hwnd, wMsg, wParam, lParam)
  88.     End Select
  89. End Function
  90. ''
  91. Public Function SubClass1_WndMessage(ByVal hwnd As LongByVal Msg As LongByVal wp As LongByVal lp As LongAs Long
  92.     If Msg <> WM_SYSCOMMAND Then
  93.         SubClass1_WndMessage = CallWindowProc(OldWindowProc, hwnd, Msg, wp, lp)
  94.         ' 如果消息不是WM_SYSCOMMAND,就调用默认的窗口函数处理
  95.         Exit Function
  96.     End If
  97.     Select Case wp
  98.         Case 2001
  99.             Call MsgBox("本程序实现了修改系统菜单的功能  ", vbOKOnly + vbInformation)
  100.         Case 2003
  101.             Call GetSystemMenu(Form1.hwnd, True)
  102.             Call SetWindowLong(Form1.hwnd, GWL_WNDPROC, OldWindowProc)
  103.             Call MsgBox("已经恢复了默认的系统菜单  ", vbOKOnly + vbInformation)
  104.         Case Else
  105.             SubClass1_WndMessage = CallWindowProc(OldWindowProc, hwnd, Msg, wp, lp)
  106.             Exit Function
  107.     End Select
  108.     SubClass1_WndMessage = True
  109. End Function

 

 

  1. ''地址数组
  2. Public urls() As Variant
  3. ''收藏夹菜单
  4. Public Function getFavFolder()
  5.     getFavFolder = getVarFolder("userprofile") & "Favorites/"
  6. End Function
  7. ''环境变量
  8. Public Function getVarFolder(vName As String)
  9.     Dim doI As Long, buf As String
  10.     Dim denI As Long
  11.     
  12.     
  13.     ''找变量
  14.     Do
  15.         doI = doI + 1
  16.         buf = LCase(Environ(doI))
  17.         If buf = "" Then Exit Do
  18.         denI = InStr(buf, "=")
  19.         If Left(buf, denI - 1) = LCase(vName) Then
  20.             getVarFolder = Mid(buf, denI + 1) & "/"
  21.             Exit Do
  22.         End If
  23.     Loop Until buf = ""
  24. End Function
  25. ''环境变量
  26. Public Function appendFav(ByVal mHwnd As LongOptional vFolder As String = "")
  27.     Dim vName As String, tFld As String, tfldName As String
  28.     Dim tFldFull As String, vOldName As String
  29.     Dim smHwnd As Long, tmHwnd As Long
  30.     Static userNum As Long
  31.     'userNum = 10000
  32.     
  33.     If vFolder <> "" Then vName = vFolder Else vName = getFavFolder()
  34.     If Right(vName, 1) <> "/" Then vName = vName & "/"
  35.     vOldName = Form_Tools.Dir1.Path
  36.     Form_Tools.Dir1.Path = vName    '设置文件夹
  37.     Form_Tools.File1.Path = vName   '设置文件夹
  38.     
  39.     Dim vDir As Variant, vFile As Variant
  40.     Dim vDi As Long, vFi As Long
  41.     
  42.     
  43.     If Form_Tools.Dir1.ListCount > 0 Then AppendMenu mHwnd, MF_SEPARATOR, 0, "-" '分隔线
  44.     ''添加文件夹
  45.     For vDi = 0 To Form_Tools.Dir1.ListCount - 1
  46.         tFld = Form_Tools.Dir1.List(vDi)
  47.         tfldName = Mid(tFld, InStrRev(tFld, "/") + 1)
  48.         If tfldName <> "" Then
  49.             tmHwnd = CreatePopupMenu()
  50.             AppendMenu mHwnd, MF_POPUP, tmHwnd, tfldName
  51.             appendFav tmHwnd, tFld
  52.         End If
  53.     Next
  54.     If Form_Tools.File1.ListCount > 0 And Form_Tools.Dir1.ListCount > 0 Then AppendMenu mHwnd, MF_SEPARATOR, 0, "-" '分隔线
  55.     ''添加文件
  56.     For vFi = 0 To Form_Tools.File1.ListCount - 1
  57.         tFld = Form_Tools.File1.List(vFi)
  58.         tfldName = Left(tFld, InStrRev(tFld, ".") - 1)
  59.         tFldFull = tfldName
  60.         If Len(tfldName) > 15 Then tfldName = Left(tfldName, 12) & "..."
  61.         If tfldName <> "" Then
  62.             userNum = userNum + 1
  63.             ReDim Preserve urls(userNum)
  64.             Form_INI.pathINI = vName & tFld
  65.             urls(userNum) = Form_INI.classIniFile1.GetIniKey("InternetShortcut""URL")
  66.             'Debug.Print userNum, Form_INI.pathINI, urls(userNum)
  67.             AppendMenu mHwnd, MF_STRING, WM_USER + userNum, tfldName
  68.         End If
  69.     Next
  70.     DrawMenuBar mHwnd
  71.     
  72.     Form_Tools.Dir1.Path = vOldName    '设置文件夹
  73.     Form_Tools.File1.Path = vOldName   '设置文件夹
  74. End Function
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

灵易联盟

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值