3

我在winx86中使用这个程序没有任何错误,但是当我尝试在win x64中使用它时,我的问题开始了。我在我的代码中使用 ptrsafe 让我在 win 7 64bit 中运行,我会补充说这个模块有更多的代码,但是由于这个站点的限制,我已经删除了它。如果现在需要我的代码行告诉我把它们放在这里。请帮助我并告诉我为什么我的代码会产生错误:

'UDT for passing data through the hook
Private Type MSGBOX_HOOK_PARAMS
   hwndOwner   As Long
   hHook       As Long
End Type

Private MSGHOOK As MSGBOX_HOOK_PARAMS
#If VBA7 Then

    Private Declare PtrSafe Function SetWindowsHookEx Lib "user32" _
       Alias "SetWindowsHookExA" _
      (ByVal idHook As Long, _
       ByVal lpfn As Long, _
       ByVal hmod As Long, _
       ByVal dwThreadId As Long) As Long
 #Else

    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
#End If

Public Function MsgBoxHookProc(ByVal uMsg As Long, _
                               ByVal wParam As Long, _
                               ByVal lParam As Long) As Long

   If uMsg = HCBT_ACTIVATE Then

      SetDlgItemText wParam, vbYes, "بلـي"
      SetDlgItemText wParam, vbNo, "خـير"
      SetDlgItemText wParam, vbIgnore, "انصـراف"
      SetDlgItemText wParam, vbOK, "تـــاييد"

      UnhookWindowsHookEx MSGHOOK.hHook

   End If

   MsgBoxHookProc = False

End Function

Public Function MsgBoxFa(Prompt, Optional Buttons As VbMsgBoxStyle = vbOKOnly, Optional Tiltle = "", Optional HelpFile, Optional Context) As Long

  'Wrapper function for the MessageBox API
Dim hwndThreadOwner As Long
Dim frmCurrentForm As Form
Set frmCurrentForm = Screen.ActiveForm

hwndThreadOwner = frmCurrentForm.hwnd

   Dim hInstance As Long

   Dim hThreadId As Long
   Dim hwndOwner As Long
   hwndOwner = GetDesktopWindow()
   hInstance = GetWindowLong(hwndThreadOwner, GWL_HINSTANCE)
   hThreadId = GetCurrentThreadId()

   With MSGHOOK
      .hwndOwner = hwndOwner
'in next line the error produced******************************
      .hHook = SetWindowsHookEx(WH_CBT, _
                                AddressOf MsgBoxHookProc, _
                                hInstance, hThreadId)
   End With


 MsgBoxFa = MessageBox(hwndThreadOwner, Prompt, Tiltle, Buttons)

End Function
4

1 回答 1

-1

一个老问题,但我仍在处理这些东西。这是针对这种情况的具体答案。

SetWindowsHookEx 的 lpfn 参数需要是 LongPtr(它是指针的线索在参数名称中,lp 参数通常是 Windows API 中的指针)。所以:

Private Declare PtrSafe Function SetWindowsHookEx Lib "user32" _
   Alias "SetWindowsHookExA" _
  (ByVal idHook As Long, _
   ByVal lpfn As LongPtr, _
   ByVal hmod As Long, _
   ByVal dwThreadId As Long) As Long

您可以在 32 位和 64 位 office 中进行此更改,因为语法是向后兼容的。

我们还没有完成。在你调用 SetWindowsHookEx 的地方,你传入的AddressOf是 MsgBoxHookProc 的结果 (),因此需要将其更改为返回 LongPtr:

Public Function MsgBoxHookProc(ByVal uMsg As Long, _
                           ByVal wParam As Long, _
                           ByVal lParam As Long) As LongPtr

这些改变就足够了。

于 2021-12-07T18:32:33.427 回答