PopMenu.cls
上传用户:davilee3
上传日期:2015-04-22
资源大小:986k
文件大小:11k
源码类别:

浏览器

开发平台:

Visual Basic

  1. VERSION 1.0 CLASS
  2. BEGIN
  3.   MultiUse = -1  'True
  4.   Persistable = 0  'NotPersistable
  5.   DataBindingBehavior = 0  'vbNone
  6.   DataSourceBehavior  = 0  'vbNone
  7.   MTSTransactionMode  = 0  'NotAnMTSObject
  8. END
  9. Attribute VB_Name = "cPopMenu"
  10. Attribute VB_GlobalNameSpace = False
  11. Attribute VB_Creatable = True
  12. Attribute VB_PredeclaredId = False
  13. Attribute VB_Exposed = False
  14. 'cPopMenu,用api生成的 popup menu
  15. '2004-12-18 修正了UnCheckAll的一个错误
  16. '2004-12-17 修改了popup,popup2函数,增加了enum pmnTPM
  17. '2004-11-29 增加函数GetItemCount
  18. '2004-11-28 补充了两种状态 pmsUnChecked pmsPopup,修正了pmsDisabled
  19. '           增加了函数:RemoveItems
  20. '           增加一参数:NODestroy,可以设置退出时是否destroy menu
  21. '2004-9-13  发现当使用CheckRadioItem后,UnCheckAll无效,已修正
  22. '2004-8-11  添加一个函数 Add2,可以指定添加的菜单项的位置
  23. '2004-6-26  添加了几个函数DeleteItem,ClearItems,CheckItem,
  24. '    CheckRadioItem,UnCheckAll
  25. '1:14 2004-3-5
  26. Option Explicit
  27. Private Declare Function GetCursorPos Lib "user32" (lpPoint As POINTAPI) As Long
  28. Private Declare Function SetMenuDefaultItem Lib "user32" (ByVal hMenu As Long, ByVal uItem As Long, ByVal fByPos As Long) As Long
  29. Private Declare Function EnableMenuItem Lib "user32" (ByVal hMenu As Long, ByVal wIDEnableItem As Long, ByVal wEnable As Long) As Long
  30. Private Declare Function TrackPopupMenu Lib "user32" (ByVal hMenu As Long, ByVal wFlags As Long, ByVal x As Long, ByVal y As Long, ByVal nReserved As Long, ByVal hwnd As Long, lprc As Any) As Long
  31. Private Declare Function AppendMenu Lib "user32" Alias "AppendMenuA" (ByVal hMenu As Long, ByVal wFlags As Long, ByVal wIDNewItem As Long, ByVal lpNewItem As Any) As Long
  32. Private Declare Function InsertMenu Lib "user32" Alias "InsertMenuA" (ByVal hMenu As Long, ByVal nPosition As Long, ByVal wFlags As Long, ByVal wIDNewItem As Long, ByVal lpNewItem As Any) As Long
  33. Private Declare Function CreatePopupMenu Lib "user32" () As Long
  34. Private Declare Function DestroyMenu Lib "user32" (ByVal hMenu As Long) As Long
  35. Private Declare Function DeleteMenu Lib "user32" (ByVal hMenu As Long, ByVal nPosition As Long, ByVal wFlags As Long) As Long
  36. Private Declare Function GetMenuItemCount Lib "user32" (ByVal hMenu As Long) As Long
  37. Private Declare Function CheckMenuItem Lib "user32" (ByVal hMenu As Long, ByVal wIDCheckItem As Long, ByVal wCheck As Long) As Long
  38. Private Declare Function CheckMenuRadioItem Lib "user32" (ByVal hMenu As Long, ByVal un1 As Long, ByVal un2 As Long, ByVal un3 As Long, ByVal un4 As Long) As Long
  39. Private Declare Function RemoveMenu Lib "user32" (ByVal hMenu As Long, ByVal nPosition As Long, ByVal wFlags As Long) As Long
  40. Public Enum pmnTPM
  41.     TPM_BOTTOMALIGN = &H20&
  42.     TPM_CENTERALIGN = &H4&
  43.     TPM_HORIZONTAL = &H0&
  44.     TPM_HORNEGANIMATION = &H800&
  45.     TPM_HORPOSANIMATION = &H400&
  46.     TPM_LEFTALIGN = &H0&
  47.     TPM_LEFTBUTTON = &H0&
  48.     TPM_NOANIMATION = &H4000&
  49.     TPM_NONOTIFY = &H80&
  50.     TPM_RECURSE = &H1&
  51.     TPM_RETURNCMD = &H100&
  52.     TPM_RIGHTALIGN = &H8&
  53.     TPM_RIGHTBUTTON = &H2&
  54.     TPM_TOPALIGN = &H0&
  55.     TPM_VCENTERALIGN = &H10&
  56.     TPM_VERNEGANIMATION = &H2000&
  57.     TPM_VERPOSANIMATION = &H1000&
  58.     TPM_VERTICAL = &H40&
  59.     
  60.     TPM_Default = TPM_LEFTALIGN Or TPM_RETURNCMD
  61. End Enum
  62. Private Const MF_BYCOMMAND = &H0&         '菜单条目由菜单的命令ID指定
  63. Private Const MF_BYPOSITION = &H400&      '菜单条目由条目在菜单中的位置决定。零代表菜单中的第一个条目
  64. Private Const MF_CHECKED = &H8&           '检查指定的菜单条目。不能与VB的Checked属性兼容
  65. Private Const MF_DISABLED = &H2&          '禁止指定的菜单条目。不与VB的Enabled属性兼容
  66. Private Const MF_ENABLED = &H0&           '允许指定的菜单条目。不与VB的Enabled属性兼容
  67. Private Const MF_GRAYED = &H1&            '禁止指定的菜单条目,并用浅灰色描述它。不与VB的Enabled属性兼容
  68. Private Const MF_HILITE = &H80&
  69. Private Const MF_SEPARATOR = &H800&       '在指定的条目处显示一条分隔线
  70. Private Const MF_STRING = &H0&            '在指定的条目处放置一个字串。不与VB的Caption属性兼容
  71. Private Const MF_UNCHECKED = &H0&         '检查指定的条目。不能与VB的Checked属性兼容
  72. Private Const MF_UNHILITE = &H0&
  73. Private Const MF_POPUP = &H10&            '将一个弹出式菜单置于指定的条目。可用于创建子菜单及弹出式菜单
  74. Private Type MENUITEMINFO
  75.     cbSize As Long
  76.     fMask As Long
  77.     fType As Long
  78.     fState As Long
  79.     wID As Long
  80.     hSubMenu As Long
  81.     hbmpChecked As Long
  82.     hbmpUnchecked As Long
  83.     dwItemData As Long
  84.     dwTypeData As String
  85.     cch As Long
  86. End Type
  87. Private Declare Function GetMenuItemInfo Lib "user32" Alias "GetMenuItemInfoA" (ByVal hMenu As Long, ByVal un As Long, ByVal b As Boolean, lpMenuItemInfo As MENUITEMINFO) As Long
  88. Private Declare Function SetMenuItemInfo Lib "user32" Alias "SetMenuItemInfoA" (ByVal hMenu As Long, ByVal un As Long, ByVal bool As Boolean, lpcMenuItemInfo As MENUITEMINFO) As Long
  89. Private Const MIIM_FTYPE As Long = &H100
  90. Private Const MIIM_STATE As Long = &H1
  91. Private Const MFT_RADIOCHECK As Long = &H200&
  92. Private Const MFS_CHECKED As Long = MF_CHECKED
  93. Private Const MFS_UNCHECKED = MF_UNCHECKED
  94. Private Type POINTAPI
  95.     x As Long
  96.     y As Long
  97. End Type
  98. Public Enum enumPopMenuMenuStyle
  99.     pmsString = MF_STRING
  100.     pmsSeparator = MF_SEPARATOR
  101.     pmsChecked = MF_CHECKED
  102.     pmsUnChecked = MF_UNCHECKED
  103.     pmsDisabled = MF_DISABLED Or MF_GRAYED
  104.     pmsHilite = MF_HILITE
  105.     pmsPopup = MF_POPUP
  106. End Enum
  107. 'local variable(s) to hold property value(s)
  108. Private mvarhwnd As Long 'local copy
  109. Private mvarParent As Long
  110. '退出时不毁灭 menu
  111. Public NODestroy As Boolean
  112. Public Function Popup(Optional AutoPos As Boolean = True, _
  113.         Optional x As Long, Optional y As Long, _
  114.         Optional ByVal nFlag As pmnTPM = TPM_Default) As Long
  115. Dim rtn As Long
  116. rtn = Popup2(mvarParent, AutoPos, x, y, nFlag)
  117. Popup = rtn
  118. End Function
  119. Public Function Popup2(nParent As Long, Optional AutoPos As Boolean = True, _
  120.         Optional x As Long, Optional y As Long, _
  121.         Optional ByVal nFlag As pmnTPM = TPM_Default) As Long
  122. Dim tpt As POINTAPI
  123. Dim rtn As Long
  124. If AutoPos Then
  125.     Call GetCursorPos(tpt)
  126. Else
  127.     tpt.x = x
  128.     tpt.y = y
  129. End If
  130. 'nFlag = TPM_LEFTALIGN Or TPM_RECURSE Or TPM_RETURNCMD
  131. rtn = TrackPopupMenu(hwnd, nFlag, tpt.x, tpt.y, 0&, nParent, 0&)
  132. Debug.Print rtn
  133. Popup2 = rtn
  134. End Function
  135. '在菜单末尾添加
  136. Public Sub Add(nCaption As String, _
  137.     Optional nFlag As enumPopMenuMenuStyle = pmsString, _
  138.     Optional id As Long, Optional DefaultItem As Boolean = False)
  139. If mvarhwnd <> 0 Then
  140.     Call AppendMenu(mvarhwnd, nFlag, id, nCaption)
  141.     If DefaultItem Then
  142.         Call SetMenuDefaultItem(mvarhwnd, id, 0)
  143.     End If
  144. End If
  145. End Sub
  146. '可以添加在任何位置
  147. Public Sub Add2(nCaption As String, _
  148.     uItem As Long, Optional fByPosition As Boolean = True, _
  149.     Optional nFlag As enumPopMenuMenuStyle = pmsString, _
  150.     Optional id As Long)
  151. If mvarhwnd <> 0 Then
  152.     If fByPosition Then
  153.         nFlag = nFlag Or MF_BYPOSITION
  154.     Else
  155.         nFlag = nFlag Or MF_BYCOMMAND
  156.     End If
  157.     
  158.     Call InsertMenu(mvarhwnd, uItem, nFlag, id, nCaption)
  159. End If
  160. End Sub
  161. Public Property Get hwnd() As Long
  162. 'used when retrieving value of a property, on the right side of an assignment.
  163. 'Syntax: Debug.Print X.hwnd
  164.     hwnd = mvarhwnd
  165. End Property
  166. '获得菜单项的数量
  167. Public Function GetItemCount() As Long
  168. If mvarhwnd <> 0 Then
  169.     GetItemCount = GetMenuItemCount(mvarhwnd)
  170. End If
  171. End Function
  172. Public Function SetDefault(nID As Long, Optional ByCommand As Boolean = True) As Boolean
  173. Dim rtn As Boolean
  174. rtn = False
  175. If mvarhwnd <> 0 Then
  176.     If SetMenuDefaultItem(mvarhwnd, nID, Not ByCommand) <> 0 Then rtn = True
  177. End If
  178. SetDefault = rtn
  179. End Function
  180. Public Function EnableItem(uID As Long, nEnable As Boolean, Optional ByCommand As Boolean = True)
  181. Dim nFlag As Long
  182. If nEnable Then
  183.     nFlag = MF_ENABLED
  184. Else
  185.     nFlag = MF_DISABLED Or MF_GRAYED
  186. End If
  187. If ByCommand Then
  188.     nFlag = nFlag Or MF_BYCOMMAND
  189. Else
  190.     nFlag = nFlag Or MF_BYPOSITION
  191. End If
  192. Call EnableMenuItem(mvarhwnd, uID, nFlag)
  193. End Function
  194. 'check某item(勾)
  195. Public Function CheckItem(uID As Long, nChecked As Boolean, Optional ByCommand As Boolean = True)
  196. Dim nFlag As Long
  197. If mvarhwnd <> 0 Then
  198.     If nChecked Then
  199.         nFlag = MF_CHECKED
  200.     Else
  201.         nFlag = MF_UNCHECKED
  202.     End If
  203.     
  204.     If ByCommand Then
  205.         nFlag = nFlag Or MF_BYCOMMAND
  206.     Else
  207.         nFlag = nFlag Or MF_BYPOSITION
  208.     End If
  209.     
  210.     Call CheckMenuItem(mvarhwnd, uID, nFlag)
  211. End If
  212. End Function
  213. Public Function UnCheckAll()
  214. Dim i&
  215. Dim tcnt&
  216. Dim tIIf As MENUITEMINFO
  217. If mvarhwnd <> 0 Then
  218.     tcnt = GetMenuItemCount(mvarhwnd)
  219.     With tIIf
  220.         .cbSize = Len(tIIf)
  221.         .fMask = MIIM_FTYPE Or MIIM_STATE
  222.     End With
  223.     
  224.     For i = 0 To tcnt - 1
  225.         GetMenuItemInfo mvarhwnd, i, True, tIIf
  226.         tIIf.fState = tIIf.fState Or MFS_CHECKED Xor MFS_CHECKED
  227.         tIIf.fType = tIIf.fType Or MFT_RADIOCHECK Xor MFT_RADIOCHECK
  228.         Call SetMenuItemInfo(mvarhwnd, i, True, tIIf)
  229.     Next i
  230. End If
  231. 'Dim i&
  232. 'Dim tFlag&, tCnt&
  233. 'If mvarhwnd <> 0 Then
  234. '    tCnt = GetMenuItemCount(mvarhwnd)
  235. '    tFlag = MF_UNCHECKED Or MF_BYPOSITION
  236. '    For i = 0 To tCnt - 1
  237. '        Call CheckMenuItem(mvarhwnd, i, tFlag)
  238. '    Next i
  239. 'End If
  240. End Function
  241. 'check某item,其他un check(圆)
  242. Public Function CheckRadioItem(uID As Long, Optional ByCommand As Boolean = True)
  243. Dim tcnt&
  244. Dim tFlag&
  245. If mvarhwnd <> 0 Then
  246.     If ByCommand Then
  247.         tFlag = MF_BYCOMMAND
  248.     Else
  249.         tFlag = MF_BYPOSITION
  250.     End If
  251.     
  252.     tcnt = GetMenuItemCount(mvarhwnd)
  253.     Call CheckMenuRadioItem(mvarhwnd, 0, tcnt - 1, uID, tFlag)
  254. End If
  255. End Function
  256. '删除某项, 会 destroy sub menu
  257. Public Function DeleteItem(uID As Long, Optional ByCommand As Boolean = True)
  258. Dim tFlag As Long
  259. If mvarhwnd <> 0 Then
  260.     If ByCommand Then
  261.         tFlag = MF_BYCOMMAND
  262.     Else
  263.         tFlag = MF_BYPOSITION
  264.     End If
  265.     
  266.     Call DeleteMenu(mvarhwnd, uID, tFlag)
  267. End If
  268. End Function
  269. '删除多项,index from uPos1 to uPos2,不会 destroy sub menu
  270. Public Function RemoveItems(uPos1&, uPos2&)
  271. Dim i&
  272. If mvarhwnd <> 0 Then
  273.     If uPos1 <= uPos2 Then
  274.         For i = uPos2 To uPos1 Step -1
  275.             Call RemoveMenu(mvarhwnd, i, MF_BYPOSITION)
  276.         Next i
  277.     End If
  278. End If
  279. End Function
  280. '删除全部项
  281. Public Function ClearItems()
  282. Dim i&, tcnt&
  283. If mvarhwnd <> 0 Then
  284.     tcnt = GetMenuItemCount(mvarhwnd)
  285.     For i = tcnt - 1 To 0 Step -1
  286.         Call DeleteMenu(mvarhwnd, i, MF_BYPOSITION)
  287.     Next i
  288. End If
  289. End Function
  290. Public Function Create(Optional nHwdPopMenu As Long = 0) As Boolean
  291. If mvarhwnd <> 0 Then Call Destroy
  292. If nHwdPopMenu = 0 Then
  293.     mvarhwnd = CreatePopupMenu
  294.     If mvarhwnd <> 0 Then
  295.         Create = True
  296.     Else
  297.         Create = False
  298.     End If
  299. Else
  300.     mvarhwnd = nHwdPopMenu
  301.     Create = True
  302. End If
  303. End Function
  304. Public Function Destroy() As Boolean
  305. If mvarhwnd <> 0 Then
  306.     Call DestroyMenu(mvarhwnd)
  307.     mvarhwnd = 0
  308. End If
  309. End Function
  310. Private Sub Class_Initialize()
  311. mvarhwnd = 0
  312. NODestroy = False
  313. End Sub
  314. Private Sub Class_Terminate()
  315. If NODestroy Then
  316. Else
  317.     Call Destroy
  318. End If
  319. End Sub
  320. Public Property Get Parent() As Long
  321.     Parent = mvarParent
  322. End Property
  323. Public Property Let Parent(ByVal vNewValue As Long)
  324.     mvarParent = vNewValue
  325. End Property