Странное поведение wm_keydown с THtmlEdit

#delphi #firemonkey

#delphi #firemonkey

Вопрос:

Это странно: это ситуация

Приложение создает форму редактирования во время выполнения из XML-документа. Дизайн пользовательского интерфейса / UX таков, что существует три уровня вложенных TTabControls, и для последнего (самого низкого) уровня TTabItem создается во время выполнения. У этого есть TVertScrollBox, который сам содержит мой элемент управления сеткой столбцов и который (наконец-то!) Содержит THtmlEditor.

Проблема в том, что при создании элементов управления и загрузке содержимого THtmlEdit изначально игнорирует keydown. Он будет реагировать на события мыши, курсор может быть установлен. Переключение на другую вкладку верхнего уровня или из всего приложения и обратно устраняет проблему, и редактор отвечает на сообщения keydown.

Я попытался ввести точку останова procedure THtmlEditor.KeyDown() … а затем отследить цепочку вызовов. Кажется, что ничто не ведет себя по-другому. Я уделил особое внимание фокусу ввода, явно вызывая Editor .SetFocus, хотя это, по-видимому, уже вызвано…

Я попытался ввести условную точку останова в function TPlatformWin.HandleMessage: Boolean; … и мое единственное наблюдение заключается в том, что в нерабочем режиме вызов DispatchMessage(Msg) не поступает в редактор или его родительскую форму.

Я пытался создать MDC для этого, копируя структуру, описанную выше, но… это всегда работает!

Что я могу попробовать дальше? Кто-нибудь видел это поведение (и исправил его)?

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

Деталь, которую я не упомянул — не думал об этом — заключается в том, что для отображения условия ошибки элемент управления, сфокусированный перед THmtlEditor, является TWebBrowser . Если я установлю фокус на TEdit после TWebBrowser, а затем на THtmlEditor, похоже, это сработает.

Гррр!

Комментарии:

1. Возможно, у вас есть KeyPreview свойство, установленное true в вашей форме.? Это может привести wm_keydown к тому, что сообщение уже будет обработано вашей формой до того, как оно попадет в ваш HTML-редактор. Также, возможно, у вас есть какой-то другой элемент управления, который мог бы принимать ввод с клавиатуры, например, в поле редактирования? Если у вас есть, проверьте, могут ли ваши нажатия клавиш не обрабатываться этим элементом управления.

2. @SilverWarrior Это приложение Firemonkey, и я не думаю, что есть KeyPreview свойство.

Ответ №1:

Это только половина ответа, но для дальнейшего использования это то, что я сделал:

Это ошибка 🙁

Я поместил TEdit в основную форму и сделал его невидимым. Затем я добавил обработчик OnFocusChanged в основную форму, который устанавливает логический флаг-ловушку, чтобы отслеживать, был ли TWebBrowser ранее сфокусирован.

Для экземпляров THtmlEditor я добавил OnClick обработчик, который проверяет флаг-ловушку и делает TEdit видимым, вызывает SetFocus его, повторно скрывает TEdit и возвращает True, чтобы THtmlEditor мог повторно установить фокус на себя. Флаг-ловушка предназначен для предотвращения ненужной потери фокуса, если пользователь просто нажимает на THtmlEditor.

Следующим шагом, до которого я, возможно, никогда не доберусь, будет отслеживание кода фокусировки для TEdit. Я подозреваю, что все это связано ITextInput с тем, что поддерживает TEdit, а THtmlEditor — нет.