Когда кто-то запускает вторую копию вашего приложения, которое допускает только один экземпляр, вы обычно хотите, чтобы вторая копия послала первой командную строку (и как-то разобралась бы с текущим каталогом), а затем вы хотите, чтобы первая копия вылезла на передний план. Но при этом люди часто встречаются с проблемой, что если вызовете в первом экземпляре
SetForegroundWindow
, она завершится неудачей.Проблема тут в том, что с точки зрения менеджера окон первый экземпляр программы получил какое-то сообщение и неожиданно попытался украсть передний план. Это сообщение не было сообщением ввода, поэтому оконный менеджер не видит никаких причин, которые давали бы вашей первой копии права на передний фон. У него нет доказательств, что первая копия выходит на передний план, отвечая на действие пользователя.
Есть несколько способов разобраться с этой проблемой. Проще всего - пусть вторая копия вызывает SetForegroundWindow. У второй программы есть на это право, потому что её только что запустил пользователь. И если программа забрала себе передний план, то она также может его и отдать - в нашем случае, передачей его окну первой программе.
Второй способ сделать это - пусть вторая программа вызовет функцию AllowSetForegroundWindow, указав PID первой программы прежде чем отправлять ей сообщение. Функция
AllowSetForegroundWindow
даёт возможность программе сказать менеджеру окон: "Всё в порядке, он со мной". А когда затем первый экземпляр попробует выдвинуть себя на передний план вызовом SetForegroundWindow
, менеджер окон скажет: "Ага, с ним нет проблем. Другая программа поручилась за него".Если вы передаёте право на передний план COM серверу, то вы можете использовать соответствующую COM функцию CoAllowSetForegroundWindow.
Во всех случаях заметьте, что вы не можете отдать что-то, что вам не принадлежит. Если у вас нет права на передний план, то вызов
AllowSetForegroundWindow
(или её эквивалентов) ничего не сделает: вы говорите менеджеру окон: "Всё в порядке, он со мной", а он вам отвечает: "Ты кто, чёрт побери, такой?".Упреждающий сварливый комментарий: "А всё же существует очень хитрый способ обойти правило и украсть передний план". Ага, а ещё находятся очень хитрые люди, которые находят способ украсть любовь. Если с миром всё в порядке, то обе группы людей рано или поздно себя обнаружат и будут страдать за свои злодеяния.
Обновление: удалил все комментарии, показывающие способы обойти правила. Ну вы даёте.
Ахахахахаа статья - огонь))) Поржал)))
ОтветитьУдалитьСпасибо)
> Обновление: удалил все комментарии, показывающие способы обойти правила. Ну вы даёте.
ОтветитьУдалитьЛол. :D
Хорошо :)!
ОтветитьУдалитьВ принципе, я согласен, что «левые» окна не должны выскакивать наверх и мешать.
ОтветитьУдалитьНо есть и исключения. К примеру, программа рабочего места оператора. Эта программа должна иметь приоритет над другими. И, как минимум, окно авторизации должно быть постоянно на виду. Можно, конечно, сказать, что нужно запускать в «монопольном» режиме, чтобы никого больше не было. Но, к сожалению, не все заказчики на это согласны. Они желают и программу видеть наверху (хотя бы её первое окно — авторизации), и иметь возможность работать с другими программами. А «заказчик всегда прав» ((. Вот и приходится изобретать методы обхода.