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