Панель задач Windows 7, часть 1: основы
Это первая статья из серии статей и вебкастов о новой панели задач Windows 7. Для получения дополнительной информации на Channel 9 вы можете посмотреть вебкаст Jump into the Windows 7 Taskbar Jump Lists или же просмотреть всю серию вебкастов по Windows 7 Taskbar. Также там можно скачать и примеры кода.
Одно из первых изменений в Windows 7, которому разработчики должны уделить свое внимание – новая панель задач Windows. Она обладает рядом новых функций, поэтому очень важно, чтобы разработчики понимали их смысл и могли использовать ее преимущества, чтобы сделать работу пользователя с системой более удобной.
При первом запуске Windows 7 новая панель задач кажется, пожалуй, наиболее заметным нововведением. Стоит сказать, что панель задач Windows 7 – это механизм запуска приложений и переключения между окнами, который объединяет возможности, имеющиеся в предыдущих версиях Windows: панель быстрого запуска, недавно использовавшиеся документы, область уведомлений, ярлыки рабочего стола, а также окна запущенных приложений.
Если вы не знакомы с данной темой и не видели новую панель задач Windows 7, рекомендую посмотреть замечательную презентацию Чайтаньи Сари (Chaitanya Sareen), проведенную во время доклада Welcome to the New Desktop на конференции PDC 2008. Она прольет свет на некоторые темы, о которых будет идти речь в данной статье. Дополнительная информация о панели задач Windows 7 может быть найдена в статье «Панель задач в Windows 7» из блога E7 и в серии вебкастов Windows Taskbar на Channel 9.
Ну а в этой статье мы расскажем о функциональных возможностях и программной модели панели задач Windows 7. Должен сразу оговориться, что статья не претендует на роль всеобъемлющего пошагового гида для разработчика панели задач Windows 7. Скорее, расширенное описание. За дополнительными материалами о панели задач Windows 7 обращайтесь к будущим статьям в нашем блоге.
Панель задач Windows 7 задумывалась с одной простой целью – обеспечить пользователей простым и быстрым доступом к тем элементам, которые они используют повседневно. Такими элементами могут выступать и изображения, и музыка, и документы, и ярлыки приложений или папок. Под облегчением и ускорением доступа мы понимаем получение доступа к часто используемым приложениям в один щелчок или значительное уменьшение количества щелчков, необходимых для выполнения операции. Кроме того, облегчение и ускорение доступа также означает, что пользователи должны иметь возможность сразу же перейти к тем материалам, с которыми они собираются работать, и могут начать работать с ними в один щелчок мыши. И с этой целью в Windows 7 появилась концепция всплывающих списков – Jump Lists.
Функцию Jump Lists следует расценивать в качестве аналога меню Start, но для конкретного приложения. Образно говоря, типичный всплывающий список состоит из имен существительных (назначений) и глаголов (задач программы). С его помощью можно выполнить типовую или избавиться от необходимости запускать приложение и затем выбирать необходимой документ. На приведенном ниже рисунке показано меню Jump Lists для Microsoft Office Word. В категории "Recent" представлен перечень документов, с которыми я недавно работал в Office Word. Выбрав один из документов в списке, этот документ будет мгновенно загружен в Word.
После первого запуска операционной системы в меню Jump Lists включены лишь стандартные задания панели задач. В них входят: запуск нового экземпляра приложения, прикрепление или открепление приложения к панели задач, а также закрытие приложения. Вы можете открыть меню Jump List, щелкнув правой кнопкой на значке приложения в панели задач. Также можно настроить меню Jump Lists для своего приложения:
Изображение из презентации Роберта Джаретта (Robert Jarrett) с PDC 2008
Формулировки в Windows 7 SDK звучат следующим образом:
Назначения (от англ. destinations) – это элементы, представленные в категориях "Recent" и "Frequent" (на изображении выше это категория Important) в зависимости от частоты использования. Назначениями могут быть файлы, папки, сайты или любые другие элементы. Назначения могут быть прикреплены или удалены пользователем из меню Jump List. Обычно они представлены элементами IShellItem, но также могут быть и элементами IShellLink.
Задачи (от англ. tasks) – это часто выполняемые действия, которые доступны всем пользователям приложения независимо от пользовательских шаблонов. Задачи могут быть прикреплены или откреплены. Задачи представлены объектами IShellLInk, так как, по сути, являются ссылками (с опциональными параметрами) на действия – "Actions".
Как разработчики мы вправе:
Контролировать назначения у приложений (тех элементов, к которым мы хотим обеспечить доступ через меню Jump List)
· Назначением может быть одна из известных категорий, например, Recent или Frequent.
· Категория Custom аналогична иным категориям, но при этом позволяет разработчику самому присваивать ей имя, а также наполнять содержимым.
· Категория Pinned рассчитана на прикрепленные элементы, к которым пользователи хотят иметь постоянный доступ в своих меню Jump Lists.
Определять общие задачи
· Панель задача сама по себе содержит ряд стандартных задач, среди которых запуск или закрытие приложений, возможность прикрепить или открепить их от панели задач. Как разработчики мы не можем контролировать эти задачи, но мы можем изменять пользовательские.
· Пользовательские задачи – это общедоступные задачи, которые разработчик хочет сделать доступными в меню Jump List и которые позволят совершать определенные действия прямо из Jump List. Например, воспроизвести музыку из библиотеки не переключаясь на плеер. Обычно это приводит к автоматическому запуску приложения и выполнению задачи. Повторюсь еще раз: это позволяет сэкономить массу времени и свести до минимума количество щелчков, необходимых для выполнения задачи.
Теперь самое время поговорить о программной модели панели задач. У панели задач, как и у любого другого компонента Windows Shell, есть свой набор API, доступный через набор COM-интерфейсов. Однако, перед тем, как перейти к использованию Windows Taskbar COM API, стоит выполнить ряд действий.
Шаг первый: воспользоваться стандартным набором назначений и задач
По умолчанию в меню Jump List содержится категория Recent, которая автоматически заполняется у приложений, которые работают с файлами с помощью функции SHAddToRecentDocs. Эта функция добавляет использованный элемент (документ) в список оболочки недавно открытых документов. В дополнение к обновлению списка недавно открытых документов оболочка также добавляет ссылку на папку Recent. Панель задач Windows 7 использует этот список и папку Recent для того, чтобы заполнять список недавно использовавшихся документов в Jump Lists.
Windows также может сделать эту работу за вас, если формат файла вашего приложения имеет зарегистрированный обработчик (это не обязательно должен быть стандартный обработчик). В любой момент, когда вы дважды щелкните на файле с зарегистрированным обработчиком, Windows еще до запуска приложения, автоматически вызовет SHAddToRecentDocs от его имени. Это действие поместит элемент в список недавних документов Windows и в категорию Recent меню Jump List. Тоже самое происходит при открытии файла через диалоговое окно открытия файла Windows.
В обоих случаях используется стандартное поведение Windows когда имеется зарегистрированный Application ID и обработчик файла, благодаря которым эти файлы ассоциируются со списками Recent и Frequent. Windows автоматически размещает файл в данных списках, если вы намеренно не отключали эту функцию, используя COM API. Очевидно, что у пользователей также есть возможность удалить любой элемент списка Jump Lists. Удаленный из списка Jump List элемент попадает в список Removed, о котором мы поговорим чуть позже.
Шаг второй: создать собственную категорию
Если категории Recent или Frequent не подходят для вашего приложения, то самое время создать собственную категорию. Для того, чтобы создать собственный список назначений, необходимо использовать интерфейс ICustomDestinationList.
Он предполагает использование метода, позволяющего приложению передавать панели задач собственное меню Jump List, включая разделы назначения и задачи. Вот методы, которые мы используем для примера:
· AppendCategory – определяет категорию и содержащиеся в ней назначения для внесения их в Jump List
· AppendKnownCategory – определяет, что категории Frequent или Recent должны быть включены в Jump List
· BeginList – инициирует начало сессии Jump List
· CommitList – объявляет, что Jump List инициирован вызовом BeginList и готов для вывода.
Вот фрагмент кода нового меню Jump List под названием Custom Lists, состоящего из четырех пунктов:
1: void CreateJumpList()
2: {
3: ICustomDestinationList *pcdl;
4: HRESULT hr = CoCreateInstance
5: (CLSID_DestinationList,
6: NULL, CLSCTX_INPROC_SERVER,
7: IID_PPV_ARGS(&pcdl));
8:
9: if (SUCCEEDED(hr))
10: {
11: hr = pcdl->SetAppID(c_szAppID);
12: if (SUCCEEDED(hr))
13: {
14: UINT uMaxSlots;
15: IObjectArray *poaRemoved;
16: hr = pcdl->BeginList
17: (&uMaxSlots, IID_PPV_ARGS(&poaRemoved));
18: if (SUCCEEDED(hr))
19: {
20: hr = _AddCategoryToList(pcdl, poaRemoved);
21: if (SUCCEEDED(hr))
22: {
23: pcdl->CommitList();
24: }
25: poaRemoved->Release();
26: }
27: }
28: }
29: }
// This is the helper function that actually
//appends the items to a collection object HRESULT
_AddCategoryToList(ICustomDestinationList *pcdl,
IObjectArray *poaRemoved)
{
IObjectCollection *poc;
HRESULT hr = CoCreateInstance
(CLSID_EnumerableObjectCollection,
NULL,
CLSCTX_INPROC_SERVER,
IID_PPV_ARGS(&poc));
if (SUCCEEDED(hr))
{
for (UINT i = 0; i < ARRAYSIZE(c_rgpszFiles); i++)
{
IShellItem *psi;
if (SUCCEEDED(SHCreateItemInKnownFolder(
FOLDERID_Documents,
KF_FLAG_DEFAULT,
c_rgpszFiles[i],
IID_PPV_ARGS(&psi))))
{
if(!_IsItemInArray(psi, poaRemoved))
{
poc->AddObject(psi);
}
psi->Release();
}
}
IObjectArray *poa;
hr = poc->QueryInterface(IID_PPV_ARGS(&poa));
if (SUCCEEDED(hr))
{
pcdl->AppendCategory(L"Custom category", poa);
poa->Release();
}
poc->Release();
}
return hr;
}
Начнем с вызова CoCreateInstance для инициации объекта ICustomDestinationList (вот она радость работы с COM…). Дальше мы указываем Application ID, чтобы мы могли заполнить список элементами. Application ID – строка, которая является уникальным идентификатором вашего приложения, поэтому убедитесь, что все остальные окна кластеризированы таким же образом, как и файлы в категории Recent. Application ID – это предмет отдельного разговора, поэтому в будущем мы вернемся к разговору о нем.
Использование функции BeginList инициировало начало сессии по созданию Jump List. Обратите внимание на параметр элемента Remove, IObjectArray *poaRemoved, который BeginList() возвращает как выходной параметр. Удаленные из списка элементы мы будем обрабатывать чуть позже.
Дальше мы вызываем вспомогательную функцию _AddCategoryToList(), которая сделает всю фактическую работу по добавлению элементов в категорию.
Еще один новый интерфейс, IObjectCollection, представляет собой коллекцию объектов, которая поддерживает IUnKnown, куда мы добавим IShellItems. Каждый добавленный элемент будет иметь тип IShellItem и мы создаем каждый элемент в папке документов. Однако, до того, как мы добавим новый элемент в коллекцию, нам необходимо проверить, удалил ли его уже пользователь. Если пользователь удалил элемент из Jump List, то он будет находиться в Removed Item List, который также ассоциирован с Application ID, и как разработчики мы должны уважать желание пользователя и избежать добавления данного элемента в Jump List. У нас уже есть список удаленных элементов – это IObjectArray *poaRemoved, который мы получили при вызове функции BeginList(…), когда инициировали процесс создания нового списка.
На данном этапе у нас есть коллекция IShellItems, которую пользователь ожидает увидеть в своем Jump List. Дальше мы добавим эту коллекцию в объект ICustomDestinationList и создадим категорию под названием Custom category, pcdl->AppendCategory (L"Custom category", poa);.
Мы успешно создали в панели задач новое меню Jump List и внесли туда четыре элемента. Однако, на этом работа не завершена. В заключении требуется вызвать функцию CommitList(), которая закончит транзакцию, начатую с вызова функции BeginList(). Только после вызовам CommitList(), новая категория и элементы будут отображаться. Вызов CommitList() инициирует очищение уже имеющегося списка удаленных элементов и создание нового. Вызов ICustomDestinationist является транзакционной базой для API. Чтобы обеспечить пользователю максимальное удобство работы, убедитесь в том, что безопасная копия вновь созданного списка завершена и готова к использованию. Единственная задача, которую остается выполнить панели задач – это перевести указатель на новый список.
Как видите, пользоваться панелью задач Windows 7 довольно просто и удобно. Большую часть работы Windows сделает за вас, а если требуется добавить собственную категорию, то это тоже не составит большого труда.
В панели задач Windows 7 есть масса новых функций, призванных сделать общение пользователя и Windows более приятным и удобным. Среди них следует отметить информативные многослойные иконки, индикатор прогресса копирования/перемещения, а также иконки миниатюр, о которых мы поговорим в будущих статьях.
Comments
Anonymous
January 24, 2009
PingBack from http://www.clickandsolve.com/?p=921Anonymous
May 24, 2010
Очень интересно, но есть вопрос: в какой-то момент пропало большинство пунктов Jump List для проводника, остались только Taslbar Tasks (изображение из презентации Роберта Джаретта). Есть ли какая-то возможность сбросить/восстановить настройку? Все остальные приложения работают без проблем.Anonymous
June 16, 2010
Та же проблема. Пропало большинство пунктов Jump List для Microsoft Word, остались только Taslbar Tasks. Как вернуть?Anonymous
July 29, 2010
Я такой способ нарыл: Идём в папку "%APPDATA%MicrosoftWindowsRecentAutomaticDestinations" и удаляем файл "1b4dd67f29cb1962.automaticDestinations-ms", После этого снова придётся заполнить Jump List у Проводника(любимыми папками), но главное, он будет работать! От меня: Да, папки теперь можно добавлять, но список недавно открытых не появился, пришлось удалить все эти файлы.