Reputation: 1
I'm trying to find a way to block Windows key and PrintScreen key in my Excel file (VBA 7.1). Since Application.OnKey method can't be used, my online research points to two solutions: 1) RegisterHotKeys, 2) Keyboard Hook. I've tried RegisterHotKeys since this seems to be the preferred method based on my online research. Pls let me know if there are any other solutions I should explore. I'd also like to share my code below on RegisterHotKeys for both keys that I'm trying to block (in this example, minimizing the window) - when I run it, my excel file hangs and I'm unsure where the error lies.
This is for the Windows key:
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
This is for the PrintScreen key:
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
Upvotes: 0
Views: 309