Можно ли создать подокно, которое не будет деактивировать родитель?
Обычно при создании подокна (WS_POPUP) дочернее окно становится активным, а родительский становится деактивированным. Однако с меню оба остаются активными. По крайней мере, я предполагаю, что меню активно, по крайней мере, оно имеет фокус.
Пример: нажмите на меню "Файл" в блокноте, меню появится, но окно блокнота все еще выглядит активным.
Можно ли отразить это поведение либо в стиле окна, либо в ответ на конкретное сообщение?
Спасибо
Другой пример: поля со списком, кажется, показывают подокно, но не деактивируют окно. И вы можете нажать на это подокно, сохраняя при этом главное окно активации. Любые идеи о том, как захватить класс / стиль этого окна?
4 ответа
Раскрывающийся список в выпадающем списке - это что-то вроде хака, это как всплывающее, так и дочернее окно, я не могу рекомендовать такой подход (недокументированная комбинация стилей и IIRC, это немного глючит, чтобы сделать это с "нормальным" "плавающее окно / панель инструментов)
Это оставляет вам два варианта:
- WS_EX_NOACTIVATE (главное окно останется активным, плавающее окно не активно)
- Обрабатывать сообщения активации (оба окна будут выглядеть активными)
Если вы создадите всплывающее окно с помощью WS_EX_NOACTIVATE, оно не будет активировано пользовательским вводом (вы все равно могли бы активировать его программно), и, следовательно, ваше главное окно приложения все равно останется активным.
Я удивлен, что создание нового всплывающего окна активирует его. Обычно вам нужно вызвать SetActiveWindow. Однако, проверьте WM_ACTIVATE и WM_NCACTIVATE о том, как остановить деактивацию окна.
Многие люди упускают тот факт, что окна не имеют отдельного компонента диспетчера окон:- большинство обязанностей по управлению окнами выполняется каждым окном - обычно в DefWindowProc.
Большая часть позиционирования и активации / деактивации окна выполняется, в конечном счете, посредством вызова SetWindowPos, который всегда отправляет сообщение WM_WINDOWPOSCHANGING, позволяющее окну окончательно сказать, что происходит.
DefWindowProc также активирует собственное окно в ответ на щелчки мышью и так далее.
Результатом всего этого является то, что вполне возможно создать окна, которые никогда не принимают активацию - это требует глубокого понимания того, какие сообщения и ситуации могли привести к активации.
В конечном счете, я могу сказать, что ОЧЕНЬ удобно иметь настройку отладки, настроенную для удаленной отладки, чтобы вы могли взаимодействовать с отладчиком, не влияя на состояние активации системы, и, следовательно, поместить точку останова в окно в обработчике WM_ACTIVATE вопросов и просто отладить любую ситуацию, приводящую к нежелательной активации.
Если вы также хотите обрабатывать фокус клавиатуры, это может быть сложнее - обычно фокус дается активированному окну - но опять же это обычно DefWindowProc, отвечающий за назначение обоих. Я просто вижу в этом опасность, когда одно окно все еще явно активировано, а другое - в фокусе. Это сильно запутает любое вспомогательное программное обеспечение.
Я бы испытал желание выполнить ловушку сообщения уровня цикла сообщения - Подобный IsDialogMessage - чтобы отфильтровать нажатия клавиш, предназначенные для всплывающего окна.