Программируем панель задач Windows 7: списки переходов (ч.3)
К этому моменту вы, как я надеюсь, поняли, как
Задачи пользователя (User tasks) - это настраиваемые задачи, помещаемые в свою собственную категорию Tasks. Как разработчик вы можете установить заголовок отображаемой задачи, иконку слева и, что более важно, приложение, которое запускается, когда данная задача активируется. Вы можете представить себе задачи пользователя как ярлыки на функции, доступные в вашем приложении. Как вы помните, задачи пользователя в нашем словаре представляют собой глаголы; например, в списке Windows Media Player есть задача "Resume last playlist", а в Sticky Notes - задача "New note".
Задача пользователя обычно представляет собой объект
Так что же требуется для добавления задач в список переходов? На самом деле, не так уж много. По существу, это один единственный вызов функции AddUserTasks в интерфейсе, с которым мы уже знакомы, в ICustomDestinationList (ICustomDestinationList::AddUserTasks(IObjectArray) Method). Рассматривая код, вы увидите одну единственную строку, hr = pcdl->AddUserTasks(poa);. Однако как всегда, кто-то должен создать этот poa, IObjectArray, параметр и заполнить его соответствующий информацией. Давайте рассмотрим этот процесс.
Мы создадим коллекцию IShellLinks. Эта коллекция будет позже приведена к требуемому параметру IObjectArray. Нижеприведенный код начинает этот процесс.
IObjectCollection *poc;
HRESULT hr = CoCreateInstance(
D_EnumerableObjectCollection, NULL, CLSCTX_INPROC, IID_PPV_ARGS(&poc));
if (SUCCEEDED(hr))
{
IShellLink * psl;
hr = _CreateShellLink(L"/Task1", L"Task 1", &psl);
if (SUCCEEDED(hr))
{
hr = poc->AddObject(psl);
psl->Release();
}
}
Здесь вы можете видеть, что мы использовали COM (вновь) и CoCreate и IObjectCollection, poc. Далее мы вызываем вспомогательную функцию CreateShellLink, которой присваиваются три параметра:
- Первый параметр - это аргумент командной строки для задачи
- Второй параметр - это заголовок, который будет отображен
- Третий параметр - это указатель на IShellLink
Затем объект заполняется соответствующей информацией.
Наконец, мы добавляем недавно созданный IShellLink в коллекцию объекта. Вы можете задаться вопросом, где же параметр, который указывает путь к исполняемому файлу, который мы планируем вызвать. Что же, это хороший вопрос. Для простоты, мы жестко задаем эту информацию, как показано в следующем фрагменте кода:
if (SUCCEEDED(hr))
{
hr = _CreateShellLink2(
L"C:Users<my user>Documents
ew text file.txt",
L"NotePad",
&psl);
if (SUCCEEDED(hr))
{
hr = poc->AddObject(psl);
psl->Release();
}
}
Здесь вы можете видеть, что мы вызывает жестко заданную функцию _CreateShellLink2. Ей присваиваем в качестве одного из параметров путь к текстовому файлу и запускаем Notepad (Блокнот).
Вот код для функции CreateShellLink2:
HRESULT _CreateShellLink2(
PCWSTR pszArguments, PCWSTR pszTitle,
IShellLink **ppsl)
{
IShellLink *psl;
HRESULT hr = CoCreateInstance(
CLSID_ShellLink,
NULL,
CLSCTX_INPROC_SERVER,
IID_PPV_ARGS(&psl));
if (SUCCEEDED(hr))
{
hr = psl->SetPath(c_szNotePadExecPath);
if (SUCCEEDED(hr))
{
hr = psl->SetArguments(pszArguments);
if (SUCCEEDED(hr))
{
// Свойство заголовка требуется элементам списка,
// представленным как экземпляр IShelLink. Это значение используется
// как отображаемое имя в списке переходов.
IPropertyStore *pps;
hr = psl->QueryInterface(IID_PPV_ARGS(&pps));
if (SUCCEEDED(hr))
{
PROPVARIANT propvar;
hr = InitPropVariantFromString(pszTitle, &propvar);
if (SUCCEEDED(hr))
{
hr = pps->SetValue(PKEY_Title, propvar);
if (SUCCEEDED(hr))
{
hr = pps->Commit();
if (SUCCEEDED(hr))
{
hr = psl->QueryInterface
(IID_PPV_ARGS(ppsl));
}
}
PropVariantClear(&propvar);
}
pps->Release();
}
}
}
else
{
hr = HRESULT_FROM_WIN32(GetLastError());
}
psl->Release();
}
return hr;
}
(GetLastError());
}
psl->Release();
}
return hr;
}[/code]
Сначала нам вновь следует использовать COM и CoCreate для создания COM-объекта IShellLink. Даже беглый просмотр SDK обнаруживает, что у объекта IShellLink есть множество функций. Вот несколько из них, которые мы будем использовать:
- GetPath Получает путь и имя файла объекта, которые являются путем к исполняемому файлу
- GetShowCmd Получает команду объекта Shell link, имя исполняемого файла
- SetArguments Устанавливает аргументы командной строки для объекта Shell link
- SetDescription Устанавливает описание для объекта Shell link; описание может быть любой определенной приложением строкой
- SetIconLocation Устанавливает размещение (путь и индекс) иконки объекта Shell link
- SetPath Устанавливает путь и имя файла для объекта Shell link
- SetWorkingDirectory Устанавливает имя рабочей папки для объекта Shell link
Как видите, для каждого параметра мы должны получить и установить соответствующие методы. Есть и дополнительные параметры; просмотрите раздел
В примере выше мы установили путь к Notepad (при установке Windows 7 по умолчанию, c:windows
otepad.exe). Мы также жестко задали (не самая лучшая привычка) аргумент командной строки, указывающий на текстовой файл в моей папке документов (C:Users<my user>Documents
ew text file.txt). Оставшаяся часть кода устанавливает свойство заголовка, требующееся для элементов списка.
Мы вызываем CreateShellLink2 и CreateShellLink еще несколько раз, чтобы добавить все три ярлыка, как показано на скриншоте выше.
Теперь давайте добавим разделитель.
Для добавления разделителя в наш TaskList, нам необходимо создать IShellLink и установить свойство PKEY_AppUserModel_IsDestListSeparator, используя свойство COM, как показано во фрагменте кода ниже:
[code]// Категория Tasks в списке переходов поддерживает разделительные элементы.
// Это простые экземпляры IShellLink, у которых
// Свойство PKEY_AppUserModel_IsDestListSeparator установлено на TRUE.
// Все другие значения игрорируются.
HRESULT _CreateSeparatorLink(IShellLink **ppsl)
{
IPropertyStore *pps;
HRESULT hr = CoCreateInstance(
CLSID_ShellLink,
NULL,
CLSCTX_INPROC_SERVER,
IID_PPV_ARGS(&pps));
if (SUCCEEDED(hr))
{
PROPVARIANT propvar;
hr = InitPropVariantFromBoolean(TRUE, &propvar);
if (SUCCEEDED(hr))
{
hr = pps->SetValue(PKEY_AppUserModel_IsDestListSeparator, propvar);
if (SUCCEEDED(hr))
{
hr = pps->Commit();
if (SUCCEEDED(hr))
{
hr = pps->QueryInterface(IID_PPV_ARGS(ppsl));
}
}
PropVariantClear(&propvar);
}
pps->Release();
}
return hr;
}[/code]
Здесь вы можете видеть, что мы использовали CoCreate для создания объекта IShellLink. Далее мы установили PROPVARIANT, propvar на TRUE и установили свойство PKEY_AppUserModel_IsDestListSeparator объекта IShellLink на TRUE. Это прикажет ОС показать ISHellLink как разделитель, а не как обычный IShellLink.
Что ж, это было не так уж сложно. Тем не менее, давайте взглянем на укороченную версию, используя .NET. Для этого мы воспользуемся
Как и следует ожидать от .NET, мы получаем абстракцию большей части требуемого COM-кода. Пространство имен Microsoft.WindowsAPICodePack.Shell.Taskbar включает объект JumpListLink, который расширяет объект ShellLink и встраивает IJumpListTasks.
Класс JumpList содержит UserTasks-коллекцию IJumpListTasks, к которой вы можете просто добавить новые объекты JumpListLink, как показано в следующем фрагменте кода:
[code]// Путь к системному каталогу Windows
string systemFolder =
Environment.GetFolderPath(Environment.SpecialFolder.System);
jumpList.UserTasks.Add(new JumpListLink
{
Title = "Open Notepad",
Path = Path.Combine(systemFolder, "notepad.exe"),
IconReference = new IconReference(
(systemFolder, "notepad.exe"), 0)
});[/code]
Используя синтаксис C# 3.0, мы инициализируем новый объект JumpListLink и добавляем его в коллекцию UserTasks. Как вы видите, управляемый код JumpListLink имеет очень схожие с неуправляемым свойства (что очень разумно). Мы также добавили иконку к ярлыку Блокнота в коде выше, но не указали никаких параметров командной строки.
Вы хотите добавить разделитель? Что же, это также очень просто: просто добавьте объект JumpListSeparator к коллекции UserTasks.
[code]jumpList.UserTasks.Add(new JumpListSeparator());[/code]
Заметьте, пожалуйста, что, как всегда, работая с Windows Code pack API Taskbar, вы должны вызвать функцию "refresh", чтобы подтвердить изменения, как мы объяснили это в предыдущей статье.
[code]Taskbar.JumpList.RefreshTaskbarList();[/code]
После обновления список выглядит следующим образом:
Я скомпилировал пример в неуправляемом коде из Windows 7 SDK. Вы можете получить копию этого кода
Это завершает наш разговор о списках перехода. Наша следующая статья о панели задач будет посвящена Icon Overlay.
Источник:
Перевод: Sibiryak
По теме
- Федеративный поиск в Windows 7
- Программируем панель задач Windows 7: панель миниатюр
- Использование сенсоров в приложении: реализация в managed-коде (ч.1)
- Использование сенсоров в приложении: реализация в native-коде (ч.1)
- Я тебя чувствую: использование платформы Sensor в Windows 7
- Доступны записи с Windows 7 PDC Boot Camp
- Fishbowl для Facebook с использованием новой панели задач Windows 7
- Программируем для Windows 7 в Visual Studio 2010
- Новая версия Windows API Code Pack
- Программирование служб Windows 7 с триггерами (ч.2)