在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在菜单上增加图标

※vb在 ListBox 之中点击右键弹出菜单

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

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

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


VB部分相关文章推荐:

※vb中line的用法[转]

※画图工具的VB实现

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

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

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

※[转] Vb中FSO 对象的介绍

※VB 画坐标轴

※VB 二进制文件的操作

※[VB]BMP转JPGVB中KeyCode常数用法

※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中如何在任务管理器里面隐藏应用程序进程

※如何实现VB与EXCEL的无缝连接

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

※VB用记录集填充表格函数

※VB打开文本文件各种方法

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

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

※【转】 Md rd命令之VB

※vb:读写文本文件

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

※【引用】使用CommonDialog的ShowSave后如何判断是保存还是※取消?

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

※vb UTF文本文件访问

※VB编程中的Unicode vs Ansi

※VB编PiView4注册机

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

※比CopyMemory还要快的函数SuperCopyMemory

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

※VB画出来的五星红旗

※Qt第一印象——Qte与Qt


更多精彩>>>

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

  1. Altium Designer16.0中查找元器件的三种方法

    Altium Designer16.0中查找元器件的三种方法 方法一:在已知库中查找 1 这个方法仅适用于已知元器件所在的库的情况.如果已知某个元器件在某个库中,那么只需在那个库中进行查找即可.下面以 ...

  2. 【转】VB6.0中用户类和数据源类的设计和使用技术

    本文转自: http://www.pcworld.com.cn/99/script/9907/072601b.asp 摘要:用户自定义类(Class)是Visual Basic 6.0中实现软件重用的 ...

  3. VB6.0中,DTPicker日期、时间控件不允许为空时,采用文本框与日期、时间控件相互替换赋值(解决方案)...

    VB6.0中,日期.时间控件不允许为空时,采用文本框与日期.时间控件相互替换赋值,或许是一个不错的选择. 实现效果如下图: 文本框txtStopTime1 时间框DTStopTime1(DTPicke ...

  4. VB6.0中,DTPicker日期、时间控件不允许为空时,采用文本框与日期、时间控件相互替换赋值(解决方案)

    VB6.0中,DTPicker日期.时间控件不允许为空时,采用文本框与日期.时间控件相互替换赋值(解决方案) 参考文章: (1)VB6.0中,DTPicker日期.时间控件不允许为空时,采用文本框与日 ...

  5. VB6.0中创建和使用文本资源文件

    不少网友问及如何在VB中建立和使用文本资源文件.我想这也是很多VB初学者迫切想掌握的技巧.为此,将回答网友的信件整理了一下,形成此文,希望对大家有些帮助. 一.文本资源文件的建立 第一步:启动资源编辑 ...

  6. 在VB6.0中怎么实现escape和unescape

    两套方案,一是调用JAVAscript对象,二是自己写代码编码与解码,代码在CSDN中的以下帖子里贴出: 方案一代码: 复制内容到剪贴板 程序代码 Function Escape(ByVal pstr ...

  7. VB6.0中的窗口控制技巧(1)

    移动没有标题栏的窗口 我们一般是用鼠标按住窗口的标题栏,然后移动窗口,当窗口没有标题栏时,我们可以用下面的方法来移动窗口: 在 BAS 文件中声明: Declare Function ReleaseC ...

  8. 浅谈VB6.0中的实用技巧

    浅谈VB6.0中的实用技巧 (一) VB6.0中文本框处理技巧 在Visual Basic中,文本框(TextBox)是最常用的控件,熟练运用文本框 是开发出高质量的应用程序的基础.笔者在从事应用程序 ...

  9. VB6.0中快速实现大面积不规则区域的填充

    VB6.0中快速实现大面积不规则区域的填充 ------------------------------------------------------------------------------ ...

最新文章

  1. [Cocos2d-x For WP8]矩形碰撞检测
  2. javascript this详解
  3. 简化Redis数据访问代码RedisTemplate
  4. arpanet(阿帕网)
  5. nyoj239 月老的难题 二分图 匈牙利算法
  6. Linux启动SAP服务,sap启动相关
  7. USACO-Section2.2 Preface Numbering
  8. python 测试用例 自动生成目录_如何在python中自动将测试用例添加到测试套件中...
  9. Mr.J---重拾Ajax(三)-- jsonjQuery实现Ajax
  10. 【源码阅读】看Spring Boot如何自动装配ActiveMQ收发组件
  11. 使用Opencv分离图像通道/合并图像通道
  12. SDN/NFV在演进中探寻路径
  13. 华为NP课程笔记26-VXLAN概述
  14. dwf怎么合成一个_cad多张图纸拆分(如何将一个有多个图的CAD文件,按图分成几个文件)...
  15. 华为novia3i鸿蒙,华为nova3i一马当先:值得年轻人购买的智能手机推荐
  16. cdLinux显示“没有发现无限网卡!”
  17. python爬取新浪微博大V的所有微博内容
  18. python数列求和_python练习--数列求和
  19. DataSource接口,一个被大多数程序员忽略的接口
  20. QLU—新生训练赛002补题

热门文章

  1. 如何搞定知乎模拟登陆的加密难题?
  2. iPhone 大降价;谷歌再爆丑闻;京东云金山云回应合并传闻 | 极客头条
  3. 仅一年,近半加密货币的“ICO”项目已死
  4. sqlserver text最大长度_1156. 单字符重复子串的最大长度
  5. linux 安腾,时代谢幕:英特尔安腾IA-64的Linux内核支持已成孤儿
  6. java break与continue_java中的break与continue
  7. mysql文件扩展名查询_如何通过MySQL查询获取文件的文件扩展名?
  8. 全局loading如何控制
  9. 理解vue中$watch使用
  10. java在文本域内添加按钮_JAVA中在窗体中添加了一个文本框,然后再文本框中输入字符,如何...