Плагин DLL, создающий окно с парентами, неправильно обрабатывает сообщения - PullRequest
1 голос
/ 19 августа 2008

Я создаю инфраструктуру плагинов, где мое приложение загружает серию DLL плагинов, затем создает новое окно и передает дескриптор этого нового окна плагину. Затем плагин может использовать этот дескриптор для создания собственного графического интерфейса.

Кажется, все работает очень хорошо. Единственная проблема заключается в том, что когда я нажимаю TAB на виджете плагина (например, в окне редактирования), он не переходит на другой виджет. Я понял, что некоторые сообщения Windows передаются, а некоторые нет. WM_KEYDOWN передается для других ключей, потому что я могу печатать в поле ввода, но это сообщение не обрабатывает клавишу TAB.

Надеюсь, у кого-нибудь есть подсказка.

Я использую Borland VCL с CBuilder, но я думаю, что я мог бы использовать любой фреймворк под WIN32 для создания этих плагинов, поскольку они никогда не знают, как создавались их родительские окна.

Ответы [ 4 ]

1 голос
/ 19 августа 2008

Это действительно очень сложный вопрос.

Когда вы нажимаете TAB, фокус переходит к другому элементу управления, только когда эти элементы управления принадлежат модальному диалоговому окну. На самом деле есть некоторые кнопки, такие как ESC, LEFT, RIGHT, DOWN, UP, TAB, которые модальная функция диалогового сообщения обрабатывает особым образом. Если вы хотите, чтобы эти клавиши работали аналогично с немодальным диалоговым окном или любым другим окном, вы должны изменить свою функцию обработки сообщений и использовать IsDialogMessage внутри. Более подробную информацию о функции IsDialogMessage вы найдете в MSDN, чтобы лучше разобраться в этом, вы также можете проверить Диалоговые окна раздел.

И, как уже упоминалось, вы должны установить WS_TABSTOP и WS_GROUP при необходимости.

Удачи!

0 голосов
/ 24 января 2009

DLL имеет свой собственный объект TApplication.

для обеспечения единообразной обработки ключей. когда DLL загружается. назначить DLL :: TApplication для EXE :: TApplication Обязательно сделайте обратное при выходе.

-

Michael

0 голосов
/ 27 августа 2008

Я полагаю, что вы страдаете от наличия разных экземпляров VCL в каждой из ваших библиотек и библиотек. Классы из dll не совпадают с классами из вашего exe, даже если они называются одинаковыми. Также глобальные переменные (Приложение, Экран) не разделяются между ними. Это также не память, поскольку у них обоих есть свой менеджер памяти.

Решение состоит в том, чтобы dll и exe совместно использовали библиотеку VCL и менеджер памяти. Я не разработчик BCB, но разработчик Delphi. В Delphi мы просто использовали бы rtl и vcl в качестве пакетов времени выполнения. Может быть, вы могли бы сделать эквивалент BCB.

0 голосов
/ 19 августа 2008

Полагаю, вам придется предпринять следующие шаги:

  1. Подкласс ваши элементы управления редактированием (и другие элементы управления при необходимости).
  2. Захватите сообщение WM_KEYDOWN в WndProc элемента управления редактированием.
  3. Проверьте, не нажата ли в настоящий момент клавиша Shift (используя GetKeyState или аналогичный).
  4. Вызовите GetWindow , передав дескриптор вашему элементу управления редактирования и либо GW_HWNDPREV, либо GW_HWNDNEXT в зависимости от того, удерживается ли shift Это даст вам указатель на окно, которое должно получить фокус.
  5. Позвоните SetFocus и передайте дескриптор окна, полученный на шаге 4.

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

Надеюсь, это поможет!

...