BROWSEINFO;
buffer: string;
pidl: PItemIDList;
begin
ZeroMemory(Addr (choose), SizeOf(choose));
SetLength(buffer, MAX_PATH);
//Заполнение структуры для диалога
choose.hwndOwner := hParentWnd;
choose.pidlRoot := nil; //Корень – папка Рабочего стола
choose.pszDisplayName := PAnsiChar(buffer);
choose.lpszTitle := PAnsiChar (strTitle);
choose.ulFlags := 0;
//Вывод диалогового окна и обработка результата
pidl := SHBrowseForFolder(choose);
if (pidl <> nil) then
begin
//Получение полного пути выбранной папки
SHGetPathFromIDList(pidl, PAnsiChar(buffer));
ShowChooseFolder := buffer;
DeletePIDL (pidl);
end
else
ShowChooseFolder := '
end;
В листинге 2.28 функция ShowChooseFolder возвращает полный путь указанной папки, если она выбрана, и пустую строку в противном случае. Само окно Обзор папок показано на рис. 2.5.
Рис. 2.5. Окно выбора папки
Особенностью использованной в данном примере функции SHBrowseForFolder является то, что она возвращает не путь выбранного каталога, а указатель на структуру ItemlDList (что-то вроде внутреннего представления путей). Для извлечения построения пути по содержимому этой структуры используется функция SHGetPathFromlDList. После этого структура нам больше не нужна, и ее следует правильно удалить (с использованием специального интерфейса IMalloc). Для этого используется процедура DeletePIDL, реализованная в листинге 2.29.
Листинг 2.29.
Удаление структуры ItemlDList
procedure DeletePIDL(pidl: PItemIDList);
var
pMalloc: IMalloc;
begin
SHGetMalloc(pMalloc);
if (pMalloc <> nil) then
begin
pMalloc.Free(pidl);
pMalloc._Release ();
end;
end;
Примечание
Освобождение памяти, занимаемой данными структуры ItemlDList, можно выполнить и более простым способом: использовать API-функцию CoTaskMemFree, передав ей адрес структуры в качестве следующего параметра: CoTaskMemFree (pidl).
Вообще функцию SHBrowseForFolder (листинг 2.28) можно использовать и для указания принтеров или компьютеров. Для этого достаточно установить флаги BIF_BROWSEFORCOMPUTERH BIF_BROWSEFORPRINTER соответственно:
choose.ulFlags := BIF_BROWSEFORCOMPUTER;
или
choose.ulFlags := BIF_BROWSEFORPRINTER;
Чтобы в окне отображались еще и значки файлов, необходимо установить флаг BIF_BROWSEINCLUDEFILES.
Окна подключения и отключения сетевого ресурса
Часто бывает удобно осуществлять доступ к сетевым папкам как к локальным дискам компьютера (с использованием того же принципа построения пути). Окна подключения и отключения сетевого ресурса позволяют дать пользователю возможность выбрать, какие папки считать сетевыми дисками и какие сетевые диски можно отключить.
Окно подключения сетевого ресурса в Windows ХР выглядит так, как показано на рис. 2.6.
Рис. 2.6. Окно подключения сетевого диска
Для вызова диалогового окна подключения сетевого ресурса можно использовать функцию, приведенную в листинге 2.30.
Листинг 2.30.
Окно подключения сетевого ресурса
function ShowConnection(): BOOL;
begin
ShowConnection :=
WNetConnectionDialog(hParentWnd, RESOURCETYPE_DISK) = NO_ERROR;
end;
Функция ShowConnection возвращает True в случае удачного подключения и False в противном случае.
Окно отключения сетевого диска приведено на рис. 2.7.
Рис. 2.7. Отключение сетевого ресурса
Функция, показывающая окно отключения сетевого диска, приведена в листинге 2.31.
Листинг 2.31.
Окно отключения сетевого ресурса
function ShowDisconnect(): BOOL;
begin
ShowDisconnect :=
WNetDisconnectDialog(hParentWnd, RESOURCETYPE_DISK) = NO_ERROR;
end;
Аналогично ShowConnection функция ShowDisconnect возвращает True, если отсоединен хотя бы один диск, и False в противном случае.
Системное окно «О программе»
Этот последний и довольно экзотичный пример приведен на случай, если возникнет желание или необходимость использовать красивое окно О программе, которое выводится для самой операционной системы Windows и ее компонентов. Процедура выведения этого окна приведена в листинге 2.32.
Листинг 2.32.
Окно «О программе»
procedure ShowAbout(strAppName: string; strInfo: string);
begin
ShellAbout(hParentWnd, PAnsiChar(strAppName),
PAnsiChar (strInfo),LoadIcon(0, IDI_ASTERISK));
end;
Правда, в окне О программе Windows ХР на информацию о приложении отведено всего две строки (и место для значка слева от окна). Все остальное место занимают информация о регистрации операционной системы и фирменная эмблема Microsoft Windows ХР.
Демонстрационное приложение
Теперь пришла очередь рассмотреть небольшое приложение, использующее описанные выше диалоговые окна (проект StandartWindows). Окно этого приложения приводится на рис. 2.8.
Рис. 2.8. Окно демонстрационного приложения
Размер ЕХЕ-файла приложения равен 22 Кбайт. В листинге 2.33 приводятся объявления используемых глобальных переменных, а также код, реализующий создание окна и элементов управления в нем, цикл обработки сообщений (файл StandartWindows. dpr). Функции работы с рассмотренными выше диалоговыми окнами вынесены в отдельный модуль StdWindows (файл StdWindows.pas). В этом и следующем листинге используются уже знакомые вам функции из модуля Controls.
Листинг 2.33.
Глобальные переменные, код создания окна и цикл обработки сообщений
program StandartWindows;
{$R *.res}
uses
Windows, Messages, CommDlg,
Controls in 'Controls.pas',
StdWindows in 'StdWindows.pas
var
hMainWnd: HWND;
hInst: Cardinal;
mess: MSG;
curColor: COLORREF;
font: LOGFONT;
hCurFont: HFONT;
…
function RegisterWindow ():Boolean;
…
begin
hInst := GetModuleHandle(nil);
//Регистрация и создание главного окна
if not RegisterWindow() then Exit;
hMainWnd := CreateWindow (
'MyWindowClass', //Имя класса окна
'Стандартные окна Windows', //Заголовок окна
WS_CAPTION or WS_SYSMENU or WS_CLIPCHILDREN or WS_CLIPSIBLINGS,
CW_USEDEFAULT, //Координата X по умолчанию
CW_USEDEFAULT, //Координата Y по умолчанию
470, 420,
HWND(nil), //Нет родительского окна
HMENU(nil), //Нет меню
hInst,
nil);
if (hMainWnd = HWND(nil)) then Exit;
//Инициализация модуля Controls для работы с главным
//окном приложения
Controls.hParentWnd := hMainWnd;
Controls.hAppInst := hInst;
//Инициализация модуля StdWindows для работы с главным
//окном приложения
StdWindows.hParentWnd := hMainWnd;
StdWindows.hAppInst := hInst;
//Создание кнопок для открытия диалоговых окон
CreateButton(20, 20, 200, 30, 1001, 'Открытие файла');
CreateButton(20, 60, 200, 30, 1002, 'Сохранение файла ');
CreateButton(20, 100, 200, 30, 1003, 'Выбор цвета');
CreateButton(20, 140, 200, 30, 1004, 'Выбор шрифта');
CreateButton(20, 180, 200, 30, 1005, 'Окно поиска текста ');
CreateButton(20, 220, 200, 30, 1006, 'Окно поиска и замены');
CreateButton(230, 20, 220, 30, 1010, 'Выбор папки');
CreateButton(230, 60, 220, 30, 1011, 'Подключение сетевого
ресурса');
CreateButton(230, 100, 220, 30, 1012, 'Отключение сетевого
ресурса');
CreateButton(230, 140, 220, 30, 1013, 'Системное окно 'О про-
грамме'');
//Текстовое поле для результата
CreateMemo(20, 270, 430, 100, 2001);
ShowWindow(hMainWnd, SW_NORMAL);
//Запуск цикла обработки