0

我正在尝试找到一种方法来阻止我的 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
4

0 回答 0