Демонстрационное приложение

Теперь пришла очередь рассмотреть небольшое приложение, использующее описанные выше окна (проект StandartWindows). Окно этого приложения показано на рис. 2.8.

Рис. 2.8. Окно демонстрационного приложения

Размер EXE-файла приложения равен 22 Кбайт.

В листинге 2.33 приведены объявления используемых глобальных переменных, код, реализующий создание окна и элементов управления в нем, а также цикл обработки сообщений (файл StandartWindows.dpr). Функции работы с рассмотренными выше окнами вынесены в отдельный модуль StdWindows (файл StdWindows.pas).

В листингах 2.33-2.34 используются уже знакомые вам функции из модуля 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(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).

Листинг 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: //Выбор папки

begin

SetText(2 001, 'Выбранная папка:'+ #13 + #10 +

ShowChooseFolder());

end;

1011: //Подключение сетевого ресурса

begin

ShowConnection();

end;

1012: //Отключение сетевого ресурса

begin

ShowDisconnect();

end;

1013: //Окно "О программе"

begin

ShowAbout('Standart windows',

'Демонстрация использования стандартных '+

'окон из чистого API-приложения');

end;

end;

end;

else

begin

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

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

Exit;

end;

end;

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

end;

Обработка сообщений здесь довольно проста, за исключением изменения шрифта текстового поля. Обратите внимание на следующий отрывок листинга 2.34:

//Замена шрифта в Edit

hOldFont:= HFONT(SendDlgItemMessage(hMainWnd,2001,WM_GETFONT, 0,0));

hCurFont:= CreateFontIndirect(font);

SendDlgItemMessage(hMainWnd, 2001, WM_SETFONT,

Integer(hCurFont), Integer(True));

SetEdit Text(2001, 'Текст, записанный выбранным шрифтом');

if (hOldFont <> 0) then DeleteObject(hOldFont);

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

Способ, которым можно установить шрифт всех элементов управления окна, рассмотрен ниже. Остался еще один существенный момент: не забывайте удалять объекты GDI (в данном случае – шрифт) после того, как они стали не нужны. Дело в том, что приложение может содержать не более 65 ООО объектов GDI, и при наличии так называемой «утечки» ресурсов GDI может произойти аварийное завершение приложения из-за исчерпания лимита ресурсов GDI.

Более 800 000 книг и аудиокниг! 📚

Получи 2 месяца Литрес Подписки в подарок и наслаждайся неограниченным чтением

ПОЛУЧИТЬ ПОДАРОК

Данный текст является ознакомительным фрагментом.