Рассылка закрыта
При закрытии подписчики были переданы в рассылку "Создание сайта. Уроки для начинающих и не только" на которую и рекомендуем вам подписаться.
Вы можете найти рассылки сходной тематики в Каталоге рассылок.
Программирование от Чертенка.ру Выпуск 2. Создание ярлыков на рабочем столе
Информационный Канал Subscribe.Ru |
Доброго времени суток, уважаемые подписчики!
За прошедшую неделю в мире soft IT произошли следующие интересные новости:
В сегодняшнем выпуске мы раскажем о том, как программно в Delphi создавать ярлыки на Рабочем столе (да и не только на нем).
Ярлыки Windows
В оболочке Windows предусмотрен ряд интерфейсов, которые можно использовать
для управления различными ее свойствами. Эти интерфейсы определены в модуле
ShlObj
. Подробного обсуждения всех объектов такого модуля хватило бы на целую книгу,
но в статье остановимся лишь на одном из самых полезных (и чаще всего используемых) - интерфейсе IShellLink
.
Интерфейс IShellLink
позволяет создавать в приложениях ярлыки Windows и
управлять ими. При работе на компьютере с такими объектами приходится встречаться
постоянно: большинство пиктограмм на рабочем столе - это именно ярлыки. Кроме того, такие пункты меню, как Send To
(Отправить) или Documents
(Документы), - это тоже ярлыки. Интерфейс IShellLink
определен следующим образом:
type
IShellLink = interface(IUnknown)
['{000214EE-0000-0000-C000-000000000046}']
function GetPath(pszFile: PAnsiChar; cchMaxPath: Integer; var pfd: TWin32FindData; fFlags: DWORD): HResult; stdcall;
function GetIDList(var ppidl: PItemIDList): HResult; stdcall;
function SetIDList(pidl: PItemIDList): HResult; stdcall;
function GetDescription(pszName: PAnsiChar; cchMaxName: Integer): HResult; stdcall;
function SetDescription(pszName: PAnsiChar): HResult; stdcall;
function GetWorkingDirectory(pszDir: PAnsiChar; cchMaxPath: Integer): HResult; stdcall;
function SetWorkingDirectory(pszDir: PAnsiChar): HResult;stdcall;
function GetArguments(pszArgs: PAnsiChar; cchMaxPath: Integer): HResult; stdcall;
function SetArguments(pszArgs: PAnsiChar): HResult; stdcall;
function GetHotkey(var pwHotkey: Word): HResult; stdcall;
function SetHotkey(wHotkey: Word): HResult; stdcall;
function GetShowCmd(out piShowCmd: Integer): HResult; stdcall;
function SetShowCmd(iShowCmd: Integer): HResult; stdcall;
function GetIconLocation(pszIconPath: PAnsiChar; cchIconPath: Integer; out piIcon: Integer): HResult; stdcall;
function SetIconLocation(pszIconPath: PAnsiChar; iIcon: Integer): HResult; stdcall;
function SetRelativePath(pszPathRel: PAnsiChar; dwReserved: DWORD): HResult; stdcall;
function Resolve(Wnd: HWND; fFlags: DWORD): HResult; stdcall;
function SetPath(pszFile: PAnsiChar): HResult; stdcall;
end;
Создание экземпляра интерфейса IShellLink
При работе с интерфейсом IShellLink
не нужно реализовывать интерфейс - он
уже реализован в самой оболочке Windows
, и остается лишь создать его экземпляр.
Для этого служит функция API COM CoCreateInstance()
. Предлагаем рассмотреть
пример создания подобного экземпляра.
var
SL: IShellLink;
begin
OleCheck(CoCreateInstance(CLSID_ShellLink, nil, CLSCTX_INPROC_SERVER, IShellLink, SL));
// Здесь используется экземпляр интерфейса SL
end;
Не забудьте, что, прежде чем использовать какую-либо из функций OLE, необходимо с
помощью функции API CoInitialize()
инициализировать библиотеку COM. По окончании работы для освобождения ресурсов следует вызвать функцию API CoUninitialize()
.
Если приложение использует модуль ComObj и содержит вызов функции
Application.Initialize()
, то упомянутые функции будут вызваны автоматически.
В противном случае их придется вызывать самостоятельно.
Использование интерфейса IShellLink
Иногда кажется, что ярлыки Windows обладают просто магическими возможностями: щелкнув правой кнопкой мыши на поверхности рабочего стола можно выбирать в контекстном меню пункт создания нового ярлыка, и после этого происходит нечто, сопровождающееся появлением пиктограммы на поверхности рабочего
стола. Но стоит узнать, что именно происходит в действительности — и от загадочности не остается и следа. Ярлык (shell link) на самом деле представляет собой файл
с расширением .lnk, расположенный в определенной папке (shell folder). При запуске Windows в известных папках выполняется поиск файлов .lnk. К числу этих
специальных папок (папок системной оболочки или системных папок) относятся
такие, как Network Neighborhood, Send To, Startup, Desktop
и т.д. Windows
хранит отношения “ярлык–папка” в системном реестре, главным образом в следующей ветви:
HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders
Для того чтобы создать в некоторой папке ярлык, достаточно просто поместить в эту папку файл .lnk. Чтобы узнать пути к системным папкам можно, конечно, обратиться к системному реестру, однако гораздо эффективнее использовать функцию API Win32 SHGetSpecialFolderPath(), которая определена следующим образом:
function SHGetSpecialFolderPath(hwndOwner: HWND; lpszPath: PChar;
nFolder: Integer; fCreate: BOOL): BOOL; stdcall;
Параметр hwndOwner
содержит дескриптор окна, которое будет владельцем всех
диалоговых окон, вызываемых этой функцией.
Параметр lpszPath
является указателем на буфер, куда будет передан возвращаемый путь. Размер данного буфера должен быть не меньше значения MAX_PATH
.
В параметре nFolder
указано имя специальной папки, путь к которой необходимо
получить. В табл. приведены возможные значения этого параметра.
С помощью параметра fCreate
определяется, будет ли создана папка в случае, если таковая отсутствует.
Возможные значения параметра nFolder
Флаг | Описание |
---|---|
CSIDL_ALTSTARTUP | Папка, соответствующая нелокализованной группе Startup (Автозагрузка) конкретного пользователя |
CSIDL_APPDATA | Папка, выделенная как общее место хранения данных приложений |
CSIDL_BITBUCKET | Папка, содержащая файловые объекты корзины пользователя (Recycle Bin). Расположение этой папки не зафиксировано в системном реестре; чтобы не допустить ее перемещения или удаления, она помечена атрибутами “скрытый” и “системный” |
CSIDL_COMMON_ALTSTARTUP | Папка, соответствующая нелокализованной группе
Startup всех пользователей |
CSIDL_COMMON_DESKTOPDIRECTORY | Папка, содержащая файлы и папки, которые отображаются на рабочем столе для всех пользователей Desktop (Рабочий стол) |
CSIDL_COMMON_FAVORITES | Папка Favorite (Избранное) для всех пользователей |
CSIDL_COMMON_PROGRAMS | Папка, содержащая программы из папки Start (Пуск) для всех пользователей (Programs (Программы)) |
CSIDL_COMMON_STARTMENU | Папка, содержащая папки групп программ из меню Start (для всех пользователей) |
CSIDL_COMMON_STARTUP | Папка, содержащая программы и папки, отображаемые в меню Start (для всех пользователей) |
CSIDL_CONTROLS | Виртуальная папка, содержащая индикаторы приложений панели управления |
CSIDL_COOKIES | Папка для хранения файлов Internet типа cookies |
CSIDL_DESKTOP | Виртуальная папка рабочего стола (Windows Desktop) для хранения корневого пространства имен |
CSIDL_DESKTOPDIRECTORY | Папка, где физически расположены файловые объекты рабочего стола (не путать с папкой Desktop!) |
CSIDL_DRIVES | Папка My Computer (Мой компьютер), содержащая все объекты на локальном компьютере: дисковые устройства, принтеры и панель управления. Эта папка может также содержать подключенные сетевые устройства |
CSIDL_FAVORITES | Папка, в которой хранится “Избранное” конкретного пользователя |
CSIDL_FONTS | Виртуальная папка, содержащая шрифты |
CSIDL_HISTORY | Папка, где хранятся ссылки на адреса Internet, посещенные пользователем |
CSIDL_INTERNET | Виртуальная папка, представляющая Internet |
CSIDL_INTERNET_CACHE | Папка общего хранилища временных файлов Internet |
CSIDL_NETHOOD | Папка, содержащая объекты сетевого окружения (Network Neighborhood) |
CSIDL_NETWORK | Виртуальная папка Network Neighborhood, представляющая собой высший уровень сетевой иерархии |
CSIDL_PERSONAL | Папка, используемая как общее хранилище для документов |
CSIDL_PRINTERS | Виртуальная папка, содержащая информацию обо всех установленных принтерах |
CSIDL_PRINTHOOD | Папка, используемая как общее хранилище для ярлыков принтеров |
CSIDL_PROGRAMS | Папка, содержащая группы программ (которые также являются папками) конкретного пользователя |
CSIDL_RECENT | Папка, содержащая ссылки на документы, с которыми пользователь работал в последнее время |
CSIDL_SENDTO | Папка, которая содержит объекты, появляющиеся в меню Send To |
CSIDL_STARTMENU | Папка, содержащая пункты меню Start |
CSIDL_STARTUP | Папка, соответствующая группе программ Startup (для конкретного пользователя). Программы из этой папки автоматически запускаются каждый раз при регистрации в Windows NT либо при запуске Windows 95 или Windows 98 |
CSIDL_TEMPLATES | Папка для хранения шаблонов документов |
Создание ярлыка
Интерфейс IShellLink
инкапсулирует объект ярлыка, но не определяет, как он
может быть прочитан или записан на диск. Поэтому реализация данного интерфейса
требует дополнительной поддержки интерфейса IPersistFile
,
который используется для обеспечения доступа к файлам. Интерфейс IPersistFile
содержит методы
чтения и записи данных на диск и определен следующим образом:
type
IPersistFile = interface(IPersist)
['{0000010B-0000-0000-C000-000000000046}']
function IsDirty: HResult; stdcall;
function Load(pszFileName: POleStr;dwMode: Longint): HResult; stdcall;
function Save(pszFileName: POleStr;fRemember: BOOL): HResult; stdcall;
function SaveCompleted(pszFileName: POleStr): HResult;stdcall;
function GetCurFile(out pszFileName: POleStr): HResult;stdcall;
end;
Поскольку класс, реализующий интерфейс IShellLink
, всегда содержит
реализацию интерфейса IPersistFile
, экземпляр интерфейса IShellLink
можно использовать
для получения экземпляра интерфейса IPersistFile
с помощью операции
преобразования типа as
, как показано ниже.
var
SL: IShellLink;
PF: IPersistFile;
begin
OleCheck(CoCreateInstance(CLSID_ShellLink, nil,CLSCTX_INPROC_SERVER, IShellLink, SL));
PF := SL as IPersistFile;
// Использовать экземпляры интерфейсов PF и SL
end;
Рассмотрим создания ярлыка для приложения Notepad (Блокнот), который помещается на поверхность рабочего стола:
procedure MakeNotepad;
const
// Предположим, что Notepad расположен в папке:
AppName = 'c:\windows\notepad.exe';
var
SL: IShellLink;
PF: IPersistFile;
LnkName: WideString;
begin
OleCheck(CoCreateInstance(CLSID_ShellLink, nil,CLSCTX_INPROC_SERVER, IShellLink, SL));
{ При реализации интерфейса IShellLink обязательно реализуется и интерфейс IPersistFile }
PF := SL as IPersistFile;
OleCheck(SL.SetPath(PChar(AppName)));
// Установить путь к необходимому файлу:
{ Указать размещение и имя файла создаваемого ярлыка: }
LnkName := GetFolderLocation('Desktop') + '\' + ChangeFileExt(ExtractFileName(AppName), '.lnk');
PF.Save(PWideChar(LnkName), True); // Сохранить файл ярлыка
end;
В этой процедуре метод SetPath()
интерфейса IShellLink
используется для
указания пути к исполняемому файлу или документу, для которого создается ярлык (в
данном случае это программа Notepad). Затем определяется полный путь и имя файла
ярлыка, для чего используется информация, возвращаемая функцией GetFolderLocation('Desktop')
(описанной выше). Кроме того, для изменения
расширения файла Notepad.exe с .exe на lnk используется функция ChangeFileExt()
.
Новое имя файла сохраняется в переменной LnkName
. Затем с помощью метода Save()
новый ярлык сохраняется в файле на диске. Как уже было сказано,
при завершении приведенной выше процедуры и выходе экземпляров интерфейсов SL и PF
за пределы области видимости соответствующие ссылки на них освобождаются.
Ждем Ваших откликов на емайл 5781-author@subscribe.ru или subscr@chertenok.ru
Приглашаем авторов в рассылку!
С уважением,
координатор рассылки Алексей aka Gelios.
Наши координаты:
сайт - www.delphi.chertenok.ru
форум - www.forum.chertenok.ru
контактный email - 5781-author@subscribe.ru
Другие проекты:
www.travel.chertenok.ru - сайт о путешествиях!
Subscribe.Ru
Поддержка подписчиков Другие рассылки этой тематики Другие рассылки этого автора |
Подписан адрес:
Код этой рассылки: comp.soft.prog.allofdelphi Архив рассылки |
Отписаться
Вспомнить пароль |
В избранное | ||