Вызов метода внутри кода ловушки мыши вызывает нарушение прав доступа

У меня низкоуровневый хук мыши, который я пытаюсь использовать для обработки глобальных событий левого клика. Я определил хук в базовом классе основной формы следующим образом:

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 класс, когда на самом деле во время выполнения, форма, которая наследует от TMainForm будет активным. Чтобы сделать это, я написал виртуальный метод под названием GetHandle(),

Эта функция определена в TMainForm заголовок как это:

virtual HWND__ * __fastcall GetHandle();

и в наследующем классе вот так:

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

Тем не менее, когда я звоню GetHandle() в TMainForm Я все еще получаю нарушение прав доступа. Кроме того, попробовав еще несколько вещей, я понял, что вызов любой виртуальной функции вообще изнутри MouseHook вызывает нарушение доступа.

Почему я не могу получить дескриптор формы, используя Platform::Win::WindowHandleToPlatform(this->Handle)->Wnd; Внутри MouseHook? Почему вызов виртуальной функции внутри MouseHook вызвать нарушение прав доступа?

Редактировать:

Чтобы проверить предложенный Реми ответ о недействительности указателя MainForm, я добавил блок кода в TMainForm конструктор для проверки правильности указателя. Кроме того, я добавил блок кода в конструктор класса, который наследуется от TMainForm и загружается при запуске моего приложения, чтобы проверить его глобальный указатель. Глобальный MainForm указатель в моем TMainForm класс был фактически недействительным. Тем не менее, глобальный указатель для наследующего класса был действительным, так как это был фактически созданный экземпляр класса.

0

Решение

То, что вы описываете, предполагает, что ваш глобальный MainForm Указатель не указывает на действительный объект Form при вызове ловушки. Любой вызов метода формы, такой как MouseHook(), таким образом, будет иметь недействительным this указатель. Вы должны убедиться, что вы назначаете этот указатель.

Вы используете SetWindowsHookEx() пример, который я дал вам в ответ на Другой вопрос. В этом же ответе я также дал вам альтернативное решение, которое не SetWindowsHookEx() — обработка WM_INPUT сообщение от RAW Input API. В вашем вопросе не упоминалось, что вы используете FireMonkey вместо VCL. Я привел вам пример для VCL. Теперь я обновил этот ответ, включив в него пример FireMonkey.

1

Другие решения

Других решений пока нет …