2013-07-22 2 views
1

Мое приложение должно получить фокус, когда оно получило вызов внешним инструментом (через API), я знаю, что по умолчанию это значит, что он должен просто мигать на панели задач, но в этом случае это абсолютно не то поведение, которое я хочу. В этом случае я пытаюсь получить фокус с помощью «this.Activate()» (C#).Общие сведения о SystemParametersInfo SPI_SETFOREGROUNDLOCKTIMEOUT

Здесь используется ForeGroundLockTimeOut. Однако у меня возникла небольшая проблема с пониманием SystemParameterInfo SPI_SETFOREGROUNDLOCKTIMEOUT.

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

(для получения дополнительной информации переменной «Вал» является IntPtr, который установлен в 0)

SystemParametersInfo(SPI_SETFOREGROUNDLOCKTIMEOUT,0,val,SPIF_SENDWININICHANGE + SPIF_UPDATEINIFILE); 

это один будет изменить ключ реестра, который обрабатывает тайм-аут (HKEY_CURRENT_USER \ Control Panel \ Desktop \ ForeGroundLockTimout) Поскольку это изменит поведение всех приложений, это действительно последнее средство для использования.

Теперь я подумал, что если я не обновляю раздел реестра. Так что я попытался это:

SystemParametersInfo(SPI_SETFOREGROUNDLOCKTIMEOUT, 0, val, 0); 

Однако это не меняет поведение моего приложения в любом случае, но

SystemParametersInfo(SPI_SETFOREGROUNDLOCKTIMEOUT,0,val,SPIF_SENDWININICHANGE); 

делает.

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

Примечание. Если вы хотите протестировать это поведение, протестируйте его, когда Visual Studio не работает, хотя он работает (даже если это решение не загружено), он изменяет поведение приложения в получении фокуса в любом случае.

+1

* В любом случае он изменяет поведение приложения в получении фокуса. * Вы даже [прочитали прекрасное руководство] (http://msdn.microsoft.com/en-us/library/windows/desktop/ms633539 (v = vs.85) .aspx)? * Система ограничивает, какие процессы могут устанавливать окно переднего плана. Процесс может установить окно переднего плана, только если выполняется одно из следующих условий: ... Процесс переднего плана отлаживается. * То, что вы пытаетесь сделать, напоминает мне об этом [http: //blogs.msdn. ком/б/oldnewthing/Архив/2011/03/10/10138969.aspx). –

+0

Также напоминает мне об этом [http://blogs.msdn.com/b/oldnewthing/archive/2009/02/20/9435239.aspx). –

+0

Да, я читал его, и я не пытаюсь сделать мое окно самым верхним, он работает в фоновом режиме большую часть времени, я хочу, чтобы он получал фокус, когда он вызывается через api (добавит это к вопросу) но он не должен быть максимальным, даже если он имеет фокус. – Visions

ответ

4

Это не настройка для каждого приложения, это глобальная системная настройка. Невозможно установить его только для своего приложения, поэтому, когда вы вызываете SystemParametersInfo с 0 для последнего параметра, ничего не происходит.

С другой стороны, когда вы используете SPIF_SENDWININICHANGE, новый параметр получает широковещательную передачу в виде сообщения WM_SETTINGCHANGE. (. Вот почему ручное редактирование реестра является неправильным, что нужно сделать, всегда вызывать документированный API)

Кроме того, этот код является неправильным:

SPIF_SENDWININICHANGE + SPIF_UPDATEINIFILE 

Объединяет два флага, вы должны использовать логический оператор OR (|), а не оператор добавления (+). В этом конкретном случае, поскольку 0x1 + 0x2 и 0x1 | 0x2 оба равны 3, кажется, это работает, но это просто случайность.

Реальное решение этой проблемы не требует манипулирования глобальными настройками (потому что вы, конечно же, не хотите делать это на клиентских машинах, даже если с ними все в порядке). Вам нужно работать с системой, а не пытаться работать против нее.В модели системы процесс, который в настоящее время имеет фокус, - это тот, у кого есть привилегия установки/изменения фокуса. Таким образом, есть три основных варианта:

  1. Просто есть внешний вызов инструмента SetForegroundWindow самих и передавать окно вашего приложения в качестве параметра. Это полностью позволяет вашему приложению активировать себя.

  2. Используйте функцию AllowSetForegroundWindow, чтобы делегировать привилегии переднего плана для внешнего инструмента для вашего приложения. Он должен вызывать эту функцию, передавая идентификатор процесса вашего приложения в качестве параметра. Таким образом, когда ваше приложение называет SetForegroundWindow, оно будет работать должным образом.

  3. В зависимости от того, как ваш инструмент и приложение разработаны, вы можете просто иметь внешний инструмент запуск приложения. Как и в случае the documentation, если процесс запускается процессом переднего плана, ему разрешено задавать окно переднего плана.

+1

+1 кто-то, кто знает, как читать точное руководство –

+0

Хм, я не уверен, что это абсолютно правильно. когда я вызываю его с помощью SPIF_SENDWININICHANGE, меняет поведение моего приложения, а не других. – Visions

+0

И учитывая ваше реальное решение, проблема в том, что я не обязательно могу изменить код внешнего инструмента – Visions

0

SPIF_UPDATEINIFILE - Записывает новый параметр всей системы в профиль пользователя. SPIF_SENDCHANGE - трансляция сообщения WM_SETTINGCHANGE после обновления профиля пользователя.

Смежные вопросы