【VB开源代码栏目提醒】:网学会员,鉴于大家对VB开源代码十分关注,论文会员在此为大家搜集整理了“VB程序中实现鼠标 - 编程语言”一文,供大家参考学习!
在
VB 程序中实现鼠标右键双击 西北工业大学710072 况正谦 在 Microsoft Visual BASICVB 中 窗 体 Form 和 控 件 Control 等 对 象 的 单 击 Click 和 双 击Double-Click事件都是指鼠标左键而言的。
鼠标右键的单击和双击事件在
VB 中没有对应的事件驱动过程去响应和处理。
但是在实际应用中特别是一些可视化的图形软件可能对鼠标键的功能定义比较丰富单靠鼠标左键的单击和双击难以满足复杂的需要。
因此有必要开发和扩充
VB 应用程序对鼠标右键的响应能力。
VB 定义的鼠标事件
VB 定义的鼠标事件有五种:单击Click、双击DblClick、鼠标键按下MouseDown、鼠标键松开MouseUp和鼠标光标移动MouseMove。
其中前两种事件单击和双击是专指鼠标左键而言后三种则适用于所有鼠标键。
后三种鼠标事件的事件驱动过程有如下的形式:Sub 对象名-鼠标事件Button As IntegerShift As Integer X As Single Y As Single 用户插入的事件响应和处理
代码 End Sub 传递给事件过程的参数中整型数 Button 的最低三位从右到左分别对应鼠标左、右、中三个键。
事件发生时哪个或哪些键处于被按下的状态Button 的对应位就为 1否则为 0。
程序中可以用
VB 的位运算 AND 来检测鼠标键的状态。
整数 Shift 的最低三位从右到左分别对应事件发生时键盘的 Shift、 Ctrl、 键。
Alt 事件发生时Shift、 Ctrl、 中的哪个或哪些键处于被按下的状态参数 Shift Alt的对应位就为 1否则为 0。
单精度值 X 和 Y 存放的是事件发生时鼠标光标的 X-Y 坐标值。
该值对于窗体对象而言是鼠标光标在窗体客户区中的坐标对于控件对象则是鼠标光标在窗体客户区中相对于控件左上角的坐标。
鼠标右键事件的检测 实际上鼠标的单击事件可以被分解为 MouseDown 和MouseUp 两个事件所以我们可以用 MouseDown 事件来取代单击事件。
同样鼠标双击事件也可以分解为两个非常紧凑的单击事件。
根据这一思路我们可以在 MouseDown 事件过程中判定鼠标右键的单击和双击事件并作出相应的响应和处理。
1.右键单击的判断和处理 鼠标右键单击事件的判断很简单只需在 MouseDown 事件过程中检测一个 Button 参数。
如下所示: Sub 对象名-MouseDownButton AsIntegerShift As Integer X As Single Y AsSingle If Button 2 Then 鼠标右键按下 鼠标右键单击的响应和处理
代码 End If End Sub 2.右键双击的判断和处理 Windows 对鼠标双击的定义是:同一鼠标键的两次快速按动-放开。
只要两次按键的时间间隔不超过某一阈值Windows 就作为双击对待否则认为是两次单击。
这一阈值称为 DoubleClickSpeed它是在 Widnows 启动时从初始化文件 WIN.INI 中读入的。
这一阈值在 WIN.INI 文件Windows段的 Dou-bleClickSpeed 项中存放以毫秒为单位。
一般情况下DoubleClickSpeed 值为 452 毫秒但是也可以在 WIN.INI 中人为地改变这一设定。
为了判断鼠标右键的双击事件我们需要在程序中读取 WIN.INI 中的 DoubleClick-Speed 值。
以后每次鼠标右键按下时在 Mouse-Down 事 件 过 程 中 都 要 读 当 前 的 系 统 时 间 并 与 上 次 按 键 的 时 间 比 较 看 是 否 超 过Dou-bleClickSpeed 值:如果没超过则转到双击事件的响应呼处理
代码否则作为单击事件处理。
这里涉及读 WIN.INI 的
问题。
虽然 WIN.INI 是格式固定的文本文件但是用读文本文件的方法去查找DoubleClickSpeed 还是很麻烦。
Windows 系统专门提供了一组函数用于访问 Windows 的初始化文件 在这组函数同其它一些函数包含在 Windows 的三个系统动态链接库DDL中。
Windows 的
软件开发环境中一般都提供了访问这些函数的能力这是通过 Windows 的应用程序接口API实现的。
WindowsAPI 函数库中包含了几百个功能强大的系统函数
VB 程序可以通过调用 API 函数完成很多
VB 系统本身不提供的功能。
在
VB 中调用 API 函数之前首先要用 Declare 语句对调用的函数、函数所在的动态链接库、函数的参数和返回类型进行必要的声明。
声明格式为: Declare Function API 函数名 Libquot动态链接库名quot形式参数表 As 返回类型 为了读取 WIN.INI 文件中某一项的值我们需要调用 API 函数GetProfileInt它的声明为 Declare Function GetProfileInt Lib quotKernelquotByVal lpAppName As StringByVallpkeyName As StringByVal nDefault As IntegerAs Integer 其中字符串 lpAppName 为段名lp-KeyName为 项 的 名 字 整 型 量 nDefault 为 该 项 不 存 在 时 返 回 的 缺 省 值 。
因 此 以 下 语 句 可 以 读 出Dou-bleClickSpeed 值: DoubleClickSpeedGetProfileIntquotWindowsquotquotDoubleClickSpeedquot452 此外
VB 程序只能读到以秒为单位的时间精度显然不够。
为了读到较为精确毫秒为单位的
系统时间需要求助于另外一个 API 函数:GetTickCount它返回自 Windows 启动时经过的时间以毫秒为单位。
GetTickCount的声明如下: Declare Function GetTickCount LibquotUserquot As Long 有了以下的技术准备就可以在MouseDown 事件过程中判断和处理鼠标右键的双击事件了。
首先在窗体启动时的加载Load事件过程中读取 Windows 系统的双击时间阈值 DoubleClickSpeed。
然后对 MouseDown 事件过程编程如下:Dim DoubleClickSpeed As Integer Dim FirstClickTick As Long 前一次鼠标右键按下的时刻 Sub 对象名-MouseDownButton As IntegerShift As Integer X As Single Y AsSingle If Button2 Then 鼠标右键按下Dim CurrentTick As Long CurrentTick GetTickCount 读 取 当 前 系 统 时 间 If CurrentTick -FirstClickTick lt DoubleClickSpeed Then 没有超过时限作双击对待 鼠标右键双击的响应和处理
代码Else 超过时限作单击对待 鼠标右键单击的响应和处理
代码 FirstClickTick CurrentTick 记录本次右键按下的时刻 End If End If End Sub
程序的改进 如果在窗体中加入一个命令钮CommandButton或称按钮控件当鼠标光标位于按钮上并按下左键时按钮会自动显示被按下的样子松开左键时按钮又恢复原状。
以上这些都是系统自动完成的不需要用户干预。
按钮对鼠标右键就没有类似的反应。
前面虽然在功能上实现了对右键单击和双击的处理但是从界面上还不尽如人意。
鼠标右键点按钮时只是完成一定的功能按钮本身纹丝不动用户无法得知刚才的按动是否有效。
我们需要再调用一个 API 函数 SendMessage让按钮对鼠标右键作出同对左键一样的反应。
SendMessage 给 Windows 窗口的处理函数WndProc发送一个消息使函数作出相应的处理。
SendMessage 的声明如下: Declare PunctionSendMessage Lib quotUserquot ByVal hwnd As IntegerByVal wMsgAs IntegerByVal wParam As IntegerlParamAs Any As Long 其中的参数 hwnd 是窗口的句柄handlewMsg 是消息的
代码wParam 和 lParam 是与消息有关的两个参数。
VB 中的控件在 Windows 系统中是被作为窗体的子窗口看待的。
窗体和控件都有一个 hWnd 属性该属性即窗体或控件的窗口句柄。
我们用 SendMessage 给按钮的窗口处理函数发送一个 BM.SET-STATE 消息可以让按钮显示出被按下或放开的状态。
BM.SETSTATE 是一个常数其值为十六进制的 403。
如果要显示按钮被按下则调用 tmp SendMessage按钮名.hwnd ampH403 1 0amp如果要显示按钮被松开则调用 tmp SendMessage按钮名.hwnd ampH403 0 0amp SendMessage 返回值无用放在一个临时的变量 tmp 中。
于是我们可以在按钮的鼠标事件过程中进行如下的扩充: ConstBM_SETSTATE ampH403 Sub 按钮名-MouseDownButton As IntegerShift As Integer X As Single YAsSingle If Button 2 Then 鼠标右键按下 …… tmp SendMessage按钮名.hwndBM_SETSTATE 10amp End If End Sub Sub 按钮名-MouseMoveButton As Integer Shift As Integer X As Single Y AsSingleIf Button And 2 Then 鼠标右键按下 If X lt 0 Or Y lt 0 Or X gt按钮名.Width Or Y gt按钮名.Height Then 鼠标光标移到了按钮以外 tmp SendMessage按钮名.hwnd BM_SETSTATE 0 0amp Else tmp SendMessage按钮名.hwnd BM_SETSTATE 1 0amp End If End If End If Sub 按钮名-MouseUpButton AsIntegerShift As Integer X As Single Y As Single If Button And 2 Then tmp Send Message按钮名.hwndBM_SETSTATE 0 0amp End If End Sub 其中 MouseDown 和 MouseUp 事件过程中的处理比较简单。
MouseMove 事件中的处理结果是如果按下鼠标右键按钮显示被按下的状态如果不松开右键而把鼠标光标移到按钮外按钮会弹起如果再移回按钮中按钮再次显示被按下。
这就和用鼠标左键做类似动作时的效果完全一样了。
程序示例 以下是一个完整的
VB 程序例子。
该程序实现了对鼠标右键双击事件的判断和响应处理并从功能和外观上都达到了和左键双击一样的效果。
程序的界面部分非常简单:一个标准的窗体 Forml 和一个位于窗体正中的标准的命令钮 Command1。
运行后每当用户双击按钮时程序都发出quot嘟quot的一声。
该程序在 Microsoft Visual BASIC 4.0 版下调试通过Windows 系统用的是3.2 中文简体版。
FORM1.FRM 源文件: VERSION 4.00 Begin
VB.Form Form1 Caption quotForm1quotClientHeight 4230 ClientLeft 1095 ClientTop 1515 ClientWidth 6720 Height 4635 Left 1035LinkTopic quotForm1quot ScaleHeight 4230 ScaleWidth 6720 Top 1170 Width 6840 BeginVB.CommandButton Command1 Caption quotCommand1quot Height 495 Left 2760 TabIndex 0 Top 1920 Width 1215 End End Attribute
VB_Name quotForm1quot Attribute
VB_Creatable False AttributeVB_Exposed False Private Declare Function GetTickCount Lib quotUserquot As Long Private DeclareFunction GetProfileInt Lib quotKernelquot ByVal lpappName As String ByVal lpKeyName As StringByValnDefault As Integer As Integer Private Declare Function SendMessage LibquotUserquotByVal hwnd As IntegerByVal wMsg As g As IntegerByVal wParam As IntegerlParam As Any As Long Const BM_SETSTATE ampH403 Dim DoubleClickSpeed As Integer Dim FirstClickTick As Long Private SubCommand1_MouseDownButton As IntegerShift As Integer X As Single Y As Singie If Button And 2Then Dim CurrentTick As Long CurrentTick GetTickCount If CurrentTick - FirstClickTickltDoubleClickSpeed Then Beep Else FirstClickTick CurrentTick End If tmp SendMessageCommand1.hwnd BM_SETSTATE 1 0amp End If End Sub Private SubCommand1_MouseMoveButton As IntegerShift As Integer X As SingleY As Single If Button And 2 ThenIf X lt 0 Or Y lt 0 Or X gt Command1.Width Or Y gt Command1.Height Then tmp SendMessageCommand1.hwnd BM_SETSTATE 0 0amp Else tmp SendMessageCommand1.hwndBM_SETSTATE 1 0amp End If End If End Sub Private Sub Command1_MouseUpButton As Integer ShiftAs Integer X As Single Y As Single If Button And 2 Then tmp SendMessageCommand1.hwndBM_SETSTATE 0 0amp End If End Sub Private Sub Form_Load DoubleClickSpeed GetProfileIntquotWindowsquotquotDoubleClickSpeedquot500 End Sub 本版责任编辑 陈春梅
VB 实现窗口的弹出式菜单 在 Windows95、Windows98 或 NT 的风格中,有按动鼠标器右键弹出下拉菜单的操作,在
VB 执行环境下,有一些控件本身具有弹下拉菜单的功能,如 TexTbox 控件等,但大多数编 辑类控件以及窗体本身却没有此功能, ( 要在窗口中任意位置实现 PopUpMenu 弹出式菜单) , 可借助
VB 的菜单工具来实现。
首先,打开
VB 的“工具”菜单条,利用“菜单编辑器”为窗体生成一个菜单: 标题Caption 菜单条名Name 编辑 menuEdit ……复制 mnuCopy ……剪切 munCut 其次,将生成的 menuEdit 菜单设置为不可视。
Private Sub Form_Load Me.menuEdit.VisibeFalse ′menuEdit 菜单设置为不可视End Sub然后,利用 MouseDown 事件实现任意位置弹出 PopUpMenu,如下例:本例中以 RichTexBox 控件为例,在其上面实现复制、剪切功能。
1.复制功能的实现。
Private Sub MnuCopy_ClickClipboar.Clear′将剪贴板清空′将 RichTexBox 控件上选择上的内容复制到剪贴板Clipboard.SetTextRichTexBox1.SelTextEnd Sub2.剪切功能的实现。
Private Sub MnuCut_ClickClipboard.Clear ′将剪贴板清空′将 RichTextBox 控件上选择了的内容复制到剪贴板Clipboard.SetTextRichBox1.SelText′将 RichTexBox 控件上选择了的内容删除SendKeys〃DELETE〃TrueEnd Sub3.在 RichTexBox 控件的 MouseDown 事件中实现任意位置弹出 PopUPMenu。
OPrivate Sub RichTexBox1_MouseDownButton As IntegerShift As Integerx As SingleY AsSingleDim MnuFile AS Menu ′声明一个菜单类型的变量Set munFileMe.MenuEdit ′将 MenuEdit 赋给菜单变量if Button2 Then ′判断是否按动鼠标器右键′判断 RichTexBox 控件上选择了的内容是否存在,决定复制、剪切菜单条是否可操作。
If LenRichTexBox.Text0 Or LenRichTexBox.SelText0 ThenmnuCopy.EnabledFlase ′复制菜单条不可操作。
nmuCut.EnabledFalse ′剪切菜单条不可操作。
nmuCopy.EnabledTrue ′复制菜单条可操作。
nmuCut.EnabledTrue ′剪切菜单条可操作。
End IFPopupMenu mnuFile ′弹出 PopUpMenu。
End IfEnd Sub这样,在
VB 执行环境中,操作窗体上的 RichTexBox 控件,按动鼠标器右键就可弹出下拉菜单,实现复制、剪切功能。
显示弹出式菜单弹出式菜单是独立于菜单栏而显示在窗体上的浮动菜单。
在弹出式菜单上显示的项目取决于按下鼠标右键时指针所处的位置;因而,弹出式菜单也被称为上下文菜单。
在 MicrosoftWindows 95 中,可以通过单击鼠标右键来激活上下文菜单。
在运行时,至少含有一个菜单项的任何菜单都可以作为弹出式菜单被显示。
为了显示弹出式菜单,可使用 PopupMenu 方法。
这个方法使用下列语法:object.PopupMenu menuname flags x y boldcommand 例如:当用户用鼠标右键单击一个窗体时,以下的
代码显示一个名为 mnuFile 的菜单。
可用 MouseUp 或者 MouseDown 事件来检测何时单击了鼠标右键,虽然标准用法是使用MouseUp 事件:Private Sub Form_MouseUp Button As Integer Shift As _Integer X As Single Y As SingleIf Button 2 Then 检查是否单击了鼠标右键。
PopupMenu mnuFile 把文件菜单显示为一个弹出式菜单。
End IfEnd Sub直到菜单中被选取一项或者取消这个菜单时,调用 PopupMenu 方法后面的
代码才会运行。
注意 每次只能显示一个弹出式菜单。
在已显示一个弹出式菜单的情况下,对后面的调用PopupMenu 方法将不予理睬。
在一个菜单控件正活动的任何时刻,调用 PopupMenu 方法均不会被理睬。
常常会想用一个弹出式菜单来访问那些在菜单栏中不
常用的选项。
为创建一个不显示在菜单栏里的菜单,可在设计时使顶级菜单项目为不可见(保证在菜单编辑器里的“Visible”复选框没有被选上)。
当 Visual Basic 显示一个弹出式菜单时,指定的顶级菜单的 Visible 属性会被忽略。
Flags 参数在 PopupMenu 方法中使用 flags 参数可以进一步定义弹出式菜单的位置与性能。
下表列出了可用于描述弹出式菜单位置的标志。
位置常数 描述vbPopupMenuLeftAlign 缺省。
指定的 x 位置定义了该弹出式菜单的左边界。
vbPopupMenuCenterAlign 弹出式菜单以指定的 x 位置为中心。
vbPopupMenuRightAlign 指定的 x 位置定义了该弹出式菜单的右边界。
下表列出了可用于描述弹出式菜单性能的标志。
行为常数 描述vbPopupMenuLeftButton 缺省。
只有当用户用鼠标左键单击菜单项时,才显示弹出式菜单。
vbPopupMenuRightButton 当用户用鼠标右键或者左键单击菜单项时,显示弹出式菜单。
想要指定一个标志,从每组中选取一个常数,再用 Or 操作符将它们连起来。
下面的
代码是,当用户单击一个命令按钮时,显示一个上边框在窗体中心的弹出式菜单。
弹出式菜单触发受到鼠标右键或左键单击的菜单项的 Click 事件。
Private Sub Command1_Click X 变量和 Y 变量的尺寸。
Dim xloc yloc设置 X 变量和 Y 变量到窗体中心。
xloc ScaleWidth / 2yloc ScaleHeight / 2显示弹出式菜单。
PopupMenu mnuEdit vbPopupMenuCenterAlign Or _vbPopupMenuRightButton xloc ylocEnd SubBoldcommand 参数使用 boldcommand 参数来指定在显示的弹出式菜单中想以粗体字体出现的菜单控件的名称。
在弹出式菜单中只能有一个菜单控件被加粗。
-----------------------------------------------------------------了解好弹出式菜单后没,只要在需要显示菜单的控件的 MOUSEDOWN 时间中添加就可以了.Dim flag_button As Boolean Private Sub Form_Load Dim a As Node Set a Me.TreeView1.Nodes.Add quotbquot quotasdfasdfquot Set a Me.TreeView1.Nodes.Addquotbquot 4 quotcquot quotalskdjflquot End Sub Private Sub TreeView1_MouseDownbutton As Integer Shift As Integerx As Single y As Single If button 2 Then flag_button True End If End Sub Private Sub TreeView1_NodeClickByVal Node As MSComctlLib.Node If flag_button True Then PopupMenu a End If End Sub右键菜单能让软件的使用者快捷的完成操作,那么如何把右键菜单用在自己写的程序中呢?在这个小程序中我们能看到编辑并使用右键菜单的方法。
为了
学习方便,提供的源码已经作了详细的中文注释,看看源码框中的
代码:-------------------------------------- 弹出鼠标右键菜单-------------------------------------- 洪恩在线 求知无限--------------------------------------------名称-------------作用------------ CmdCancel 退出按钮 mnublue “兰色”菜单项 mnured “红色”菜单项 RichTextBox1 文本框 PopupFrm 主窗体 mnufile 右键菜单的名字--------------------------------------Private Sub CmdCancel_ClickUnload MeEnd Sub当弹出式菜单的“红色”项被点击时Private Sub mnured_Click把 RichTextBox 框中的背景色设置为红色RichTextBox1.BackColor vbRedEnd Sub当弹出式菜单的“兰色”项被点击时Private Sub mnublue_Click把 RichTextBox 框中的背景色设置为兰色RichTextBox1.BackColor vbBlueEnd Sub当文本框上出现鼠标按下的事件时Private Sub RichTextBox1_MouseDownButton As Integer Shift As Integer X As Single Y AsSingleMouseDown 事件各种语法包含下列部分:button 返回一个整数,用来标识该事件的产生是按下哪个按钮其中 左按钮(位 0) ,右按钮(位 2),以及中间按钮(位 4)shift 返回一个整数,标示是否同时有 ShiftCtrlAlt 键按下x y 返回一个指定鼠标指针当前位置的数Button 2 表示右键按下If Button 2 ThenPopupMenu 方法用来弹出一个菜单语法是 object.PopupMenu menuname flags X Ymnufile 是我们在菜单编辑器中
设计好的菜单XY 是弹出菜单的位置,可以为数字,如果直接写为 XY 则是在当前鼠标位置弹出.