Стоит пояснить, что за переменная, а точнее, адрес, сохраняется в поле lpCustColors – это массив из 16 значений типа COLORREF:
colors: array [1..16] of COLORREF;
Обратите внимание на 16 квадратов в левой нижней области окна (рис. 2.4) – это места для определенных пользователем цветов. Для заполнения этой области окна и используются значения из массива colors. Массив может быть как локальным, так и глобальным (что иногда удобнее, так как значения определенных пользователем цветов в этом случае сохраняются между вызовами окна выбора цвета).
Окно для выбора шрифта
Для вывода окна для выбора шрифта подойдет функция, приведенная в листинге 2.27.
function ShowChooseFont(var font: LOGFONT):BOOL;
var
choose: TChooseFont;
begin
ZeroMemory(Addr(choose), SizeOf(choose));
//Заполнение структуры для окна
choose.lStructSize:= SizeOf(choose);
choose.hWndOwner:= hParentWnd;
choose.hInstance:= hAppInst;
choose.lpLogFont:= Addr(font);
choose.Flags:= CF_BOTH or CF_INITTOLOGFONTSTRUCT;
//Отображение окна и обработка результата
if (ChooseFont (choose) = True) then
begin
CopyMemory(Addr(font), choose.lpLogFont, SizeOf(font));
ShowChooseFont:= True;
end
else ShowChooseFont:= False;
end;
Здесь используются флаги окна, имеющие следующие значения:
• CF_BOTH – позволяет отображать экранные и принтерные шрифты (для отображения либо экранных, либо принтерных шрифтов можно использовать флаги CF_SCREENFONTS и CF_PRINTERFONTS соответственно);
• CF_INITTOLOGFONTSTRUCT – позволяют выбрать в окне шрифт, соответствующий (или максимально похожий) шрифту, описываемому структурой LOGFONT, указатель на которую сохраняется в поле lpLogFont.
Окно для выбора папки
Чтобы иметь возможность пользоваться окном Обзор папок, можно использовать функцию, представленную в листинге 2.28.
function ShowChooseFolder(strTitle: string):string;
var
choose: BROWSEINFO;
buffer: string;
pidl: PItemIDList;
begin
ZeroMemory(Addr(choose), SizeOf(choose));
SetLength(buffer, MAX_PATH);
//Заполнение структуры для окна
choose.hwndOwner:= hParentWnd;
choose.pi dlRoot:= 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 (что-то вроде внутреннего представления путей). Для извлечения построения пути по содержимому этой структуры используется функция SHGetPathFromIDList. После этого структура становится больше не нужна, и ее следует удалить (с использованием специального интерфейса IMalloc). Для этого используется процедура DeletePIDL, реализованная в листинге 2.29.
procedure DeletePIDL(pidl: PItemIDList);
var
pMalloc: IMalloc;
begin
SHGetMalloc(pMalloc);
if (pMalloc <> nil) then
begin
pMalloc.Free(pidl);
pMalloc._Release();
end;
end;
Функцию SHBrowseForFolder (листинг 2.28) можно использовать и для указания принтеров или компьютеров. Для этого достаточно установить флаги BIF_ BROWSEFORCOMPUTER и BIF_BROWSEFORPRINTER соответственно: