登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

miaozk2006

点滴积累与收藏:关于技术,关于生活

 
 
 

日志

 
 

【引用】在VB6.0中实现弹出式菜单的几种方法  

2012-05-11 08:58:13|  分类: 编程-VB |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |

在Windows应用程序中,利用弹出式菜单(Pop-up Menu)是增加软件易用性的一个重要方式。本文将向大家介绍在VB6.0中实现弹出式菜单的几种方法。

利用VB6.0内置的PopupMenu方法

PopupMenu方法(Method)是VB6.0内置的实现弹出式菜单的方法,用于在MDIForm或Form等对象中的鼠标点位置或指定位置显示弹出式菜单。其语法为:
Object.PopupMenu menuname, flags, x, y, boldcommand
说明如下:


Object

可选项,可以是PropertyPage, Usercontrol, UserDocument, Form, MDIForm等对象之一,如果该部分省略,则具有焦点(Focus)的Form对象将作为此Object。

Menuname

必须,将被显示的弹出式菜单的名称,此菜单必须至少包含一个子菜单

Flags

可选项,一个值或常数,设置弹出式菜单显示的位置及行为方式,定义如下:

常数(位置)

说明

VbPopupMenuLeftAlign

0

(缺省值)弹出式菜单左对齐于X

VbPopupMenuCenterAlign

4

菜单居中于X

VbPopupMenuRightAlign

8

弹出式菜单右对齐于X

常数(行为)

说明

VbPopupMenuLeftButton

0

(缺省值)只能通过点击鼠标左键来选择弹出式菜单的菜单项

VbPopupMenuRightButton

2

可以通过点击鼠标的左键或右键来选择弹出式菜单的菜单项

X

可选项,设定显示弹出式菜单的X坐标,如省略,鼠标点坐标将被作为X使用

Y

可选项,设定显示弹出式菜单的Y坐标,如省略,鼠标点坐标将被作为Y使用

Boldcommand

可选项,定义弹出式菜单中某一个菜单项的名称,该菜单项文字将被加粗显示,如省略该项,则无菜单项文字被加粗。

通过设置对象(Object)的Scalemode属性来规定X,Y坐标的度量单位,X,Y坐标设定弹出式菜单在对象(Object)中显示的相对位置,如果省略X,Y,则弹出式菜单将显示在当前鼠标点位置。
当用PopupMenu方法激活弹出菜单后,要等到用户选择了弹出菜单中的某个菜单项之后(这种情况下,还要先运行被选择菜单项的相应代码)或在表单其它位置单击鼠标左键消除弹出菜单后,后面的代码才能继续执行。并且,一次只能激活一个弹出式菜单,当已经有一个弹处菜单被激活或已经有一个下拉菜单被打开时,对PopupMenu方法的调用将被忽略。
下面的例子演示当用户在表单上点击鼠标右键时,在鼠标点处显示弹出式菜单。欲试验此例子,建立一个表单,在表单中建立一个菜单控件,将其命名为mnuFile(mnuFile菜单至少包含一个子菜单)。在表单的声明(Declaration)区域加入如下代码:
Private Sub Form_MouseDown (Button As Integer, Shift As Integer, X As Single, Y As Single)
If Button = vbRightButton Then
PopupMenu mnuFile
End If
End Sub
PopupMenu方法是VB6.0内置的方法,使用起来方便简单,但该方法有一个不足,即当点击鼠标弹出菜单后,如果不选择菜单项而在其他位置点击鼠标,则菜单并不会在新的鼠标点处显示。这虽然不至于影响应用程序的功能,但却降低了易用性。

利用Windows API函数

除了利用VB6.0内置的PopupMenu方法来实现弹出式菜单外,还可以利用Windows 的应用程序接口(API)函数中的菜单函数来实现弹出式菜单。
利用API的菜单函数实现弹出式菜单与VB6.0内置的PopupMenu方法相比,要复杂一些,但却弥补了PopupMenu方法的不足点,即当弹出菜单后不选择菜单项而在其它位置点击鼠标时,弹出式菜单会立即出现在那个位置。并且利用API函数,编程者可以更加灵活、自由度更大地实现弹出式菜单。
本文用到的API函数为:GetMenu, GetSubMenu, GetMenuItemInfo, InsertMenuItem, CreatePopupMenu, DestroyMenu, TrackPopupMenu。下面先简单介绍一下这几个函数。


GetMenu

GetMenu函数返回指定窗口的菜单的句柄

语法:GetMenu ( HWnd )

参数的意义

HWnd

窗口句柄,该窗口所包含的菜单的句柄将被函数返回

GetSubMenu

GetSubMenu函数返回下拉菜单或被指定菜单项激活的子菜单的句柄

语法:GetSubMenu ( hMenu, nPos )

参数的意义

Hmenu

菜单句柄

NPos

定义激活下拉菜单或子菜单的菜单项在所给菜单中的相对位置(起始为0)

GetMenuItemInfo

GetMenuItemInfo函数返回菜单项的信息

语法:GetMenuItemInfo ( hMenu, uItem, fByPosition, lpmii )

参数的意义

Hmenu

包含相应菜单项的菜单的句柄

Uitem

欲获得其信息的菜单项的标识号或位置,该参数的具体意义由fByPositon参数的值来决定

FbyPosition

用来定义uItem参数的意义,如果此参数的值为False,则uItem参数为菜单项的标识号,否则,为菜单项的位置

Lpmii

指向MENUITEMINFO结构变量的指针,该变量指定了需要返回菜单项的哪些信息,并接收这些信息。MENUITEMINFO结构各元素说明如下:

CbSize

结构占用的字节数

Fmask

设置欲获得结构中哪些元素的值

Ftype

菜单项类型

Fstate

菜单项状态

WID

标识菜单项的16位值

HsubMenu

与菜单项关联的下拉菜单或子菜单的句柄

HbmpChecked

菜单项被选中时,显示在菜单项旁边的位图的句柄,该值为Null时使用缺省位图

HbmpUnchecked

菜单项未被选中时,显示在菜单项旁边的位图的句柄,该值为Null则不使用位图

DwTypeData

菜单项文字,长度在元素cch中给出

Cch

菜单项文字长度

InsertMenuItem

InsertMenuItem函数在一菜单的指定位置插入一个新菜单项

语法:InsertMenuItem ( hMenu, uItem, fByPosition, lpmii )

参数的意义

Hmenu

新菜单项将被插入的菜单的句柄

Uitem

新菜单项将被插入在其之前的菜单项的标识号或位置,该参数的具体意义由fByPositon参数的值来决定

FbyPosition

用来定义uItem参数的意义,如果此参数的值为False,则uItem参数为菜单项的标识号,否则,为菜单项的位置

Lpmii

指向MENUITEMINFO结构变量的指针,该变量包含了新菜单项的信息

CreatePopupMenu

CreatePopupMenu函数生成一个下拉菜单、子菜单或弹出式操单,菜单在初始时是空的,可以使用InsertMenuItem函数来插入菜单项

语法:CreatePopupMenu ( )

DestroyMenu

DestroyMenu函数清除指定的菜单并释放该菜单所占用的内存空间

语法:DestroyMenu ( hMenu )

参数的意义

HMenu

将被清除的菜单的句秉

TrackPopupMenu

TrackPopupMenu函数在指定位置显示一个弹出式菜单,并跟踪菜单中菜单项的选择,弹出菜单可以出现在屏幕的任何位置

语法:TrackPopupMenu (hMenu, uFlags, x, y, nReserved, hWnd, *PrcRect)

参数的意义

HMenu

被显示的弹出式菜单的句柄,此句柄可通过调用CreatePopupMenu函数生成一个新弹出式菜单获得,或调用GetSubMenu函数获得一个现有某子菜单的句柄

UFlags

一组标识符来指定函数的选项,意义如下

常数

说明

TPM_CENTERALIGN

4

设置该值,弹出式菜单水平居中于X

TPM_LEFTALIGN

0

设置该值,弹出式菜单左对齐于X

TPM_RIGHTALIGN

8

设置该值,弹出式菜单右对齐于X

TPM_LEFTBUTTON

0

设置该值,用户只能通过鼠标左键选择菜单项

TPM_RIGHTBUTTON

2

设置该值,用户既可以通过鼠标左键也可以通过鼠标右键选择菜单项

X

定义弹出菜单的水平位置(屏幕坐标系)

Y

定义弹出菜单的垂直位置(屏幕坐标系)

Nreserved

保留,必须为0

HWnd

拥有弹出式菜单的窗口的句柄,该窗口接收所有从该菜单传来的消息,该窗口在函数返回之前不从菜单接收WM_COMMAND消息
如在uflags参数中定义了TPM_NONOTIFY,函数不向HWnd定义的窗口发送消息,但仍需向HWnd传递一个窗口句柄,它可以是所在应用程序中的任何窗口句柄

PrcRect

忽略

三.利用工程(Project)中其他表单的菜单作为当前表单的弹出菜单

如果表单(Form)的菜单中不包含弹出菜单需要的菜单项,那么可以新建一个表单,在新表单中建立一个与所需弹出菜单完全一样的菜单及相应代码。然后在MouseDown事件中利用GetMenu和GetSubMenu函数来获得新表单中的菜单句柄,再利用TrackPopupMenu函数激活弹出式菜单。
下面的例子演示当在表单中单击鼠标右键时,在鼠标点位置显示弹出式菜单,此弹出式菜单是通过调用另外一个表单中的菜单得到的。要试验这个例子,需要创建两个表单,一个命名为Form1,另一个命名为MnuForm。在MnuForm中加入一个菜单控件,将其命名为MnuFile(MnuFile中至少要包含一个子菜单)。添加一个模块(Module),在模块的声明(Declaration)区域添加如下代码:

Public Type RECT
    Left As Long
    Top As Long
    Right As Long
    Bottom As Long
End Type
Public Declare Function GetMenu Lib "user32" (ByVal hwnd As Long) As Long
Public Declare Function GetSubMenu Lib "user32" (ByVal hMenu As Long, ByVal nPos As Long) As Long
Public 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 RECT) As Long

在Form1的声明(Declaration)区域添加如下代码:


Private Sub Form_MouseDown(Button As Integer, Shift As Integer, X As Single, Y As Single)
    Dim IX As Integer, IY As Integer
    Dim hMenu As Long, hSubMenu As Long, R As Integer
    Dim menRect As RECT
    If Button = vbRightButton Then
        ScaleMode = TWIPS
        IX = (X + Left) \ Screen.TwipsPerPixelX
        IY = (Y + Top) \ Screen.TwipsPerPixelY
        hMenu = GetMenu(MnuForm.hwnd)     '获得MnuForm中的菜单句柄保存于hMenu
        hSubMenu = GetSubMenu(hMenu, 0)   '获得hMenu中的第一个子菜单的句柄保存于hSubMenu
        R = TrackPopupMenu(hSubMenu, 2, IX, IY, 0, MnuForm.hwnd, menRect) '激活弹出菜单
    End If
End Sub

利用表单中的菜单项实现弹出式菜单

如果表单的菜单中包含了弹出菜单所需的菜单项,那么可以通过CreatePopupMenu函数生成一个空的pop-up menu,然后利用GetMenuItemInfo函数从表单的菜单中获得相应菜单项的内容,再用InsertMenuItem函数将菜单项加入到pop-up menu中,最后使用TrackPopupMenu函数激活弹出式菜单。
下面的例子演示当在表单中单击鼠标右键时,在鼠标点位置显示弹出式菜单,此弹出式菜单是通过调用表单中的若干菜单项得到的。要试验这个例子,需要创建一个表单。在表单中加入一个菜单控件,将其命名为MnuFile,在MnuFile中至少要包含一个子菜单,将其命名为MnuOpen,MnuOpen的Caption值为“&Open”。添加一个模块(Module),在模块的Declaration区域添加如下代码:

Public Type RECT
    Left As Long
    Top As Long
    Right As Long
    Bottom As Long
End Type
Public 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
Public Declare Function GetMenu Lib "user32" (ByVal hwnd As Long) As Long
Public Declare Function GetSubMenu Lib "user32" (ByVal hMenu As Long, ByVal nPos As Long) As Long
Public 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 RECT) As Long
Public Declare Function CreatePopupMenu Lib "user32" () As Long
Public Declare Function DestroyMenu Lib "user32" (ByVal hMenu As Long) As Long
Public Declare Function GetMenuItemInfo Lib "user32" Alias "GetMenuItemInfoA" (ByVal hMenu As Long, ByVal un As Long, ByVal b As Long, lpMenuItemInfo As MENUITEMINFO) As Long
Public Declare Function InsertMenuItem Lib "user32" Alias "InsertMenuItemA" (ByVal hMenu As Long, ByVal un As Long, ByVal bool As Boolean, ByRef lpcMenuItemInfo As MENUITEMINFO) As Long

在表单的声明(Declaration)区域添加如下代码:


Private Sub Form_MouseDown(Button As Integer, Shift As Integer, X As Single, Y As Single)
    Dim IX As Integer, IY As Integer
    Dim hMenu As Long, hSubMenu As Long, PMenu As Long
    Dim theR As Long
    Dim menRect As RECT
    Dim MnuItmInfo As MENUITEMINFO, TempMnuItmInfo As MENUITEMINFO
    Dim Dummy As Variant
    If Button And vbRightButton Then
        ScaleMode = vbTwips
        IX = (X + Left) \ Screen.TwipsPerPixelX
        IY = (Y + Top) \ Screen.TwipsPerPixelY
        PMenu = CreatePopupMenu()    '生成一个空弹出菜单
        hMenu = GetMenu(Form1.hwnd) '获得Form1的菜单句柄保存于hMenu
        hSubMenu = GetSubMenu(hMenu, 0) '获得hMenu的第一个子菜单的句柄保存于hSubMenu
        With TempMnuItmInfo
            .cbSize = Len(TempMnuItmInfo)
            .dwTypeData = Space$(10)
            .fMask = 126 '获得所有元素的值
            .cch = 10
        End With
        MnuItmInfo = TempMnuItmInfo
        Dummy = GetMenuItemInfo(hSubMenu, 0, True, MnuItmInfo) '获得hSubMenu第一个菜单
        Dummy = InsertMenuItem(PMenu, 0, True, MnuItmInfo) '项的信息,将其插入到PMenu
        .
        .
        .
        MnuItmInfo = TempMnuItmInfo
        Dummy = GetMenuItemInfo(hSubMenu, n, True, MnuItmInfo) '获得hSubMenu第n-1个菜
        Dummy = InsertMenuItem(PMenu, n, True, MnuItmInfo) '单项的信息,将其插入到PMenu
        theR = TrackPopupMenu(PMenu, 2, IX, IY, 0, Form1.hwnd, menRect) '激活弹出菜单
        Dummy = DestroyMenu(PMenu)
    End If
End Sub


相关参考


vb屏蔽文本框点右键时的弹出菜单

VB 小技巧自定义TextBox文本框右键菜单

VB 自启动建立右键菜单

VB在菜单上增加图标

vbListBox 之中点击右键弹出菜单

【引用】在VB6.0中实现弹出式菜单的几种方法

vb中实现真正锁定的带自定义菜单的文本控件

记录一下:在菜单上添加自绘图形的例子(VB6代码)


VB相关


vbline的用法[]

画图工具的VB实现

VB 一个获得自己外网 IP 地址的程序代码

VB程序中实现IP地址子网掩码网关DNS的更改  []

VB 中应用 FSO 对象模型介绍(摘自网络)

[] VbFSO 对象的介绍

VB 画坐标轴

VB 二进制文件的操作

[VB]BMPJPGVBKeyCode常数用法

vb实时曲线的绘制和保存

VB操作EXCEL

vb初学回顾:最大公约数 最小公倍数 素数求取

vb 关于窗口样式的API以及处理文本的API参考

【引用】在VB6.0中实现弹出式菜单的几种方法

【引用】URLDownloadToFile_VB下载文件!

利用WinRar压缩和解压缩文件

VB 剪切板

VB实现指示窗口中拖动方框的程序

VB绘制走动的表针

如何用VB制作DLL文件

【引用】VB修改IP地址

VB多窗体退出代码

[]VB:如何检测到U盘的插拔(源代码)

巧用SendMessage函数扩展Treeview功能

vb中如何在任务管理器里面隐藏应用程序进程

如何实现VBEXCEL的无缝连接

一个API方式存取日志文件的模块[VB]

VB用记录集填充表格函数

VB打开文本文件各种方法

vb ClipBoard 剪切板应用(复制剪切粘贴)

【引用】窗口处理技巧大全 vb(窗体控件)

【转】 Md rd命令之VB

vb:读写文本文件

vb中实现真正锁定的带自定义菜单的文本控件

【引用】使用CommonDialogShowSave后如何判断是保存还是取消?

vb 关于commondialog的多选VB获取Windows操作系统所有版本

vb UTF文本文件访问

VB编程中的Unicode vs Ansi

VBPiView4注册机

VB获取超过2G文件的大小

CopyMemory还要快的函数SuperCopyMemory

VB:编程效率快步提高之:十七种可用一行代码完成的技巧

VB画出来的五星红旗

Qt第一印象——QteQt  


更多精彩>>>
  评论这张
 
阅读(797)| 评论(0)

历史上的今天

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2018