//выделение в ListBox

5001: if HIWORD(wParam) = LBN_SELCHANGE then;

//изменен текст в Edit

6001: if HIWORD(wParam) = EN_CHANGE then;

//изменен текст в Memo

6002: if HIWORD(wParam) = EN_CHANGE then;

end;

end;

else

begin

//Обработка по умолчанию

WindowFunc:= DefWindowProc(hWnd, msg, wParam, lParam);

Exit;

end;

end;

WindowFunc:= S_OK; //Сообщение обработано

end;


Приведенная в листинге 2.22 функция не претендует на то, чтобы быть эталоном в порядке классификации сообщений от элементов управления. Иногда бывает полезно сразу классифицировать сообщения не по элементам управления, которые их прислали, а по типу самих сообщений. К тому же в ряде случаев можно предусмотреть один обработчик сообщений сразу для нескольких элементов управления, например, для группы переключателей. В таком случае полезным окажется параметр lParam сообщения WM COMMAND.

Кстати, размер исполняемого файла этого приложения равен всего 19 Кбайт.

Стандартные окна Windows

Теперь рассмотрим, как можно с помощью только функций Windows API вызывать некоторые распространенные окна. Чтобы использовать API-функции и структуры с информацией для этих окон, необходимо подключить следующие модули:

• CommDlg – для окон открытия и сохранения файла, выбора цвета и шрифта, поиска и замены текста;

• ShlObj и ActiveX – для окна выбора папки (второй модуль нужен для доступа к интерфейсу IMalloc, зачем – будет рассказано далее);

• Windows – помимо объявления основных структур и API-функций, этот модуль содержит объявления функций для работы с окнами подключения и отключения от сетевого ресурса (сетевого диска);

• ShellAPI – для системного окна О программе.

Вариант использования рассматриваемых в этом разделе окон приведен в подразделе «Демонстрационное приложение» данной главы (стр. 81).

Примечание

В приведенных далее примерах вызова окон можно увидеть не объявленные, но используемые в программах переменные hAppInst и hParentWnd. Подразумевается, что это глобальные переменные, которые инициализируются вне процедур и функций, приведенных в примерах. Для инициализации этих переменных можно также написать специальную процедуру, например, с именем Init, в которую и передавать значения для hParentWnd и hAppInst.

Окно открытия и сохранения файла

Чтобы использовать возможности окна открытия файла, достаточно воспользоваться функцией, представленной в листинге 2.23.

Листинг 2.23. Окно открытия файла

function ShowOpen(strFilter: string; nFilterIndex: Integer= 0;

strInitFileName: string = '';

var

ofn: OPENFILENAME;

begin

ZeroMemory(Addr(ofn), SizeOf(ofn));

//Формирование буфера (260 символов)

SetLength(strInitFileName, MAX_PATH);

PrepareFilterString(strFilter);

//Заполнение структуры для окна

ofn.lStructSize:= SizeOf(ofn);

ofn.hWndOwner:= hParentWnd;

ofn.hInstance:= hAppInst;

ofn.lpstrFilter:= PAnsiChar(strFilter);

ofn.nFilterIndex:= nFilterIndex;

ofn.lpstrFile:= PAnsiChar(strInitFileName);

ofn.nMaxFile:= MAX_PATH;

ofn.lpstrTitle:= pAnsiChar(strTitle);

ofn.Flags:= OFN_FILEMUSTEXIST or OFN_PATHMUSTEXIST or OFN_HIDEREADONLY;

//Отображение окна и обработка результата

if(GetOpenFileName(ofn) = True) then

ShowOpen:= ofn.lpstrFile;

end;


Приведенная в листинге 2.23 функция возвращает непустую строку – полный путь файла в случае, если пользователь выбрал или ввел имя файла. Здесь главной трудностью является заполнение довольно большой структуры OPENFILENAME. В данном примере используются только базовые возможности окна открытия файла и лишь некоторые из поддерживаемых им флагов (поле Flags):

• OFN_FILEMUSTEXIST – при этом установленном флаге, если окно успешно завершило свою работу, можно быть уверенным, что результирующий путь является путем существующего файла;