Отправляет email-рассылки с помощью сервиса Sendsay
  Все выпуски  

Программирование от Чертенка.ру Выпуск 2. Создание ярлыков на рабочем столе


Информационный Канал Subscribe.Ru

Доброго времени суток, уважаемые подписчики!

За прошедшую неделю в мире soft IT произошли следующие интересные новости:

  1. IBM рассказал о планах по выпуску бесплатной версии своей СУБД DB2


В сегодняшнем выпуске мы раскажем о том, как программно в 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 за пределы области видимости соответствующие ссылки на них освобождаются.

В следующих выпусках мы продолжим цикл статей по .Net Framework, поделимся накопленным опытом в области Делфи (автоматическое обновление программы по локальной сети, упрощение работы с репортами FastReport и XLReport, автоматизация работы с СУБД, работа с Excel), расскажем о продуктах фирмы Devrace, а также будут авторские статьи по Делфи

Ждем Ваших откликов на емайл 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
Архив рассылки
Отписаться
Вспомнить пароль

В избранное