Разработка для панели задач Windows 7 — AppID (ч.1)

Автор: Topol Четверг, Май 3rd, 2012 Нет комментариев

Рубрика: Операционные системы

Это первая статья в новом цикле статей, посвященных панели задач Windows 7 . Разработчикам стоит уделять панели задач первоочередное внимание. Мы должны понять новые возможности панели, чтобы создавать приложения, эффективно работающие с ней, чтобы расширить возможности пользователей и сделать их работу с ОС максимально удобной.

Я полагаю, что вы успели ознакомиться с базовой функциональностью и нововведениями панели задач Windows 7. Если же вы не знакомы, рекомендую вам посмотреть видео-обзор функциональных возможностей панели задач Windows 7 на Channel 9 и прочитать статьи в блоге E7. Это позволит вам лучше понять, о чем идет речь в сегодняшней в статье.

При первом запуске системы новая панель задач, пожалуй, является наиболее заметным нововведением в Windows 7. В Windows 7 панель задач представляет собой механизм для запуска приложений и переключения окон, консолидирующим возможности панелей задач из предыдущих версий Windows и, в частности, панель быстрого запуска, недавние документы, уведомления и окна запущенных приложений. В дополнение к старым возможностям панель задач Windows 7 обладает новыми: списками быстрого перехода, интерактивными миниатюрами открытых окон и несколькими иными. Но для начала давайте заложим основу для нашей беседы и определимся с терминологией.

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

Возьмем, к примеру, кнопку Windows Media Player: она не обрамлена и ничем не выделяется. Это свидетельствует о том, что Windows Media Player не запущен. Однако, приложение закреплено на панели задач и будет оставаться там, если мы не уберем ее. Вокруг иконки Windows Explorer можно видеть тусклую рамку: это свидетельствует о том, что приложение работает, но не активно. У Visual Studio иконка в более непрозрачной прямоугольной рамке, указывающей на, что в данный момент пользователь работает с этим приложением. Обратите внимание, что в Word открыто много документов и они сгруппированы в одну иконку приложения. Очень важно понимать логику создания и группировки окон приложений на панели задач.

Существенное количество приложений, работающих в Windows 7 (например, Office Word 2007 и Visual Studio 2008), не были предназначены для работы с новой панелью задач Windows 7. Так каким же образом все они взаимодействуют с панелью задач и поддерживают списки переходов в Word? В основе лежит специальный Application ID, который автоматически присвается запускаемым приложениям после их запуска. Каждое запускаемое приложение имеет свой AppID, присваиваемый либо самой Windows, либо приложением. Это не GUID, а простой string-параметр, состоящий из128 символов максимально. Все приложения и окна, имеющие одинаковый параметр AppID, включая списки переходов, группируются в одну кнопку на панели задач. Важно понимать, что каждый компонент (процесс, ярлык, окно, кнопка или документ) имеет ассоциированное с ним значение AppID.

Вы спросите, откуда берется этот AppID? Как уже упоминалось ранее, ОС генерирует код для приложения, используя простой принцип: ОС пытается экстраполировать приложения от его окна. Приложения, как правило, имеют хотя бы одно окно, у которого система и запрашивает AppID. Однако, большинство приложений не имеют AppID, ассоциированных с каждым окном (или вообще не имеют AppID), поэтому система вынуждена обращаться к процессу, в котором выполняется окно. У каждого процесса есть несколько свойств, которые может опрашивать ОС, к примеру, исполняемый файл процесса. Но даже в этом случае, процесс не гарантирует четкого разделения. Различные ярлыки могут использовать разные параметры для запуска одного и того же исполняемого файла и запускать совершенно разные приложения (вспомните хотя бы приложения типа “launcher”), которые сгруппированы под одной кнопкой на панели задач. В таких случаях ОС может исследовать ярлык, отыскать исполняемый файл, параметры запуска и т.д. Обратите внимание, в случае зарегистрированного типа файла регистрация указывает на приложение, которое запускается двойным щелчком на файле. Это еще один способ получения AppID. Нижеприведенное изображение иллюстрирует процедуру автоматического получения AppID:

Если вам интересны внутренние составляющие панели задач Windows 7, рекомендую вам посмотреть несколько видео: видео Роба Джэретта (Rob Jarrett) и Бена Бетса (Ben Bets) - За кулисами панели задач windows 7 и Обзор списков переходов.

Несмотря на то, что ОС может автоматически присвоить AppID, многие разработчики хотят иметь больший контроль над AppID для своего приложения или отдельного окна приложения. Предположим, что у вас есть приложения, запускающие другие приложения (таким образом работает отладка приложений с помощью Visual Studio). Или у вас есть несколько различных приложений и процессов, которые вы хотите сгруппировать под одной кнопкой панели задач. В любом случае, если вы пишете новое приложение для Windows 7, мы настоятельно рекомендуем вам указать свой собственный идентификатор приложения, согласно приведенной инструкции.

Теперь давайте перейдем к непосредственным тестам API, который позволяет контролировать ассоциации AppID для вашего приложения.

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

Код:
SetCurrentProcessExplicitAppUserModelID(c_rgszAppID[0]);

где c_rgszAppID[0] — указатель на string-параметр. Необходимо отметить, что в соответствии с SDK документацией этот метод должен быть применен в ходе загрузки приложения перед появлением его интерфейса или манипуляций со списками переходов.

В управляемом коде из последней версии API-библиотек вы можете использовать свойство AppID как часть объекта Taskbar, который можно найти в именном пространстве Microsoft.WindowsAPICodePack.Shell.Taskbar. Используя это свойство, можно присваивать AppID.

Присвоить AppID отдельному окну чуть сложнее. Выполняется это вызовом функции SHGetPropertyStoreForWindow и дальнейшей манипуляцией объектаIPropertyStore для получения необходимого свойства:

Код:
void SetAppID(HWND hWnd, int iAppID)
{
IPropertyStore *pps;
HRESULT hr = SHGetPropertyStoreForWindow(hWnd, IID_PPV_ARGS(&pps));
if (SUCCEEDED(hr))
{
PROPVARIANT pv;
if (iAppID >= 0)
{
hr = InitPropVariantFromString(c_rgszAppID[iAppID], &pv);
}
else
{
PropVariantInit(&pv);
}
if (SUCCEEDED(hr))
{
hr = pps->SetValue(PKEY_AppUserModel_ID, pv);
PropVariantClear(&pv);
}
pps->Release();
}
}

В приведенном фрагменте можно видеть, как извлекаются свойство окна вызовом SHGetPropertyStoreForWindow, передачей hWnd в качестве ссылки на окно. Затем инициируем InitPropVariantFromString(c_rgszAppID[iAppID], &pv), вариант свойства со строкой, представляющей AppID для конкретного окна. И, наконец, мы устанавливаем значение нового свойства для окна.

К сожалению, нынешний Windows API Code Pack не поддерживает установку AppID для отдельных окон, хотя все, что вам нужно сделать, — это добавить следующую функцию в файл Taskbar.cs:

Код:
private static void SetWindowAppId(string appId)
{
Microsoft.WindowsAPICodePack.Shell.ShellNativeMethods.SetWindowAppId
(OwnerHandle, «name here»);
}

Поскольку в Windows API Codec Pack присутствует исходный код, вы можете проверить реализую функции SetWindowAppId и увидеть собственными глазами, что она очень похожа на пример SetAppID, приведенный выше. Обратите внимание, что вовсе не обязательно использовать полное имя сборки «Microsoft.WindowsAPICodePack.Shell ‘ — я использовал его, чтобы объяснить иерархию Windows API Code Pack.

Кстати, окно AppID динамично, так что вполне возможно чтобы окно отображалось как одна кнопка панели задач, а затем изменить его AppID, чтобы оно появилось на совершенно другой кнопке. Это имеет интересный эффект. Допустим, список перехода прикреплен к кнопке на панели задач (с конкретным AppID), поэтому одно и то же окно может отображать разные списки перехода при прикреплении к другим кнопкам панели задач. Это может ввести пользователей в заблуждение, поэтому мы рекомендуем установить окну определенный AppID и придерживаться его, используя тот же процесс для определения AppID при каждом отображении окна.

Источник: thevista.ru

Оставить комментарий

Чтобы оставлять комментарии Вы должны быть авторизованы.

Похожие посты