Скачиваний:
100
Добавлен:
01.05.2014
Размер:
1.56 Mб
Скачать

Применение com-объектов, входящих в состав Windows Создание ярлыков

Как известно, ссылки для запуска приложений сохраняются в соответствующих директориях в виде ярлыков (Shortcuts) - файлов с расширением *.lnk. Это двоичные файлы, имеющие достаточно сложную структуру. Для их создания в Windows 3.x использовался динамический обмен данными - DDE (Dynamic Data Exchange) с приложением Program Manager, которое всегда запущено при работе Windows 3.1/З.11. Для создания такого файла в Windows 95 можно также использовать динамический обмен данными с Program Manager, но для этого его нужно обязательно предварительно запустить (например, набрав Progman после команды Run главного меню); в противном случае команды DDE не станут выполняться. Кроме того, компанией Microsoft было объявлено о недопустимости использования DDE при создании новых приложений; поддержка динамического обмена данными сохраняется только с целью обеспечения работоспособности ранее созданных приложений.

Конечно, можно создать ярлык непосредственно с помощью записи двоичных данных, однако для этой цели необходимо знать формат такого файла. Вместо этого можно воспользоваться тем, что программный интерфейс Microsoft Shell API полностью базируется на СОМ-технологии.

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

#include <shlobj.h>

#include <string.h>

HRESULT CreateLink (LPCSTR lpszPathObj, LPCSTR lpszPathLink,

LPCSTR lpszDesc)

{

HRESULT hres;

IShellLink *psl;

// Получить указатель на интерфейс IShellLink

hres = CoCreateInstance (CLSID_ShellLink, NULL,

CLSCTX_INPROC_SERVER,

IID_IShellLink, (LPVOID *) &psl);

if (SUCCEEDED (hres))

{

IPersistFile *ppf;

// Установить путь к ярлыку и добавить описание

psl->SetPath (lpszPathObj);

psl->SetDescription (lpszDesc);

// Преобразовать IShellLink в IPersistFile для сохранения ярлыка

hres = psl->QueryInterface (IID_IPersistFile, (LPVOID *) &ppf);

if (SUCCEEDED (hres))

{

WCHAR wsz[MAX_PATH];

// Преобразовать строку в Unicode

MultiByteToWideChar (CP_ACP, 0, lpszPathLink, -1, wsz, MAX_PATH);

// Сохранить ярлык вызовом IPersistFile::Save.

hres = ppf->Save (wsz, TRUE);

ppf->Release ();

}

psl->Release ();

}

return hres;

}

int main (int argc, char *argv[])

{

LPITEMIDLIST P;

char szLink[512] = "";

// Инициализация библиотеки COM

CoInitialize (NULL);

// Получить путь к Рабочему столу

if (SHGetSpecialFolderLocation (NULL, CSIDL_DESKTOP, &P) == NOERROR)

{

// Преобразовать путь к строке

SHGetPathFromIDList (P, szLink);

strcat (szLink, "\\Program.lnk");

// Создать ярлык

CreateLink (argv[0], szLink, "Link");

}

// Закрытие библиотеки COM

CoUninitialize ();

return 0;

}

При выполнении этого кода сначала инициализируется библиотека СОМ и определяется путь к Рабочему столу. Создается COM-объект, который поддерживает несколько стандартных СОМ-интерфейсов, в частности IShellLinkиIPersistFile. В интерфейсеIShellLinkследует определить ряд параметров - путь и имя исполняемого файла, а также описание. Можно также определить некоторые необязательные параметры, например выбрать другую пиктограмму для ярлыка или указать, в каком состоянии должно быть при запуске главное окно приложения - в минимизированном, максимизированном или нормальном.

Интерфейс IPersistFileслужит для запоминания или считывания файла *.lnk. В качестве параметра он использует один из стандартных каталогов Windows - Desktop, Program Files и др.

Обратите внимание на то, что никогда не следует указывать имена этих каталогов в явном виде - в различных языковых версиях Windows они могут быть различными! Например, каталогу Main Menu/Program Files английской версии Windows соответствует каталог "Главное меню/Программы" в соответствующей русской версии Windows. Следует также помнить, что имена, присваиваемые по умолчанию при установке Windows всем специальным каталогам, могут быть впоследствии изменены.

По этой причине необходимо использовать метод SHGetSpecialFolderLocation и вслед за ним SHGetPathFromIDList для получения физического адреса специальных каталогов. Эти методы вместе со списком констант, определяющих тип специальных каталогов, приведены в файле shlobj.h.