vb:如何禁止鼠标指针进入某个区域
2006-01-18 22:54
323 查看
我们知道ClipCursor可以将指针限制到指定区域,那么如何反其道而为之,禁止鼠标进入某个区域呢,答案是用鼠标钩子,在WIN NT 4.0 SP3以上系统可以用WH_MOUSE_LL这个钩子实现,这个钩子的特殊之处是不需要用dll,另外,这个钩子用到了一个结构体,简单说明一下:
typedef struct {
POINT pt;
DWORD mouseData;
DWORD flags;
DWORD time;
ULONG_PTR dwExtraInfo;
} MSLLHOOKSTRUCT, *PMSLLHOOKSTRUCT;
Members
pt
Specifies a POINT structure that contains the x- and y-coordinates of the cursor, in screen coordinates.
mouseData
If the message is WM_MOUSEWHEEL, the high-order word of this member is the wheel delta. The low-order word is reserved. A positive value indicates that the wheel was rotated forward, away from the user; a negative value indicates that the wheel was rotated backward, toward the user. One wheel click is defined as WHEEL_DELTA, which is 120.
If the message is WM_XBUTTONDOWN, WM_XBUTTONUP, WM_XBUTTONDBLCLK, WM_NCXBUTTONDOWN, WM_NCXBUTTONUP, or WM_NCXBUTTONDBLCLK, the high-order word specifies which X button was pressed or released, and the low-order word is reserved. This value can be one or more of the following values. Otherwise, mouseData is not used.
XBUTTON1
The first X button was pressed or released.
XBUTTON2
The second X button was pressed or released.
flags
Specifies the event-injected flag. An application can use the following value to test the mouse flags.
0
Specifies whether the event was injected. The value is 1 if the event was injected; otherwise, it is 0.
1-15
Reserved.
time
Specifies the time stamp for this message.
dwExtraInfo
Specifies extra information associated with the message.
好了废话少说,看代码:
一个模块,一个窗体(名为Form1)
模块代码:
Option Explicit
Private Declare Sub CopyMemory Lib "kernel32.dll" Alias "RtlMoveMemory" (ByRef Destination As Any, ByRef Source As Any, ByVal Length As Long)
Private Declare Function PtInRect Lib "user32" (lpRect As RECT, ByVal x As Long, ByVal y As Long) As Long
Private 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
Private Declare Function UnhookWindowsHookEx Lib "user32" (ByVal hHook As Long) As Long
Private Declare Function CallNextHookEx Lib "user32" (ByVal hHook As Long, ByVal nCode As Long, ByVal wParam As Long, lparam As Any) As Long
Private Const HC_ACTION = 0
Private Const WH_MOUSE_LL As Long = 14
Private Const WM_MOUSEMOVE = &H200
Public Type RECT
Left As Long
Top As Long
Right As Long
Bottom As Long
End Type
Private Type POINTAPI
x As Long
y As Long
End Type
Private Type MSLLHOOKSTRUCT
pt As POINTAPI
mouseData As Long
Flags As Long
time As Long
dwExtraInfo As Long
End Type
Public hHook As Long
Public hRT As RECT
Public Sub EnableHook(hRect As RECT)
hRT = hRect
If hHook = 0 Then
hHook = SetWindowsHookEx(WH_MOUSE_LL, AddressOf HookProc, App.hInstance, 0)
End If
End Sub
Public Sub FreeHook()
If hHook <> 0 Then
Call UnhookWindowsHookEx(hHook)
hHook = 0
End If
End Sub
Public Function HookProc(ByVal nCode As Long, ByVal wParam As Long, ByVal lparam As Long) As Long
Dim typMHS As MSLLHOOKSTRUCT, pt As POINTAPI
If nCode < 0 Then
HookProc = CallNextHookEx(hHook, nCode, wParam, lparam)
Exit Function
End If
If wParam = WM_MOUSEMOVE Then
Call CopyMemory(typMHS, ByVal lparam, LenB(typMHS))
pt = typMHS.pt
If PtInRect(hRT, pt.x, pt.y) <> 0 Then
HookProc = 1 '取消原本要完成的動作
Else
Form1.Caption = "mouse Cursor at " + CStr(pt.x) + "," + CStr(pt.y)
HookProc = 0 '令待完成的動作繼續完成
End If
End If
End Function
窗体代码:
Option Explicit
Const HWND_TOPMOST = -1
Const HWND_NOTOPMOST = -2
Const SWP_NOSIZE = &H1
Const SWP_NOMOVE = &H2
Const SWP_NOACTIVATE = &H10
Const SWP_SHOWWINDOW = &H40
Private Declare Sub SetWindowPos Lib "user32" (ByVal hWnd As Long, ByVal hWndInsertAfter As Long, ByVal x As Long, ByVal y As Long, ByVal cx As Long, ByVal cy As Long, ByVal wFlags As Long)
Private Sub Form_Activate()
'设置窗口为TOPMOST窗口,目的是便于观察
SetWindowPos Me.hWnd, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOACTIVATE Or SWP_SHOWWINDOW Or SWP_NOMOVE Or SWP_NOSIZE
End Sub
Private Sub Form_Load()
Dim RT As RECT
With RT
.Left = 0
.Right = 400
.Top = 0
.Bottom = 300
End With
EnableHook RT
End Sub
Private Sub Form_Unload(Cancel As Integer)
FreeHook
End Sub
需要指出的是VB自带的api浏览器中的PtInRect声明有问题,调用它的时候尽管不报错,但不能判断指定点是否位于RECT内,为此修改了它的声明
另外,我这段程序是禁止鼠标指针进入(0,0)-(400,300)这个区域,在调试的时候可能窗体的关闭按钮正好位于这一区域,这时候,记得按下 alt+F4关闭窗口
typedef struct {
POINT pt;
DWORD mouseData;
DWORD flags;
DWORD time;
ULONG_PTR dwExtraInfo;
} MSLLHOOKSTRUCT, *PMSLLHOOKSTRUCT;
Members
pt
Specifies a POINT structure that contains the x- and y-coordinates of the cursor, in screen coordinates.
mouseData
If the message is WM_MOUSEWHEEL, the high-order word of this member is the wheel delta. The low-order word is reserved. A positive value indicates that the wheel was rotated forward, away from the user; a negative value indicates that the wheel was rotated backward, toward the user. One wheel click is defined as WHEEL_DELTA, which is 120.
If the message is WM_XBUTTONDOWN, WM_XBUTTONUP, WM_XBUTTONDBLCLK, WM_NCXBUTTONDOWN, WM_NCXBUTTONUP, or WM_NCXBUTTONDBLCLK, the high-order word specifies which X button was pressed or released, and the low-order word is reserved. This value can be one or more of the following values. Otherwise, mouseData is not used.
XBUTTON1
The first X button was pressed or released.
XBUTTON2
The second X button was pressed or released.
flags
Specifies the event-injected flag. An application can use the following value to test the mouse flags.
Value | Purpose |
---|---|
LLMHF_INJECTED | Test the event-injected flag. |
Specifies whether the event was injected. The value is 1 if the event was injected; otherwise, it is 0.
1-15
Reserved.
time
Specifies the time stamp for this message.
dwExtraInfo
Specifies extra information associated with the message.
好了废话少说,看代码:
一个模块,一个窗体(名为Form1)
模块代码:
Option Explicit
Private Declare Sub CopyMemory Lib "kernel32.dll" Alias "RtlMoveMemory" (ByRef Destination As Any, ByRef Source As Any, ByVal Length As Long)
Private Declare Function PtInRect Lib "user32" (lpRect As RECT, ByVal x As Long, ByVal y As Long) As Long
Private 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
Private Declare Function UnhookWindowsHookEx Lib "user32" (ByVal hHook As Long) As Long
Private Declare Function CallNextHookEx Lib "user32" (ByVal hHook As Long, ByVal nCode As Long, ByVal wParam As Long, lparam As Any) As Long
Private Const HC_ACTION = 0
Private Const WH_MOUSE_LL As Long = 14
Private Const WM_MOUSEMOVE = &H200
Public Type RECT
Left As Long
Top As Long
Right As Long
Bottom As Long
End Type
Private Type POINTAPI
x As Long
y As Long
End Type
Private Type MSLLHOOKSTRUCT
pt As POINTAPI
mouseData As Long
Flags As Long
time As Long
dwExtraInfo As Long
End Type
Public hHook As Long
Public hRT As RECT
Public Sub EnableHook(hRect As RECT)
hRT = hRect
If hHook = 0 Then
hHook = SetWindowsHookEx(WH_MOUSE_LL, AddressOf HookProc, App.hInstance, 0)
End If
End Sub
Public Sub FreeHook()
If hHook <> 0 Then
Call UnhookWindowsHookEx(hHook)
hHook = 0
End If
End Sub
Public Function HookProc(ByVal nCode As Long, ByVal wParam As Long, ByVal lparam As Long) As Long
Dim typMHS As MSLLHOOKSTRUCT, pt As POINTAPI
If nCode < 0 Then
HookProc = CallNextHookEx(hHook, nCode, wParam, lparam)
Exit Function
End If
If wParam = WM_MOUSEMOVE Then
Call CopyMemory(typMHS, ByVal lparam, LenB(typMHS))
pt = typMHS.pt
If PtInRect(hRT, pt.x, pt.y) <> 0 Then
HookProc = 1 '取消原本要完成的動作
Else
Form1.Caption = "mouse Cursor at " + CStr(pt.x) + "," + CStr(pt.y)
HookProc = 0 '令待完成的動作繼續完成
End If
End If
End Function
窗体代码:
Option Explicit
Const HWND_TOPMOST = -1
Const HWND_NOTOPMOST = -2
Const SWP_NOSIZE = &H1
Const SWP_NOMOVE = &H2
Const SWP_NOACTIVATE = &H10
Const SWP_SHOWWINDOW = &H40
Private Declare Sub SetWindowPos Lib "user32" (ByVal hWnd As Long, ByVal hWndInsertAfter As Long, ByVal x As Long, ByVal y As Long, ByVal cx As Long, ByVal cy As Long, ByVal wFlags As Long)
Private Sub Form_Activate()
'设置窗口为TOPMOST窗口,目的是便于观察
SetWindowPos Me.hWnd, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOACTIVATE Or SWP_SHOWWINDOW Or SWP_NOMOVE Or SWP_NOSIZE
End Sub
Private Sub Form_Load()
Dim RT As RECT
With RT
.Left = 0
.Right = 400
.Top = 0
.Bottom = 300
End With
EnableHook RT
End Sub
Private Sub Form_Unload(Cancel As Integer)
FreeHook
End Sub
需要指出的是VB自带的api浏览器中的PtInRect声明有问题,调用它的时候尽管不报错,但不能判断指定点是否位于RECT内,为此修改了它的声明
另外,我这段程序是禁止鼠标指针进入(0,0)-(400,300)这个区域,在调试的时候可能窗体的关闭按钮正好位于这一区域,这时候,记得按下 alt+F4关闭窗口
相关文章推荐
- 在一个CButton派生类CArrowButton内部,如何判断鼠标进入Button区域
- MFC中如何使鼠标移到某个区域后变形?
- 如何改变MFC程序中的窗体的鼠标指针
- 请问vb.NET中如何打印一个某一固定区域的内容?
- 如何取消Qt中的鼠标指针?
- 如何解决Ubuntu系统鼠标指针跳动的问题
- c++ builder\delphi中如何改变操作数据库时的鼠标指针形状
- [转]当鼠标点击ListView下面的空白区域时,如何使ListView的原item选项仍然为选中状态
- 如何判断鼠标是否在DIV的区域内
- 如何限制鼠标区域(c++builder)
- 如何禁止开机时进入安全模式
- 如何知道鼠标进入及离开CHtmlView(或它的子类)?
- win7下进入系统弹出Adobe Flash Player自动更新如何禁止
- VB之如何禁止x按钮
- 如何在Windows 2000开机时按下F8无效(禁止进入安全模式)
- VB关于精确限制鼠标活动区域
- win7系统长时间无操作进入睡眠模式后禁止鼠标和键盘唤醒
- MFC中如何在指定的区域响应鼠标单击事件?
- [转]当鼠标点击ListView下面的空白区域时,如何使ListView的原item选项仍然为选中状态
- VB中如何传递指针给DLL