API обеспечивает COM-интерфейс по имени IShellLink, который позволяет Вам создать ярлык. Чтобы создать ярлык на рабочем столе, обратимся к объекту IShellLink, заполним его атрибуты, и сохраним ярлык.
Пример кода ниже демонстрирует, как сделать ярлык. В этом примере, ярлык будет сохранен в корне диска C
//---------------------------------------------------------------------- #define NO_WIN32_LEAN_AND_MEAN
#include <shlobj.h> void __fastcall TForm1::Button1Click(TObject *Sender) { // Позволим пользователю выбрать файл в диалоговом окне
// выбора файлов и затем создадим ярлык на этот файл. if(OpenDialog1->Execute()) CreateShortCut(OpenDialog1->FileName); } //---------------------------------------------------------------------- void TForm1::CreateShortCut(const AnsiString &file) { // IShellLink позволит нам создать ярлык. // IPersistFile сохранит ярлык на жесткий диск С. IShellLink* pLink; IPersistFile* pPersistFile; // Первым делом инициализируем COM библиотеку
if(SUCCEEDED(CoInitialize(NULL))) { // Если инициализация прошла успешно, то получим // объект IShellLink вызвав CoCreateInstance. if(SUCCEEDED(CoCreateInstance(CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, IID_IShellLink, (void **) &pLink))) { // если все прошло успешно — заполним атрибуты ярлыка pLink->SetPath(file.c_str()); pLink->SetDescription("Woo hoo, look at Homer's shortcut"); pLink->SetShowCmd(SW_SHOW); // Теперь необходимо сохранить ярлык диске. Объект // IShellLink также содержит интерфейс IPersistFile. // Получим интерфейс IPersistFile вызвав QueryInterface. if(SUCCEEDED(pLink->QueryInterface(IID_IPersistFile, (void **)&pPersistFile))) { // Если все успешно, вызовем метод Save // объекта IPersistFile для сохранения/записи ярлыка. WideString strShortCutLocation("C:\\bcbshortcut.lnk"); pPersistFile->Save(strShortCutLocation.c_bstr(), TRUE); pPersistFile->Release(); } pLink->Release(); } // После вызова CoInitialize необходимо вызвать CoUninitialize CoUninitialize(); } } //----------------------------------------------------------------------
Если Вы выполните этот код, Вы увидете новый ярлык файла в корне вашего диска
C:\. Это конечно круто, но цель этой страницы состоит в том, чтобы создать ярлык
на рабочем столе. Вышеприведенный пример кода не сохраняет ярлык в нужном месте.
(рабочем столе)
Чтобы сделать ярлык на рабочем столе вместо корня диска, мы просто должны изменить
место, где мы сохраняем ярлык (LNK файл). Мы можем заимствовать код из темы
"Определение
пути к Windows Desktop и другим специальным каталогам", чтобы найти
путь к Windows каталогом Desktop. Как только мы узнаем, где каталог рабочего
стола, мы можем сохранить наш ярлык в этом каталоге. После выполнения этого,
Windows отобразит ярлык на рабочем столе. Код ниже показывает новую версию CreateShortCut,
который сохраняет ярлык на рабочем столе.
//---------------------------------------------------------------------- void TForm1::CreateShortCut(const AnsiString &file) { IShellLink* pLink; IPersistFile* pPersistFile; LPMALLOC ShellMalloc; LPITEMIDLIST DesktopPidl; char DesktopDir[MAX_PATH]; // Мы собираемся получить pidl и нам нам нужен shell mallocator. // Получим shell mallocator используя API-функцию SHGetMalloc. if(FAILED(SHGetMalloc(&ShellMalloc))) return; // используем API для получения pidl для папки рабочема стола // если ошибка выполнения функции — выходим if(FAILED(SHGetSpecialFolderLocation(NULL, CSIDL_DESKTOPDIRECTORY, &DesktopPidl))) return; // Теперь переведем pidl в строку символов // выходим если произошла ошибка выполнения функции if(!SHGetPathFromIDList(DesktopPidl, DesktopDir)) { ShellMalloc->Free(DesktopPidl); ShellMalloc->Release(); return; } // Освободим все что занятые ресурсы pidl ShellMalloc->Free(DesktopPidl); ShellMalloc->Release(); if(SUCCEEDED(CoInitialize(NULL))) { if(SUCCEEDED(CoCreateInstance(CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, IID_IShellLink, (void **) &pLink))) { pLink->SetPath(file.c_str()); pLink->SetDescription("Woo hoo, look at Homer's shortcut"); pLink->SetShowCmd(SW_SHOW); if(SUCCEEDED(pLink->QueryInterface(IID_IPersistFile, (void **)&pPersistFile))) { WideString strShortCutLocation(DesktopDir); strShortCutLocation += "\\bcbshortcut.lnk"; pPersistFile->Save(strShortCutLocation.c_bstr(), TRUE); pPersistFile->Release(); } pLink->Release(); } CoUninitialize(); } } //----------------------------------------------------------------------
Создание ярлыков требует от нас использования COM. Важно не позволить себе пугаться сложностей COM. COM — только другой способ создавать и использовать объекты. Может быть полезно думать о коде COM в терминах эквивалентного кода в C++. Притворитесь, что объекты ISHELLLINK И IPERSISTFILE не отличаются от других объектов, которые Вы создаете операторами new и delete. Также может помочь игнорировать код обработки ошибок так, чтобы Вы могли видеть то, что действительно получается..
COM code C++ psuedo-equivalent IShellLink* pLink; TShellLink *Link; IPersistFile* pPersistFile; TPersistFile *PersistFile; CoInitialize(); // CoCreateInstance is like new CoCreateInstance(CLSID_ShellLink, Link = new TShellLink; NULL, CLSCTX_INPROC_SERVER, IID_IShellLink, (void **) &pLink) // These are like member functions pLink->SetPath(file.c_str()); Link->SetPath(file.c_str()); pLink->SetShowCmd(SW_SHOW); Link->SetShowCmd(SW_SHOW); // QueryInterface is like casting pLink->QueryInterface(IID_IPersistFile PersistFile = (void **)&pPersistFile))) dynamic_cast<TPersistFile*>(Link); pPersistFile->Save("C:\\", TRUE); PersistFile->Save("C:\\"); // Release is like delete pPersistFile->Release(); delete PersistFile pLink->Release(); delete Link; CoUninitialize();
Для получения дополнительной информации по IShellLink
см API-help.
(дурацкий совет дать нетрудно)