Вопрос пользователя заключается в том, как предотвратить получение фокуса формой при её перетаскивании, когда используется стиль границы bsToolWindow. Пользователь уже обрабатывает сообщение WM_MOUSEACTIVATE, но это не помогает, когда форма перетаскивается. Попытка добавить WS_EX_NOACTIVATE в ExStyle также не принесла успеха.
Подходы к решению проблемы:
Использование WM_NCACTIVATE и сброс фокуса:
В сообщении WM_NCACTIVATE можно сбросить фокус на окно с полем ввода после перетаскивания клавиатуры. Необходимо отслеживать, на какое окно был установлен фокус, и возвращать его обратно после перетаскивания.
Альтернативный подход с BorderStyle = bsNone:
Можно установить BorderStyle в bsNone и организовать перетаскивание формы, используя события мыши, например, MouseDown, MouseMove, MouseUp.
Пример реализации:
Для решения задачи можно использовать следующий подход:
Создать поле FocusedForm для хранения ссылки на форму, которая в данный момент имеет фокус.
Переопределить обработчики сообщений WM_MOUSEACTIVATE и WM_NCACTIVATE.
Реализовать метод ShowUnfocused, который будет отображать форму и сохранять ссылку на форму с фокусированным полем.
procedure TKbdForm.ShowUnfocused(FocusedWindow: THandle);
begin
FocusedForm := FocusedWindow;
Show;
end;
procedure TKbdForm.FormShow(Sender: TObject);
begin
SetForegroundWindow(FocusedForm);
end;
procedure TKbdForm.WMMouseActivate(var Message: TWMMouseActivate);
begin
Message.Result := MA_NOACTIVATE;
end;
procedure TKbdForm.WMNCActivate(var Message: TWMNCActivate);
begin
Message.Result := 1; // важно
SetForegroundWindow(FocusedForm);
end;
При вызове клавиатуры, например, из поля ввода, можно использовать следующий код:
procedure TForm17.EditClick(Sender: TObject);
begin
KbdForm.ShowUnfocused(self.Handle);
(Sender as TWinControl).SetFocus;
end;
Альтернативный подход с использованием стилей VCL:
Можно использовать более сложный подход с регистрацией стилевого хука и переопределением некоторых сообщений:
type
TKeyboardFormStyleHook = class(TFormStyleHook)
protected
procedure WMNCActivate(var Message: TWMNCActivate); message WM_NCACTIVATE;
end;
procedure TKeyboardFormStyleHook.WMNCActivate(var Message: TWMNCActivate);
begin
Message.Active := False;
inherited;
end;
class constructor TKeyboardForm.Create;
begin
TCustomStyleEngine.RegisterStyleHook(TKeyboardForm, TKeyboardFormStyleHook);
end;
// Остальные методы и свойства для управления фокусом
Этот подход позволяет избежать нежелательных визуальных эффектов, связанных с переключением фокуса, и улучшить взаимодействие с формами VCL стилей.
Заключение:
Предложенные подходы позволяют предотвратить получение фокуса формой при её перетаскивании, что особенно важно при использовании элементов ввода, таких как виртуальная клавиатура, в приложениях на Delphi. Использование правильных обработчиков сообщений и управления фокусом окна позволяет улучшить пользовательский опыт и избежать нежелательного поведения форм.
Пользователь ищет способ предотвратить получение фокуса формой, использующей стиль границы `bsToolWindow`, во время её перетаскивания, несмотря на обработку сообщения `WM_MOUSEACTIVATE` и попытку добавить `WS_EX_NOACTIVATE` в `ExStyle`.
Комментарии и вопросы
Получайте свежие новости и обновления по Object Pascal, Delphi и Lazarus прямо в свой смартфон. Подпишитесь на наш Telegram-канал delphi_kansoftware и будьте в курсе последних тенденций в разработке под Linux, Windows, Android и iOS
Материалы статей собраны из открытых источников, владелец сайта не претендует на авторство. Там где авторство установить не удалось, материал подаётся без имени автора. В случае если Вы считаете, что Ваши права нарушены, пожалуйста, свяжитесь с владельцем сайта.