Создание группы программ

Рассмотрим создание группы программ средствами Проводника. Дело в том, что меню, которое вы видите, нажав на кнопку Пуск, хранится на диске в виде обычных каталогов и файлов. Для того, чтобы создать группу, мы должны всего лишь создать каталог; для того, чтобы создать элемент — скопировать файл в каталог или создать ярлык на существующую программу. Что такое ярлык? Ярлык — это файл с расширением .LNK, в котором хранится информация о каком-то другом файле. Для операционной системы ярлык олицетворяет собой файл, на который он ссылается.

Для чего применяются ярлыки? Для того, чтобы вам не нужно было хранить на своём диске несколько одинаковых файлов. Например, программа WinZip во время инсталляции помещает себя на рабочий стол, в меню Пуск и в меню Программы. Что, вы думаете, файл winzip.exe хранится на диске в трёх экземплярах? Отнюдь.

Учтите, что ярлык занимает на диске где-то 250–400 байт, поэтому для файлов меньшего размера ярлыки создавать бессмысленно.

С этого момента я объявляю ярлыки новой парадигмой создания групп! :) Звучит громко... Нам осталось только выяснить, как это делается. :) Итак, группы менеджера программ доступны нам через кнопку Пуск подменю Программы. В действительности, все они являются подкаталогами, одного из каталогов Windows (это может быть, например, C:WindowsГлавное менюПрограммы. Путь к этому каталогу Проводник хранит в реестре.

procedure ReadGroups(Strings: TStrings); 
var 
ARegistry: TRegistry; 
Programs: String; 
SearchRec: TSearchRec; 
FindResult: Integer; 
begin 
Strings.Clear; 
// Находим каталог 
ARegistry := TRegistry.Create; 
with ARegistry do 
begin 
RootKey := HKEY_CURRENT_USER; 
if OpenKey('SoftwareMicrosoftWindowsCurrentVersionExplorer Shell Folders', False) then 
begin 
Programs := ReadString('Programs'); 
CloseKey; 
end 
else 
Programs := ''; 
Free; 
end; 
if (Length(Programs) > 0) and (Programs[Length(Programs)] <> '') then 
Programs := Programs + ''; 
// Читаем содержимое каталога 
FindResult := FindFirst(Programs + '*.*', faDirectory, SearchRec); 
while FindResult = 0 do 
begin 
with SearchRec do 
if (Name <> '.') and (Name <> '..') and (Attr and faDirectory <> 0) then 
Strings.Add(Name); 
FindResult := FindNext(SearchRec); 
end; 
FindClose(SearchRec); 
end;


Точно таким же макаром можно прочитать содержимое любой группы. Достаточно очевидно делаются такие вещи, как создать группу, удалить группу, переименовать (!) группу и так далее. Более того, теперь вы можете создавать группы в меню Пуск и на рабочем столе (в статье о системном реестре рассказано как найти путь к этим каталогам). Мы так же можем воспользоваться функцией SHGetSpecialFolderLocation для того, чтобы выяснить, где находится тот или иной каталог Проводника.
function GetSpecialFolderLocation(nFolder: Integer): String; 
var 
ppidl: PItemIDList; 
Malloc: IMalloc; 
szPath: array[0..MAX_PATH - 1] of Char; 
begin 
SHGetSpecialFolderLocation(Handle, nFolder, ppidl); 
SHGetMalloc(Malloc); 
SHGetPathFromIDList(ppidl, szPath); 
Malloc.Free(ppidl); 
Malloc := nil; 
Result := String(szPath); 
end; 


Что нам осталось узнать? Как получить информацию о ярлыке и как создать ярлык. Обе эти операции удобно делать с помощью интерфейса IShellLink, предоставляемого нам Проводником. Об интерфейсах (и связанных с ними COM-объектах) говорить можно долго, однако, для наших целей это не нужно. Нам достаточно знать, что интерфейсы очень напоминают обычне классы, за несколькими исключениями. Вот, например:
const 
MAX_DESCRIPTION = 100; 
var 
Bitmap: TBitmap; 
ShellLink: IShellLink; 
Description: array[0..MAX_DESCRIPTION - 1] of Char; 
begin 
// Создаём обычный объект 
Bitmap := TBitamp.Create; 
// Создаём COM-объект 
CoCreateInstance(CLSID_ShellLink, nil, CLSCTX_INPROC_SERVER, IID_IShellLinkA, ShellLink); 
. . . 
// Используем обычный объект 
Bitmap.Width := 100; 
// Используем COM-объект 
ShellLink.GetDescription(Description, MAX_DESCRIPTION); 
. . . 
// Удаляем обычный объект 
Bitmap.Free; 
// Удаляем COM-объект 
ShellLink := nil; 
end; 
Итак, для того, чтобы создать COM-объект в Дельфи, вы должны вызвать функцию CoCreateInstance, передав её в качестве параметров несколько странного вида констант. COM-объекты автоматически удаляются по завершении процедуры, в которой они были созданы. Тем не менее, я предпочитаю явное указание того факта, что COM-объект должен быть уничтожен: 
ShellLink := nil; 
Теперь приведу пример, показывающий, как можно создать ярлык на рабочем столе. 
var 
Desktop: String; 
ShellLink: IShellLink; 
hRes: HRESULT; 
PersistFile: IPersistFile; 
begin 
// Находим каталог 
Desktop := GetSpecialFolderLocation(CSIDL_DESKTOPDIRECTORY); 
if (Length(Desktop) > 0) and (Desktop[Length(Desktop)] <> '') then 
Desktop := Desktop + ''; 
CoInitialize(nil); 
hRes := CoCreateInstance(CLSID_ShellLink, nil, CLSCTX_INPROC_SERVER, 
IID_IShellLinkA, ShellLink); 
if SUCCEEDED(hRes) then 
begin 
ShellLink.SetPath(PChar(Application.ExeName)); 
ShellLink.SetDescription('Вот моя программа!'); 
hRes := ShellLink.QueryInterface(IID_IPersistFile, PersistFile); 
if SUCCEEDED(hRes) then 
begin 
PersistFile.Save(PWideChar(WideString(Desktop + 'Моя программа.lnk')), True); 
PersistFile := nil; 
end; 
ShellLink := nil; 
end; 
CoUninitialize; 
end; 
Подробнее узнать о том, что можно делать с помощью интерфейса IShellLink вы можете в win32.hlp (ключевое слово — IShellLink :) Вызовы функций CoInitialize и CoUninitialize обеспечивают работу COM, всегда вызывайте первую из них перед работой, а вторую — после работы.

Для работы этих примеров вам потребуется включить (uses) в свой модуль файлы Windows, ShlObj, ActiveX, ShellApi. По недосмотру, или по какой-то другой причине, Инпрайз не внесла константу IID_IPersistFile ни в один из этих файлов. Эту константу можно найти в модуле Ole2, однако этот модуль оставлен в 3-ей и 4-ой версиях Дельфи только в целях совместимости со 2-ой версией, где COM-интерфейсы были реализованы по другому. Я сам уже запутался, честно говоря, объясняя, что здеь к чему :) Если в двух словах, скопируйте эти строчки из модуля Ole2.pas в свою программу и расслабтесь:
const 
IID_IPersistFile: TGUID = ( 
D1:$0000010B;D2:$0000;D3:$0000;D4: 
($C0,$00,$00,$00,$00,$00,$00,$46));
Напоследок остановимся на том, какой же метод создания групп лучше? Давайте рассмотрим достоинства и недостатки этих методов.

Менеджер программ достался нам в наследство от 16-битных версий Windows. Он капризен и работает неторопливо. Помимо всего прочего, с помощью него нельзя помещать ярлыки на рабочий стол и в меню Пуск.

С другой стороны, интерфейсы проводника более современны, дают больший контроль за происходящим, работают быстрее... И помимо прочего, заставляют программиста осваивать новую технологии (а если программист ленив, ему такие стимулы необходимы, как воздух :)

И тем не менее — для создания групп в меню Программы я рекомендую вам пользоваться менеджером программ.

Почему?

Потому что менеджер программ, помимо того, что создаёт все необходимые каталоги и ярлыки, отражает изменения в файлах с расширением .GRP. Может оказаться, что некоторые программы (старые) работают с файлами групп, и, следовательно, некорректно будут работать с вашими ярлыками.

Конечно, ситуация, о которой я вам рассказываю, гипотетическая. Я ещё не разу не слышал о каких-бы то ни было действительных нареканиях для способа с IShellLink. В любом случае, решайте сами.

Примечание
Всё, о чём я говорил выше, относится только к группам, ярлыки на рабочем столе или в меню Пуск в любом случае придётся создавать с помощью IShellLink.

Вот и всё, Удачи!



Добавил(а): Skyppy Дата: 2015-06-02
Здравствуйте уважаемый. Просьба к Вам помочь написать мини программу. Суть программы: Нужно что бы в окне программы выводилась информация которая находится на листе эксель. Строк примерно 25 . колонок 3. Лист 1 Примечание. 1.В экселе информация в этик сроках обновляется каждые 5 минут и программа должна также показывать обновленное инфо. 2. Возможно ли наложить пароль для доступа к инфо ограниченный по времени (допустим на сутки или неделю или месяц) Спс большое за ранее жду ответов. За мной не заржавеет обещаю. С уважением Skyppy Если что пишите на мыло: [email protected]


    No results found.
Отменить.