Вызов метода внутри кода ловушки мыши вызывает нарушение прав доступа
У меня есть низкоуровневый хук мыши, который я пытаюсь использовать для обработки глобальных событий левого клика. Я определил хук в базовом классе основной формы следующим образом:
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
класс был фактически недействительным. Тем не менее, глобальный указатель для наследующего класса был действительным, так как это был фактически созданный экземпляр класса.
1 ответ
То, что вы описываете, предполагает, что ваш глобальный MainForm
Указатель не указывает на действительный объект Form при вызове ловушки. Любой вызов метода формы, такой как MouseHook()
, таким образом, будет иметь недействительным this
указатель. Вы должны убедиться, что вы назначаете этот указатель.
Вы используете SetWindowsHookEx()
Пример, который я дал вам в ответ на другой вопрос. В этом же ответе я также дал вам альтернативное решение, которое не SetWindowsHookEx()
- обработка WM_INPUT
сообщение от RAW Input API. В вашем вопросе не упоминалось, что вы используете FireMonkey вместо VCL. Я привел вам пример для VCL. Теперь я обновил этот ответ, включив в него пример FireMonkey.