'Стандартные окна 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(2 0, 20, 200, 30, 1001, 'Открытие файла');
CreateButton(2 0, 60, 200, 30, 1002, 'Сохранение файла');
CreateButton(2 0, 100, 200, 30, 1003, 'Выбор цвета');
CreateButton(2 0, 140, 200, 30, 1004, 'Выбора шрифта');
CreateButton(2 0, 180, 200, 30, 1005, 'Окно поиска текста');
CreateButton(2 0, 22 0, 200, 30, 1006, 'Окно поиска и замены');
CreateButton(23 0, 20, 22 0, 30, 1010, 'Выбор папки');
CreateButton(23 0, 60, 22 0, 30, 1011, 'Подключение сетевого ресурса');
CreateButton(23 0, 100, 22 0, 30, 1012, 'Отключение сетевого ресурса');
CreateButton(23 0, 140, 22 0, 30, 1013, 'Системное окно "О программе"');
//Текстовое поле для результата
CreateMemo (20, 270, 430, 100, 2001);
ShowWindow(hMainWnd, SW_NORMAL);
//Запуск цикла обработки сообщений
while (Longint(GetMessage(mess, 0, 0, 0)) <> 0) do
begin
if (IsDialogMessage(hMainWnd, mess) = False) then
begin
TranslateMessage(mess);
DispatchMessage(mess);
end;
end;
end.
Код функции RegisterWindow опущен, поскольку он аналогичен приведенному в листинге 2.4. Функции работы с рассмотренными ранее окнами вынесены в модуль StdWindows(файл StdWindows.pas).
Особенностью цикла обработки сообщений в этом примере является использование API-функции IsDialogMessage, которая позволяет реагировать на некоторые действия пользователя так, как это делается в рассмотренных выше окнах. Примером может служить перемещение фокуса между окнами при нажатии клавиши Tab.
Перед функцией RegisterWindow (на месте многоточия перед ее объявлением в листинге 2.33) находится функция обработки сообщений, имеющая следующий вид (листинг 2.34).
function WindowFunc(hWnd:HWND; msg:UINT; wParam:WPARAM; lParam:LPARAM):LRESULT; stdcall;
var
hOldFont: HFONT;
strBuf: String;
hEditDC: HDC;
begin
case msg of
WM_CLOSE:
if (hWnd = hMainWnd) then PostQuitMessage(0);
WM_CTLCOLOREDIT: //Сообщения от Edit перед перерисовкой
begin
//Зададим тексту Edit выбранный цвет
hEditDC:= HDC(wParam);
SetTextColor(hEditDC, curColor);
GetCurrentObject(hEditDC, OBJ_BRUSH);
end;
WM_COMMAND:
if (HIWORD(wParam) = BN_CLICKED) then
begin
//Определим, какая кнопка нажата
case LOWORD(wParam) of
1001: //Открытие файла
begin
SetText(2 001, 'Открыт файл:'+ #13 + #10 +
ShowOpen('Все файлы|*.*||'));
end;
1002: //Сохранение файла
begin
SetText(2001, 'Путь для сохранения:'+ #13 + #10 +
ShowSave('Все файлы|*.*||'));
end;
1003: //Выбор цвета
begin
curColor:= ShowChooseColor(curColor);
Str(curColor, strBuf);
SetText(2001, 'Выбранный цвет:'+ #13 + #10 + strBuf);
end;
1004: //Выбор шрифта
begin
if (ShowChooseFont(font) = True) then
begin
//Замена шрифта в Edit
hOldFont:= HFONT(
SendDlgItemMessage(hMainWnd,2001,WM_GETFONT, 0,0));
hCurFont:= CreateFontIndirect(font);
SendDlgItemMessage(hMainWnd, 2001, WM_SETFONT,
Integer(hCurFont), Integer(True));
SetText(2001, 'Текст, записанный выбранным шрифтом');
if (hOldFont <> 0) then DeleteObject(hOldFont);
end;
end;
1010: