2017-07-26 142 views
0

这个功能让我疯狂!我正在尝试使用SetWindwosHookEx来避免用户的一些击键,但我无法使其正常工作。使用SetWindowsHookEx。在Excel 2010中

我一直在网上浏览很多代码,但我不明白为什么它不适合我。首先,这是因为我使用Excel 2010(64位),我的代码不适合它,但现在我不知道。

基本上,我创建了一个简单的代码,当我拉“g”时显示一条消息,但是它发生的事情是当拉任何键时Excel崩溃。当我一步一步地运行代码时它不会崩溃,但如果我拉动“g”,则消息会出现三次!

这是我的代码:

#If Win64 Then 

Public Declare PtrSafe Function UnhookWindowsHookEx Lib "user32" (ByVal hHook As LongPtr) As LongPtr 
Public Declare PtrSafe Function SetWindowsHookEx Lib "user32" Alias "SetWindowsHookExA" (ByVal idHook As LongPtr, ByVal lpFn As LongPtr, ByVal hmod As LongPtr, ByVal dwThreadId As LongPtr) As LongPrt 
Public Declare PtrSafe Function CallNextHookEx Lib "user32" (ByVal hHook As LongPtr, ByVal nCode As LongPtr, ByVal wParam As LongPtr, lParam As Any) As LongPtr 
Public Declare PtrSafe Function GetModuleHandle Lib "kernel32" Alias "GetModuleHandleA" (ByVal lpModuleName As String) As LongPtr 
Public Declare PtrSafe Function GetCurrentThreadId Lib "kernel32"() As LongPtr 
Public Declare PtrSafe Function GetKeyState Lib "user32" (ByVal nVirtKey As LongPtr) As Integer 
Private hWndPPT As LongPtr 
Private HookHandle As LongPtr 

'ADICIONAL 
Private Declare Function SendDlgItemMessage Lib "user32" Alias "SendDlgItemMessageA" (ByVal hDlg As LongPrt, ByVal nIDDlgItem As LongPtr, ByVal wMsg As LongPtr, ByVal wParam As LongPtr, ByVal lParam As LongPtr) As LongPtr 
Private Declare Function GetClassName Lib "user32" Alias "GetClassNameA" (ByVal hwnd As LongPtr, ByVal lpClassName As String, ByVal nMaxCount As LongPtr) As LongPtr 



#Else 
Public Declare Function UnhookWindowsHookEx Lib "user32" (ByVal hHook 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 CallNextHookEx Lib "user32" (ByVal hHook As Long, ByVal nCode As Long, ByVal wParam As Long, lParam As Any) As Long 
Public Declare Function GetModuleHandle Lib "kernel32" Alias "GetModuleHandleA" (ByVal lpModuleName As String) As Long 
Public Declare Function GetCurrentThreadId Lib "kernel32"() As Long 
Public Declare Function GetKeyState Lib "user32" (ByVal nVirtKey As Long) As Integer 
Private hWndPPT As Long 
Private HookHandle As Long 

'ADICIONAL 
Private Declare Function SendDlgItemMessage Lib "user32" Alias "SendDlgItemMessageA" (ByVal hDlg As Long, ByVal nIDDlgItem As Long, ByVal wMsg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long 
Private Declare Function GetClassName Lib "user32" Alias "GetClassNameA" (ByVal hwnd As Long, ByVal lpClassName As String, ByVal nMaxCount As Long) As Long 

#End If 



'Constants to be used in our API functions 
'Private Const EM_SETPASSWORDCHAR = &HCC 
'Private Const WH_CBT = 5 
Private Const WH_KEYBOARD = 2 
'Private Const HCBT_ACTIVATE = 5 
Private Const HC_ACTION = 0 

'Private hHook As Long 


Public Sub RemoveHook() 
    UnhookWindowsHookEx (HookHandle) 
End Sub 

Sub SetHook() 
#If Win64 Then 
Dim lThreadID As LongPtr 
Dim lngModHwnd As LongPtr 
#Else 
Dim lThreadID As Long 
Dim lngModHwnd As Long 
#End If 

lThreadID = GetCurrentThreadId 
lngModHwnd = GetModuleHandle(vbNullString) 

'Set a local hook 
HookHandle = SetWindowsHookEx(WH_KEYBOARD, AddressOf NewProc, 0, lThreadID) 
End Sub 

Public Function NewProc(ByVal lngCode As LongPtr, ByVal wParam As LongPtr, ByVal lParam As LongPtr) As LongPtr 

    If lngCode < HC_ACTION Then 
     NewProc = CallNextHookEx(HookHandle, lngCode, wParam, lParam) 
     Exit Function 
    End If 

    If wParam = 71 Then 
     'MsgBox "g" 
     'NewProc = 1 
     wParam = 70 
     'Exit Function 
    End If 

    'This line will ensure that any other hooks that may be in place are 
    'called correctly. 
    CallNextHookEx HookHandle, lngCode, wParam, lParam 

End Function 
+0

你需要检查你的声明 - 不是所有的东西都应该是'LongPtr'。那些应该是“LongPtr”而不是“LongPrt”。 – Rory

+0

对不起我的无知,但哪些不会是LongPtr?这是我第一次为64位编码。谢谢。 – Rafavb

回答

0

64位正确的声明将是:

Public Declare PtrSafe Function UnhookWindowsHookEx Lib "user32" (ByVal hHook As LongPtr) As Long 
Public Declare PtrSafe Function SetWindowsHookEx Lib "user32" Alias "SetWindowsHookExA" (ByVal idHook As Long, ByVal lpFn As LongPtr, ByVal hmod As LongPtr, ByVal dwThreadId As Long) As LongPtr 
Public Declare PtrSafe Function CallNextHookEx Lib "user32" (ByVal hHook As LongPtr, ByVal nCode As Long, ByVal wParam As LongPtr, lParam As Any) As LongPtr 
Public Declare PtrSafe Function GetModuleHandle Lib "kernel32" Alias "GetModuleHandleA" (ByVal lpModuleName As String) As LongPtr 
Public Declare PtrSafe Function GetCurrentThreadId Lib "kernel32"() As Long 
Public Declare PtrSafe Function GetKeyState Lib "user32" (ByVal nVirtKey As Long) As Integer 
Private Declare Function SendDlgItemMessage Lib "user32" Alias "SendDlgItemMessageA" (ByVal hDlg As LongPtr, ByVal nIDDlgItem As Long, ByVal wMsg As Long, ByVal wParam As LongPtr, ByVal lParam As LongPtr) As LongPtr 
Private Declare Function GetClassName Lib "user32" Alias "GetClassNameA" (ByVal hwnd As LongPtr, ByVal lpClassName As String, ByVal nMaxCount As Long) As Long 

我不能真正看到你是如何发布的代码将在64位上运行的。

+0

谢谢!其实,它并不真正起作用。一旦我拉了一把钥匙,代码就进入了一个不可阻挡的循环。在准备好了关于钩子,setwindowsex,callnexthookex等的信息和许多代码后,我无法看到错误。所有示例代码看起来非常简单,但我无法使其工作 – Rafavb

+0

嗨,我已经做了一些改进和这个代码工作几乎没有问题... – Rafavb

+0

嗨,再次,我做了一些改进,这段代码工作得很好,但有几个问题:当我运行代码时,函数不会返回键我在拉,所以没有任何东西被写入,并且“NewProc_64”函数运行两次: – Rafavb