鼠标钩子代码内部的调用方法导致访问冲突

Calling method inside of mouse hook code causes access violation

我有一个低级鼠标钩子,我正试图用它来处理全局左键单击事件。我已经在基本主窗体 class 中定义了钩子,如下所示:

class TMainForm : public TForm
{
private:
    HHOOK hMouseHook;
    static LRESULT CALLBACK MouseHookProc(int nCode, WPARAM wParam, LPARAM lParam);
    void __fastcall MouseHook(int nCode, WPARAM wParam, LPARAM lParam);
};
extern PACKAGE TMainForm *MainForm;


LRESULT CALLBACK TMainForm::MouseHookProc(int nCode, WPARAM wParam, LPARAM lParam)
{
    MainForm->MouseHook(nCode, wParam, lParam);
    return CallNextHookEx(0, nCode, wParam, lParam);
}

void TMainForm::MouseHook(int nCode, WPARAM wParam, LPARAM lParam)
{
    if (nCode >= 0 && wParam == WM_LBUTTONDOWN)
    {

        HWND__ * handle = Platform::Win::WindowHandleToPlatform(this->Handle)->Wnd;

        RECT Rect;
        GetWindowRect(handle, &Rect);
    }
}

我的鼠标钩子可以很好地检测到左键单击,但是当我尝试获取 MainForm 的句柄时,我遇到了访问冲突。

我原本认为这可能是因为我试图在 TMainForm class 中检索句柄,而实际上在 运行 期间,继承自 TMainForm 将处于活动状态。为此,我编写了一个名为 GetHandle().

的虚拟方法

这个函数在TMainFormheader中是这样定义的:

virtual HWND__ * __fastcall GetHandle();

并在继承 class 中像这样:

HWND__ * __fastcall TMainFormPass::GetHandle()
{
   return Platform::Win::WindowHandleToPlatform(this->Handle)->Wnd;
}

但是,当我在 TMainForm 中调用 GetHandle() 时,我仍然遇到访问冲突。此外,在尝试了更多东西之后,我意识到从 MouseHook 内部调用任何虚函数都会导致访问冲突。

为什么我无法使用 MouseHook 中的 Platform::Win::WindowHandleToPlatform(this->Handle)->Wnd; 检索我的表单句柄?为什么在 MouseHook 中调用虚函数会导致访问冲突?

编辑:

为了测试 Remy 提出的 MainForm 指针无效的答案,我在 TMainForm 构造函数中添加了一段代码来测试指针是否有效。此外,我在 class 的构造函数中添加了一段代码,它继承自 TMainForm 并在启动我的应用程序时加载,以测试其全局指针。我的 TMainForm class 中的全局 MainForm 指针实际上是无效的。但是,继承 class 的全局指针是有效的,因为它实际上是 class 被实例化。

根据您的描述,您的全局 MainForm 指针在调用挂钩时未指向有效的 Form 对象。因此,对 MouseHook() 等形式的方法的任何调用都将具有无效的 this 指针。您必须确保正在分配该指针。

您正在使用我在回答 . In that same answer, I had also given you an alternative solution that did not involve SetWindowsHookEx() - handling the WM_INPUT message from the RAW Input API 时给您的 SetWindowsHookEx() 示例。您的问题没有提到您使用的是 FireMonkey 而不是 VCL。我给你的例子是针对 VCL 的。我现在已经更新了该答案以包括一个 FireMonkey 示例。