В каких случаях отправляется WM_ACTIVATE? - PullRequest
1 голос
/ 19 января 2010

Я пытаюсь отладить огромное приложение Win32 GUI (у меня есть полные источники), разделенное на несколько процессов.Проблема заключается в следующем: в одном процессе у меня есть диалоговое окно со списком, когда я дважды щелкаю элемент в списке, запускается другой процесс, который создает свое собственное окно, которое выводится на передний план и закрывает начальный диалог.Если я выполняю некоторые манипуляции (которые я пока не могу полностью объяснить, поскольку я еще не до конца их понимаю), то что-то заставляет начальный диалог начать мигать на панели задач.

Я пробовал Microsoft Spy ++ и вижу это всякий раз, когдаЯ делаю, что манипуляция WM_ACTIVATE отправляется в диалог, в большинстве случаев она имеет следующие параметры:

fActive: WA_INACTIVE fMinimized:False hwndPrevious:(null)

, и в этих случаях диалог не начинает мигать.Но время от времени параметры равны

fActive: WA_ACTIVE fMinimized:False hwndPrevious:(null)

, и это точно соответствует мигающему окну.

MSDN говорит, что WM_ACTIVATE отправляется с WA_ACTIVE, когда окно активируется каким-либо иным способом, кроме щелчка мыши (например, с помощью вызова функции SetActiveWindow или с помощью интерфейса клавиатуры для выбора окна) .

Теперь в коде приложения SetActiveWindow() никогда не вызывается, и я ничего не делаю с клавиатурой, которая может переключать окна.

Какие другие причины возможны для отправки WM_ACTIVATE с помощью WA_ACTIVE?

Ответы [ 2 ]

4 голосов
/ 10 декабря 2012

Ваша проблема вызвана SetForegroundWindow(). Он имеет контрмеры, которые не позволяют процессу толкнуть окно в лицо пользователю, когда она активно работает в другом приложении.

SetForegroundWindow() происходит, когда второй процесс создает свое окно и неявно пытается выйти с ним на передний план. (Вы сказали столько же, когда написали «выведен на фронт».)

Первое приложение должно вызвать AllowSetForegroundWindow(), чтобы сказать «все в порядке, это окно может принимать активацию переднего плана от меня».

Обратите внимание, что если вы сделаете это, пользователь может столкнуться с такой ситуацией:

  • Пользователь нажимает на элемент списка.
  • Второй процесс запускается медленно.
  • Пользователь нажимает на что-то еще в первом приложении. (Потерянное терпение.)
  • Второй процесс крадет передний план у первого приложения. (Пользователь разочарован, потому что он занимался чем-то другим.)

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

1 голос
/ 12 октября 2010

Если вы создаете окно в стиле WS_VISIBLE, оно будет активировано при создании.

Если вы сделаете ShowWindow(SW_SHOW), оно активирует окно (используйте SW_SHOWNA)

Если вы сделаете SetWindowPos без флага SWP_NOACTIVATE, окно будет активировано.

Наконец, если вы создаете окно с шаблоном (CDialog), оно всегда активируется.

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