在vb中实现鼠标手势

在vb中实现鼠标手势

1.什么是鼠标手势:
我的理解,按着鼠标某键(一般是右键)移动鼠标,然后放开某键,程序会识别你的移动轨迹,做出相应的响应.

2.实现原理:
首先说明一下,我在网上没有找到相关的文档,我的方法未必与其他人是一致的,实际效果感觉还可以.
鼠标移动的轨迹我们可以将其看成是许多小段直线组成的,然后这些直线的方向就是鼠标在这段轨迹中的方向了.
3.实现代码:
还要说明一下,
a)要捕获鼠标的移动事件,可以使用vb中的mousemove事件,但这个会受到一些限制(例如,在webbrowser控件上就没有这个事件).于是这个例子中,我用win api,在程序中安装个鼠标钩子,这样就能够捕获整个程序的鼠标事件了.
b)这个里只是个能捕获鼠标向上,下,左,右的移动的例子.(呵呵,其实这四方向一般也足够了:))

新建Standrad EXE,添加一个Module

form1的代码如下

Option Explicit

Private Sub Form_Load()
Call InstallMouseHook
End Sub

Private Sub Form_QueryUnload(Cancel As Integer, UnloadMode As Integer)
Call UninstallMouseHook
End Sub

Module1的代码如下

Option Explicit

Public Const HTCLIENT As Long = 1

Private hMouseHook As Long
Private Const KF_UP As Long = &H80000000

Public Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (hpvDest As Any, hpvSource As Any, ByVal cbCopy As Long)

Private Type POINTAPI
X As Long
Y As Long

End Type

Public Type MOUSEHOOKSTRUCT
pt As POINTAPI
hwnd As Long
wHitTestCode As Long
dwExtraInfo As Long

End Type

Public Declare Function CallNextHookEx Lib "user32" _
(ByVal hHook As Long, _
ByVal ncode As Long, _
ByVal wParam As Long, _
ByVal lParam As Long) As Long
Public Declare Function SetWindowsHookEx Lib "user32" _
Alias "SetWindowsHookExA" _
(ByVal idHook As Long, _
ByVal lpfn As Long, _
ByVal hmod As Long, _
ByVal dwThreadId As Long) As Long
Public Declare Function UnhookWindowsHookEx Lib "user32" _
(ByVal hHook As Long) As Long

Public Const WH_KEYBOARD As Long = 2
Public Const WH_MOUSE As Long = 7

Public Const HC_SYSMODALOFF = 5
Public Const HC_SYSMODALON = 4
Public Const HC_SKIP = 2
Public Const HC_GETNEXT = 1
Public Const HC_ACTION = 0
Public Const HC_NOREMOVE As Long = 3

Public Const WM_LBUTTONDBLCLK As Long = &H203
Public Const WM_LBUTTONDOWN As Long = &H201
Public Const WM_LBUTTONUP As Long = &H202
Public Const WM_MBUTTONDBLCLK As Long = &H209
Public Const WM_MBUTTONDOWN As Long = &H207
Public Const WM_MBUTTONUP As Long = &H208
Public Const WM_RBUTTONDBLCLK As Long = &H206
Public Const WM_RBUTTONDOWN As Long = &H204
Public Const WM_RBUTTONUP As Long = &H205
Public Const WM_MOUSEMOVE As Long = &H200
Public Const WM_MOUSEWHEEL As Long = &H20A

Public Declare Function PostMessage Lib "user32" Alias "PostMessageA" (ByVal hwnd As Long, ByVal wMsg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
Public Const MK_RBUTTON As Long = &H2
Public Declare Function ScreenToClient Lib "user32" (ByVal hwnd As Long, lpPoint As POINTAPI) As Long

Public Declare Function GetAsyncKeyState Lib "user32" (ByVal vKey As Long) As Integer
Public Const VK_LBUTTON As Long = &H1
Public Const VK_RBUTTON As Long = &H2
Public Const VK_MBUTTON As Long = &H4

Dim mPt As POINTAPI
Const ptGap As Single = 5 * 5
Dim preDir As Long
Dim mouseEventDsp As String
Dim eventLength As Long

'######### mouse hook #############

Public Sub InstallMouseHook()
hMouseHook = SetWindowsHookEx(WH_MOUSE, AddressOf MouseHookProc, _
App.hInstance, App.ThreadID)
End Sub

Public Function MouseHookProc(ByVal iCode As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
Dim Cancel As Boolean
Cancel = False
On Error GoTo due
Dim i&
Dim nMouseInfo As MOUSEHOOKSTRUCT
Dim tHWindowFromPoint As Long
Dim tpt As POINTAPI

If iCode = HC_ACTION Then
CopyMemory nMouseInfo, ByVal lParam, Len(nMouseInfo)
tpt = nMouseInfo.pt
ScreenToClient nMouseInfo.hwnd, tpt
'Debug.Print tpt.X, tpt.Y
If nMouseInfo.wHitTestCode = 1 Then
Select Case wParam
Case WM_RBUTTONDOWN
mPt = nMouseInfo.pt
preDir = -1
mouseEventDsp = ""
Cancel = True
Case WM_RBUTTONUP
Debug.Print mouseEventDsp
Cancel = True
Case WM_MOUSEMOVE
If vkPress(VK_RBUTTON) Then
Call GetMouseEvent(nMouseInfo.pt)
End If
End Select
End If

End If

If Cancel Then
MouseHookProc = 1
Else
MouseHookProc = CallNextHookEx(hMouseHook, iCode, wParam, lParam)
End If

Exit Function

due:

End Function

Public Sub UninstallMouseHook()
If hMouseHook <> 0 Then
Call UnhookWindowsHookEx(hMouseHook)
End If
hMouseHook = 0
End Sub

Public Function vkPress(vkcode As Long) As Boolean
If (GetAsyncKeyState(vkcode) And &H8000) <> 0 Then
vkPress = True
Else
vkPress = False
End If
End Function

Public Function GetMouseEvent(nPt As POINTAPI) As Long
Dim cx&, cy&
Dim rtn&
rtn = -1
cx = nPt.X - mPt.X: cy = -(nPt.Y - mPt.Y)
If cx * cx + cy * cy > ptGap Then
If cx > 0 And Abs(cy) <= cx Then
rtn = 0
ElseIf cy > 0 And Abs(cx) <= cy Then
rtn = 1
ElseIf cx < 0 And Abs(cy) <= Abs(cx) Then
rtn = 2
ElseIf cy < 0 And Abs(cx) <= Abs(cy) Then
rtn = 3
End If
mPt = nPt
If preDir <> rtn Then
mouseEventDsp = mouseEventDsp & DebugDir(rtn)
preDir = rtn
End If
End If
GetMouseEvent = rtn
End Function

Public Function DebugDir(nDir&) As String
Dim tStr$
Select Case nDir
Case 0
tStr = "右"
Case 1
tStr = "上"
Case 2
tStr = "左"
Case 3
tStr = "下"
Case Else
tStr = "无"
End Select
Debug.Print Timer, tStr
DebugDir = tStr
End Function

运行程序后,在程序窗口上,按着右键移动鼠标,Immediate Window就会显示出鼠标移动的轨迹了.

这里面的常数 ptGap 就是"鼠标移动的轨迹我们可以将其看成是许多小段直线组成的"中的小段的长度的平方.里面用到的api函数的用法,可以参考msdn.这里我就懒说了.

lingll (lingll2001@21cn.com)
2004-7-23

没有注释?懒啊,各位就将就着看吧:)

时间: 2024-09-05 17:51:16

在vb中实现鼠标手势的相关文章

vb中,用变量作为数组名可以吗

问题描述 vb中,用变量作为数组名可以吗 vb中,用变量作为数组名可以吗? 例如 arrrrstr()=("as","se") for i=0 to 1 for j=1 to 25 linestr=aeerrstr(i)(j)&"," next j next i 解决方案 将arrstr(i)作为变量名?可以的 解决方案二: 好久不用VB了, 好像是這樣的 dim arrrrstr(2,25) as string 解决方案三: Agoni

ASP进阶:VB中的模块,类,ActiveX与API的使用

active|activex 这几天搞了点c/s结构的程序设计, 由于ASP用得比较熟练,所以VB6.0自然成为我首选的开发工具. 在学习过程中,我结合自己的经验总结下VB中的一些高级应用,并且体会这种应用给我们所带来的好处. 一.模块 (Module) 在VB中,模块会优先执行,其实说白了,模块就象是全局的过程和函数调用.这是初步的提高代码可复用性的途径.我想有经验的ASP(VBSCRIPT,以后都只用VBScript来写Asp程序)程序员都用过<!--#Include file="&q

在VB中动态创建数据库

在VB中动态创建数据库新建工程.添加控件 对应写上代码 以下为引用的内容:Private Sub Command2_Click()    Dim myDB As DAO.Database    'Set myDB = DAO.OpenDatabase("d:\mydb3.mdb")    Set myDB = DAO.OpenDatabase(App.Path + "/mydb.mdb")    Dim d As String    d = "delete

在VB中兼容非ACCESS数据库的技巧

本文从VB数据库体系结构的角度出发,结合一个具体实例,阐述了在VB中兼容非ACCESS格式数据库的具体方法和技巧. 关键词:VB.非ACCESS数据库.数据存取对象 一个完整的数据库管理系统(DBMS)应是能兼容市面上各种较流行数据格式的系统,它充分考虑了不同用户的实际要求.鉴于目前市面上有多种数据库格式(如Foxpro.DBase.Paradox等)流行,因而在VB数据库应用程序中兼容非ACCESS数据库就显得尤为重要了. 作为一种流行的开发平台,VB提供了强大的数据库功能.主要有以下三种:数

浅谈crystal reports在VB中的调用

环境:VB6.0,crystal reports 9.0 在一个项目中用到了crystal reports,总结一些经验和教训. 以做一张单据的套打为例. 单据包括单据头,单据体.单据头和单据体可能是一对多的关系.并且他们分别存在于两张表当中,用字段FID做关联.要求能够动态的传入参数FID,显示不同的结果. 首先,打开crystal reports,做好一张单据的模板rpt.制作报表的方法有很多,比如:用它的图形化工具直接建立几个表之间的连接,然后将想要显示的字段托到报表当中:或是调用一个已经

VB中通过WMI控制DNS服务器,可在ASP中调用

dns服务器|控制 在VB中要使用Scripting API for WMI,必须引用 Microsoft WMI Scripting V1.1 Library 下面介绍Scripting API For WMI的几个对象 SWbemLocator--用于取得SWbemServices对象,他代表了本地或远程计算机上名字空间的一个连接.SWbemService--代表名字空间的一个连接,可用于处理它的部件SWbemObject--代表一个单独的类定义或一个对象实例SWbemOjbectSet--

如何实现给定日期的若干天以后的日期(有点类似VB中的DateAdd)

如何实现给定日期的若干天以后的日期(有点类似VB中的DateAdd)/*  豆腐制作  都是精品  http://www.asp888.net 豆腐技术站  如转载 请保留完整版权信息*/这几天突然有很多的人问这样的问题,就是如何在PHP中实现在VB中的DateAdd的函数,呵呵!这个可是问个正着.本来这个问题是 豆腐 去 华为 应聘的时候的一个考试题,不过当时是用C++实现的.没有想到这样的大公司,竟然用这样的小儿科来考试:),后来我没有去,这两天 应 http://www.chinaspx.

在VB中使用水晶报表的一种简易编程方法

编程|水晶报表       水晶报表(Crystal Report)的业内最专业.功能最强的报表系统,它除了强大的报表功能外,最大的优势是实现了与绝大多数流行开发工具的集成和接口.在VS.Net平台做过报表开发的程序员,一定都对水晶报表强大.高效.集成等特性留下了深刻印象.除了开发新程序外,在工作中我们常需要接触到很多较早的软件系统报表功能升级的需求,如果能结合水晶报表这一强大的工具,往往能事半功倍.       VB是以前流行的数据库开发平台,用其开发的C/S系统在社会上有非常大的保有量,但V

走近VB.Net(一),VB中的族,类,对象(摘录部分MSDN)

对象 走近VB.Net(一),VB中的族,类,对象 VB.Net是面向对象(object-oriented)的,又称为物件(object)导向(oriented).在VB.Net中所有的变量类型都是基于object,而不是VariantDim x As Variant 会被升级为 Dim as object.如果你不理解对象,暂时你可以把他理解为一段数据,他是实际存在于内存的,所以对象以称为实例(instance)而类(class)就是类别,他定义一群对象,是一个对象的群体,并定义方法成员.所以