Плагин DLL, создающий окно с парентами, неправильно обрабатывает сообщения

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

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

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

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

18.08.2008 23:56:34
4 ОТВЕТА

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

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

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

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

0
19.08.2008 00:52:48

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

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

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

Удачи!

1
19.08.2008 12:44:45

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

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

0
27.08.2008 12:18:22

У DLL есть собственный объект TApplication.

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

-

Майкл

0
24.01.2009 17:58:06