我正在尝试找到一种方法来阻止我的 Excel 文件(VBA 7.1)中的 Windows 键和 PrintScreen 键。由于不能使用Application.OnKey方法,所以我网上研究了两种解决方法:1)RegisterHotKeys,2)Keyboard Hook。我已经尝试过 RegisterHotKeys,因为根据我的在线研究,这似乎是首选方法。请让我知道是否还有其他我应该探索的解决方案。我还想在 RegisterHotKeys 上分享我试图阻止的两个键的代码(在本例中,最小化窗口) - 当我运行它时,我的 excel 文件挂起,我不确定错误在哪里.
这是 Windows 键:
Const MOD_WIN = &H8
Const PM_REMOVE = &H1
Const WM_HOTKEY = &H312
Type POINTAPI
x As Long
y As Long
End Type
Type MSG
hwnd As LongPtr
Message As Long
wParam As LongPtr
lParam As LongPtr
time As Long
pt As POINTAPI
End Type
Declare PtrSafe Function RegisterHotKey Lib "user32" (ByVal hwnd As LongPtr, ByVal id As Long, ByVal fsModifiers As Long, ByVal vk As Long) As Long
Declare PtrSafe Function UnregisterHotKey Lib "user32" (ByVal hwnd As LongPtr, ByVal id As Long) As Long
Declare PtrSafe Function PeekMessage Lib "user32" Alias "PeekMessageA" (lpMsg As MSG, ByVal hwnd As LongPtr, ByVal wMsgFilterMin As Long, ByVal wMsgFilterMax As Long, ByVal wRemoveMsg As Long) As Long
Declare PtrSafe Function WaitMessage Lib "user32" () As Long
Public bCancel As Boolean
Sub ProcessMessages()
Dim Message As MSG
Do While Not bCancel
WaitMessage
If PeekMessage(Message, Application.hwnd, WM_HOTKEY, WM_HOTKEY, PM_REMOVE) Then
WindowState = vbMinimized
End If
DoEvents
Loop
End Sub
Sub SetHotKey()
Dim ret As Long
bCancel = False
ret = RegisterHotKey(Application.hwnd, &HBFFF&, MOD_WIN, 0)
ProcessMessages
End Sub
Sub UnsetHotKey()
bCancel = True
Call UnregisterHotKey(Application.hwnd, &HBFFF&)
End Sub
这是 PrintScreen 键:
Const PM_REMOVE = &H1
Const WM_HOTKEY = &H312
Const VK_SNAPSHOT = &H2C
Type POINTAPI
x As Long
y As Long
End Type
Type MSG
hwnd As LongPtr
Message As Long
wParam As LongPtr
lParam As LongPtr
time As Long
pt As POINTAPI
End Type
Declare PtrSafe Function RegisterHotKey Lib "user32" (ByVal hwnd As LongPtr, ByVal id As Long, ByVal fsModifiers As Long, ByVal vk As Long) As Long
Declare PtrSafe Function UnregisterHotKey Lib "user32" (ByVal hwnd As LongPtr, ByVal id As Long) As Long
Declare PtrSafe Function PeekMessage Lib "user32" Alias "PeekMessageA" (lpMsg As MSG, ByVal hwnd As LongPtr, ByVal wMsgFilterMin As Long, ByVal wMsgFilterMax As Long, ByVal wRemoveMsg As Long) As Long
Declare PtrSafe Function WaitMessage Lib "user32" () As Long
Public bCancel As Boolean
Sub ProcessMessages()
Dim Message As MSG
Do While Not bCancel
WaitMessage
If PeekMessage(Message, Application.hwnd, WM_HOTKEY, WM_HOTKEY, PM_REMOVE) Then
WindowState = vbMinimized
End If
DoEvents
Loop
End Sub
Sub SetHotKey()
Dim ret As Long
bCancel = False
ret = RegisterHotKey(Application.hwnd, &HBFFE&, 0, VK_SNAPSHOT)
ProcessMessages
End Sub
Sub UnsetHotKey()
bCancel = True
Call UnregisterHotKey(Application.hwnd, &HBFFE&)
End Sub