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

       

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



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

Диалоговое окно выбора папки, созданное при вызове функции 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.

 



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