Встраивание HWND во внешний процесс с использованием SetParent - PullRequest
17 голосов
/ 04 октября 2008

Я пытаюсь встроить окно из моего процесса в окно внешнего процесса, используя функцию SetParent , и столкнулся с несколькими проблемами, с которыми, я надеюсь, кто-то может мне помочь. Прежде всего, вот схема того, что я сейчас делаю, чтобы встроить свое окно в приложение:

HWND myWindow; //Handle to my application window
HWND externalWindow; //Handle to external application window

SetParent(myWindow,externalWindow);

//Remove WS_POPUP style and add WS_CHILD style
DWORD style = GetWindowLong(myWindow,GWL_STYLE);
style = style & ~(WS_POPUP);
style = style | WS_CHILD;
SetWindowLong(myWindow,GWL_STYLE,style);

Этот код работает, и мое окно появляется в другом приложении, но вызывает следующие проблемы:

  • Когда мое окно получает фокус ввода, основное окно приложения внешнего процесса теряет фокус (то есть строка заголовка меняет цвет)
  • Команды сочетания клавиш основного приложения не работают, когда мое окно имеет фокус

Кто-нибудь знает обходной путь для этого? Я хотел бы, чтобы мое окно рассматривалось как еще одно дочернее окно основного приложения.

Ответы [ 4 ]

11 голосов
/ 03 декабря 2008

Ну, я наконец-то нашел ответ на свой вопрос.

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

Кроме того, можно использовать функцию TranslateAccelerator в ответ на сообщения WM_KEYDOWN, чтобы обеспечить запуск акселераторских сообщений основного приложения.

4 голосов
/ 17 августа 2011

Я не уверен, что вы все еще интересуетесь этой темой после почти трех лет. Я работаю над аналогичным приложением. Мое решение состоит в том, чтобы изменить стиль окна перед вызовом SetParent. С этим решением мне не нужно вызывать AttachThreadInput.

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

0 голосов
/ 06 июля 2017

Я столкнулся с той же проблемой, после тщательного прочтения документа MSDN нашел, что это легко исправить.

Вы должны удалить WS_POPUP и добавить WS_CHILD ДО , который вы вызываете setParent

В MSDN указано:

По причинам совместимости SetParent не изменяет стили окна WS_CHILD или WS_POPUP для окна, родительский элемент которого изменяется. Поэтому, если hWndNewParent равен NULL, вам также следует очистить бит WS_CHILD и установить стиль WS_POPUP после вызова SetParent. И наоборот, если hWndNewParent не равен NULL и окно ранее было дочерним для рабочего стола, вам следует очистить стиль WS_POPUP и установить стиль WS_CHILD перед вызовом SetParent. https://msdn.microsoft.com/en-us/library/windows/desktop/ms633541(v=vs.85).aspx

0 голосов
/ 04 октября 2008

Я нашел некоторую информацию об этом в Catch22.net , используя сообщение WM_NACTIVE.

Это в разделе Предотвращение деактивации окна. Надеюсь, это поможет.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...