Windows 7: списки переходов

Опубликовано 09 декабря 2009 16:59 | Coding4Fun |

В этой статье показывается, как обеспечить быстрый доступ к ссылкам и действиям в приложении для Windows 7, создав список переходов (jump list).

Автор: Ариан Т. Кулп (Arian T. Kulp)
Сложность: средняя
Необходимое время: 3 часа
Затраты: бесплатно!
ПО: Visual Basic или Visual C# Express (или более полная версия), Windows API Code Pack
Исходный код: Загрузить

Введение

В Windows 7 появилось очень много новшеств для разработчиков. К ним относятся более совершенная подсистема визуализации, новые API датчиков и определения местонахождения, библиотеки файлов, федеративный поиск и, конечно же, улучшенная панель задач. В прошлой статье я обсуждал возможность показывать на панели задач собственные образцы окон (previews) и значки панели инструментов. Эта статья посвящена спискам переходов — они заменяют контекстные меню в области уведомлений.

Для начала загрузите Visual Studio 2008 Express Edition или более полную версию (C# или VB). Либо просто возьмите Visual Studio 2010 Beta 2 — она уже доступна и стоит того, чтобы ее загрузить. Все Express-издания бесплатны, и любая из версий (2008 или 2010) будет прекрасно работать с кодом, сопутствующим этой статье.

Чтотакоесписокпереходов ?

Списки переходов — новая концепция в Windows 7, позволяющая разработчику создавать ярлыки (shortcuts) для пользователей прямо в контекстном меню значка своей программы на панели задач или в меню Пуск (Start).  Эти ярлыки могут быть простыми ссылками на папку документов или библиотеку данного приложения, либо ссылками на командную строку запуска того же приложения с передачей какого-либо параметра для выполнения какой-то специфической задачи.

Вы можете использовать этот способ в Live Messenger для изменения онлайнового состояния, вывода нового окна сообщения или для открытия веб-страниц, относящихся к приложению. В общем, все это ярлыки — к URL или тому же исполняемому файлу с аргументом, вызывающим некое изменение.

Windows API Code Pack

Windows API Code Pack дает возможность задействовать преимущества специфических средств Windows Vista и Windows 7, недоступных через универсальную инфраструктуру, а также неуправляемых функций, которые не имеют смысла в общеязыковой исполняющей среде (CLR), используемой во всех поддерживаемых конфигурациях. Большая часть таких средств состоит из interop-оболочек (позволяющих взаимодействовать с неуправляемыми функциями из управляемого кода).

С помощью Code Pack вы получаете доступ к новой панели задач, Direct2D, DirectWrite, свойствам оболочки, спискам переходов и др. В комплект также включены многочисленные проекты с примерами кода, которые послужат вам отправной точкой, так что избегать новых возможностей нет никаких причин!

Добавление списка переходов

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

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

Вот как все это делается.

Сначала добавьте две обязательные ссылки из Windows API Code Pack. Вы можете либо скомпилировать проект и ссылаться на DLL, либо напрямую включить необходимые проекты в свое решение:

clip_image002[4]

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

Visual Basic

 Imports Microsoft.WindowsAPICodePack.Taskbar

Imports Microsoft.WindowsAPICodePack.Shell

Visual C#

 using Microsoft.WindowsAPICodePack.Taskbar;

using Microsoft.WindowsAPICodePack.Shell;

Класс Microsoft . WindowsAPICodePack . Taskbar . JumpList— то место, где разворачивается большая часть действа. Для создания списка предназначен статический метод-фабрика CreateJumpList. Всегда начинайте с вызова этого метода, даже если приложение ранее создавало список переходов.

Visual Basic

 Private Sub CreateJumpList()

Dim jl As JumpList = JumpList.CreateJumpList()

Visual C#

 private void CreateJumpList()

{

JumpList jl = JumpList.CreateJumpList();

Далее у вас есть выбор из нескольких вариантов — в зависимости от того, что именно вы хотите увидеть в списке. Базовой группой является список файлов. Вы можете выбрать отображение Recent files (последние файлы), Frequent files (часто используемые файлы) или ни один из них, но не оба варианта одновременно. Если вы ничего не выбираете на этом этапе, то автоматически получите вариант Recent files — при условии, что у вас есть зарегистрированный тип файлов.

Visual Basic

 ' Показываем пользовательские файлы: Recent, Frequent или None

jl.KnownCategoryToDisplay = JumpListKnownCategoryType.Recent

Visual C#

 // Показываем пользовательские файлы: Recent, Frequent или None 
jl.KnownCategoryToDisplay = JumpListKnownCategoryType.Recent; 

Теперь вы можете добавить одну или более собственных категорий элементов. Это могут быть либо папки, либо файлы. Здесь действуют два очень важных правила.

1. Файлы/папки должны существовать! При необходимости проверьте путь перед добавлением JumpListItem; если его нет, произойдет сбой.

2. Добавляемые файлы должны относиться к типу, зарегистрированному для вашего приложения; в ином случае произойдет сбой или даже хуже: исключение будет сгенерировано не в той строке, где вы добавляете такие файлы, а по окончании настройки и попытке обновления списка.

В данном случае я закомментировал последний элемент, но вы могли бы использовать JumpListItemдля реальных файлов в файловой системе и объекты JumpListLinkдля ссылок, не относящихся к файловой системе. И вновь не добавляйте JumpListItem, если не уверены в его наличии и в том, что он зарегистрирован.

Visual Basic

 ' Добавляю свои ссылки (существительные)

Dim catActions As New JumpListCustomCategory("Destinations")

catActions.AddJumpListItems(

New JumpListLink(Environment.GetFolderPath(Environment.SpecialFolder.MyPictures), "My Pictures"), _

New JumpListLink("https://blogs.msdn.com/coding4fun", "Visit Coding4Fun"), _

New JumpListLink("https://code.msdn.microsoft.com/WindowsAPICodePack", "Windows API Code Pack"))

'new JumpListItem(@"c:\Test1.c4f")

jl.AddCustomCategories(catActions)

Visual C#

 // Добавляю свои ссылки (существительные)

JumpListCustomCategory catActions = new JumpListCustomCategory("Destinations");

catActions.AddJumpListItems(

new JumpListLink(Environment.GetFolderPath(Environment.SpecialFolder.MyPictures), "My Pictures"),

new JumpListLink("https://blogs.msdn.com/coding4fun", "Visit Coding4Fun"),

new JumpListLink("https://code.msdn.microsoft.com/WindowsAPICodePack", "Windows API Code Pack")

//new JumpListItem(@"c:\Test1.c4f")

);

jl.AddCustomCategories( catActions);

Вы можете добавить одну или более задач как ссылки на исполняемые файлы, используя метод AddUserTasksобъекта JumpList. При этом либо создавайте несколько объектов и добавляйте их как переменный список аргументов, либо добавляйте их по одному единовременно, как это сделал я.

Visual Basic

 ' Добавляем задачи наших пользователей (глаголы)

jl.AddUserTasks(New JumpListLink(Path.Combine(systemFolder, "notepad.exe"), "Open Notepad") _

With {.IconReference = New IconReference(Path.Combine(systemFolder, "notepad.exe"), 0)})

Visual C#

 ' Добавляем задачи наших пользователей (глаголы)

jl.AddUserTasks(new JumpListLink(Path.Combine(systemFolder, "notepad.exe"), "Open Notepad")

{

IconReference = new IconReference(Path.Combine(systemFolder, "notepad.exe"), 0)

});

Свойство IconReference указывает на значок, ссылаясь на DLL- или EXE-файл и задавая индекс в этом файле. Если вы хотите получить значок по умолчанию для исполняемого файла, с которым вы осуществляете связывание, указывайте EXE-файл с нулевым индексом.

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

Visual Basic

 jl.AddUserTasks(New JumpListSeparator())

Visual C#

 jl.AddUserTasks(new JumpListSeparator());

Последние ссылки в списке переходов указывают на наш же исполняемый файл. Это наиболее распространенный вариант использования списков перехода. Простой список с последними или часто используемыми файлами, конечно же, — штука хорошая, но возможность инициировать некие операции в самой программе, даже если она не запущена, по-настоящему удобна. Это почти что меню параметров командной строки запуска приложения!

Команды в списке, запускающие операции в самом приложении, требуют вызова этого приложения с разными аргументами. Помните, что это не настоящее меню — вы не получите событие Click. Вместо этого нужно обрабатывать аргумент, переданный вашей программе, даже если она уже выполняется.

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

Visual Basic

 jl.AddUserTasks(New JumpListLink(Assembly.GetEntryAssembly().Location, "Action 1 (Green)") _

With {.Arguments = "-1", .IconReference = New IconReference(Assembly.GetEntryAssembly().Location, 0)})

Visual C#

 jl.AddUserTasks(new JumpListLink(Assembly.GetEntryAssembly().Location, "Action 1 (Green)")

{

IconReference = new IconReference(Assembly.GetEntryAssembly().Location, 0),

Arguments = "-1"

});

clip_image004[4]

Запуск операций

Windows Live Messenger использует операции списка переходов для настройки своего состояния, а Windows Media Player — для пропуска треков или остановки воспроизведения. Аналогичным образом вы можете добавлять задачи, которые запускают операции в вашем приложении. Если приложение еще не запущено (помните, что при этом список переходов все равно доступен), это приведет к его запуску с соответствующим аргументом. Это не проблема. А вот как быть, если приложение уже выполняется?

Ключ к решению в том, чтобы найти способ передачи сообщений между выполняемыми экземплярами. При запуске приложения проверяйте, не выполняется ли уже другой его экземпляр, и используйте для этого Mutex(см. Program . cs). Если других экземпляров нет, просто используйте аргументы традиционным способом. А если есть, передайте информацию о параметре другому экземпляру и завершите приложение. С этой целью вы могли бы использовать временные файлы, общие разделы реестра или проецируемые в память файлы (memory-mapped files). На мой взгляд, проще всего использовать оконные сообщения.

Код для создания сообщений с собственными идентификаторами, поиска нужного окна и отправки сообщения вы найдете в моем классе WindowsMessageHelper.

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

Если приложение уже выполняется, отправляйте сообщение асинхронно (post a message). Если нет, запускайте программу как обычно и проверяйте ее очередь сообщений. Обнаружив соответствующее сообщение, выполняйте нужную операцию (в данном случае просто показывайте сообщение и меняйте цвет метки).

Еще один трюк заключается в том, что, если ваше приложение запускается только в одном экземпляре, вы все равно можете использовать параметр, — например, если пользователь щелкнул какую-то задачу в списке переходов, но приложение еще не выполняется. Я предпочитаю простой путь и проверяю параметры по окончании запуска, а затем при необходимости асинхронно отправляю их в собственную очередь! Во всяком случае, это упрощает часть логики.

Если вы не против применения пространства имен Microsoft . VisualBasic . ApplicationServices из кода на C#, то можете задействовать преимущества режима работы приложения SingleInstance из VB. Это избавит вас от явного использования мьютекса, механизма взаимодействия (interop) или передачи сообщений. Некоторую очень полезную информацию на этот счет вы найдете в отличной статье Джослин Виллараза (Jocelyn Villaraza) в его блоге (EN).

Регистрациятипафайлов

Помните: пока ваша программа не зарегистрирована как обработчик файлов данного типа, вы не можете показывать последние или часто используемые файлы или указывать на индивидуальные файлы. Для регистрации программы в качестве обработчика файлов создайте запись в раздел реестра HKEY_CLASSES.

Проблема в том, что без должных разрешений записывать что-либо в ветвь реестра HKEY_CLASSES нельзя. По умолчанию нужное разрешение выдается только группе Administrators (Администраторы). Вряд ли вы захотите, чтобы ваше приложение работало с полномочиями администратора, — это был бы возврат к стилю Windows XP!

Здесь два варианта: вы могли бы создать второе приложение, которое могло бы запускаться с повышенными полномочиями для выполнения регистрации. Именно так сделано в примерах, поставляемых с Windows API Code Pack. Способ получше заключается в том, что вы создаете собственный установщик для проекта и выполняете необходимые сопоставления типов файлов в процессе его работы. Установщик всегда требует прав администратора, но запускается лишь однажды.

Создание установщика

Чтобы создать установщик, сначала добавьте его проект в свое решение как обычно. Затем из списка Project types выберите Other Project Types | Setup and Deployment. В списке Templates щелкните Setup Project. Присвойте ему имя и добавьте в решение.

clip_image006[4]

В SolutionExplorer щелкните проект установщика правой кнопкой мыши и выберите из контекстного меню команду View | FileTypes.

clip_image008[4]

В списке File Types щелкните правой кнопкой мыши File Types on Target Machine, а затем выберите Add File Type. Заполните свойства, чтобы присвоить имя типу файлов и указать расширение. В свойстве Command выберите значение «Primary output from имя_основного_проекта».

clip_image010[6]

На вкладке FileTypes ваш тип файлов должен появиться в следующем виде:

clip_image012[5]

Теперь у вас есть зарегистрированный тип файлов. Вам все равно надо модифицировать проект установщика, чтобы копировать основной вывод (устанавливаемый EXE-файл) в папку Program Files, и настроить любые другие свойства в проекте установщика, но эти операции зависят от конкретного типа файлов. Если вы в чем-то не уверены, взгляните на образец кода, чтобы увидеть, как настраивается проект установщика.

Заключение

Windows API Code Pack значительно упрощает настройку панели задач и добавление списков переходов, а также расширяет возможности интеграции ваших программ в систему. Загрузите Visual Studio Express, скачайте Windows API Code Pack и приступайте к его изучению.

Новые средства не будут работать на компьютерах под управлением более ранних версий Windows (до Windows 7), поэтому обязательно проверяйте версию операционной системы.