Компоненты Rave Reports и отчеты в приложении Delphi

Диалоговое окно выбора папки, созданное при вызове функции ShBrowseForFolder



Рисунок 31.3. Диалоговое окно выбора папки, созданное при вызове функции ShBrowseForFolder


В данном примере корневой служит виртуальная папка My Computer. Пользователю предоставляется возможность выбрать одну из папок файловой системы (за это отвечает флаг TBrowseinfo.uiFlags, равный

BIF_RETURNONLYFSDIRS).

На выходе функция возвращает pidi папки, имя которой извлекается из него вызовом еще одной функции Shell — shGetPathFromList.

procedure TForml/ButtonlClick(Sender: TObject) ;

var

BI : TBrowselnfo;

Image : integer;

StartPIDL, ResPIDL : PItemlDList;

S, Path : ArraytO..max_path-l] Of WideChar;

begin

01eCheck(SHGetSpecialFolderLocation(Handle, CSIDL_DRIVES, StartPIDL));

With BI do



Begin

hwndOwner = Application.Handle;

pszDisplayName = @S;

IpszTitle = 'Выберите необходимую папку';

ulFlags = BIF_RETURNONLYFSDIRS;

pidlRoot = StartPIDL;

Ipfn = nil;

iImage = 1;

end;

ResPIDL := SHBrowseForFolder(BI) ; 

if SHGETPathFromlDList(ResPIDL, @Path[0]) 

then Labe11.Caption := StrPas(@Path[0]) ;

end;

Полученное имя здесь отображается при помощи компонента Label 1.

3. Наконец, перейдем к третьему действию нашей задачи. Теперь, зная pidi папки, с которой вы будете работать, можно получить указатель на интерфейс ishellFolder вызовом метода BindToObject. Мы еще не рассмотрели такой важный аспект работы с папками, как просмотр их содержимого. Верные правилу СОМ: "каждый должен заниматься своим делом", разработчики Shell предоставили для просмотра еще один интерфейс — IEnumiDList. Пугаться нечего, набор возможностей этого интерфейса даже меньше, чем у пульта ДУ в магнитофоне. Его четыре метода — Next, Skip, Reset и clone — позволяют организовать просмотр списка в одном направлении, а также возврат к началу и дублирование (Clone) выбранного элемента списка. Вот как это выглядит на практике.

Memol.Clear; try

01eCheck(SHGetDesktopFolder(DeskTop));

if not Succeeded(DeskTop.ParseDisplayName

(Self.Handle,nil, StringToWideChar (Editl.Text,ws, MAX_PATH),n, pidi, attr))

then begin ShowMessage('Неизвестное имя');

  Exit; end; OleCheck(DeskTop.BindToObject(pidl,nil, IID_IShellFolder, Pointer(NewShellFolder)});

OleCheck(NewShellFolder.EnumObj ects{Self.Handle,

SHCONTF_FOLDERS or SHCONTF_NONFOLDERS, Enumerator)); while Enumerator.Next(1, pidl, Numpidls) = S_OK do 

begin

NewShellFolder.GetDisplayNameOf(PIDL, SHGDN_FORPARSING, StrRet); case StrRet.uType of STRRET_CSTR:

s := StrRet.cStr; STRRET_OFFSET:

 begin

P := @PIDL.mkid.abID[StrRet.uOffset - SizeOf(PIDL.mkid.cb)];

  SetString(s, P, PIDL.mkid.cb - StrRet.uOffset); 

end; STRRET_WSTR:

s := StrRet.pOleStr; 

end;//case

Memol.Lines.Add(s); 

end; except

on ErEOleSysError do ShowMessage(''); 

end;

В этом примере имя нужной папки извлекается из компонента Edit1. Получив указатель на интерфейс ishellFoider и затем интерфейс IEnumiDList, программа заполняет полученными именами файлов список Memol.Lines.

Помимо названия из большинства объектов файловой системы можно "вытащить" массу полезной информации. Чаще всего задаются вопросом: а как извлечь значок, соответствующий данному файлу или хранящийся в нем?

Способов для достижения этой цели несколько. Самый простой — через вызов функции:

function SHGetFileInfo(pszPath: PAnsiChar; dwFileAttributes: DWORD; 

var psfi: TSHFilelnfo; cbFilelnfo, uFlags: UINT): DWORD;

Параметр pszPath может быть указателем как на строку с именем файла, так и на структуру вида pidl. Функция заполняет структуру psfi (тип TSHFilelnfo) длиной cbFilelnfo байт. В зависимости от значения слова флагов (параметр uFlags) на выходе может быть разнообразная информация. В частности, если в параметре uFlags заданы значения SHGFI_SYSICONINDEX и SHGFI_ICON, то в структуру psfi будет записан номер значка для данного файла в системном списке изображений, а результатом выполнения функции будет дескриптор этого списка. Воспользоваться им можно (например, для панели инструментов) так:

procedure TForml.FormCreate(Sender: TObject); 

var

Filelnfo: TSHFilelnfo; 

ImageListHandle: THandle; 

begin

ImageListHandle := SHGetFilelnfo('С:\',

0,

Filelnfo, SizeOf(Filelnfo) ,

SHGFI_SYSICONINDEX or SHGFI_ICON);

SendMessage(ToolBarl.Handle, TB_SETIMAGELIST, 0, ImageListHandle);

  end;

Точно так же можно извлечь значок, соответствующий конкретному файлу. В составе Shell есть другие функции, созданные для извлечения значков:

  •  function Extractlcon(hlnst: HINST; IpszExeFileName: PChar; nlconlndex: UINT): HICON;

Эта функция извлекает значок из файла IpszExeFileName (это должен быть файл типа EXE, DLL или ICO) и возвращает его дескриптор. Если значок не найден, возвращаемое значение равно 0.

  •  function ExtractAssociatedIcon(hInst: HINST; IpIconPath: PChar; var Ipilcon: Word): HICON;

Эта функция может работать с файлами разных форматов. Сначала она, как и предыдущая, ищет значок в теле файла. Если его там нет, предпринимается попытка отыскать значок в приложении, связанном с данным типом файлов. Например, из файла с расширением doc будет извлечен один из значков Microsoft Word.

 



Содержание раздела