Создайте новое приложение в Delphi и назовите его TestMessages, а главную форму Test, изменив свойство Name.
В результате создания VCL приложения, получился следующий код формы:
unit Unit1;
Interface
Uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs;
Type
TTest = class(TForm)
Private
{ Private declarations }
Public
{ Public declarations }
end;
Var
Test: TTest;
Implementation
{$R *.dfm}
End.
Исходный код приложения имеет вид:
program TestMessages;
Uses
Forms,
Unit1 in 'Unit1.pas' {Test};
{$R *.res}
Begin
Application.Initialize;
Application.CreateForm(TTest, Test);
Application.Run;
End.
Компиляция данной программы прошла успешно, результат ее выполнения представлен на рис.1.
рис.1. Результат работы программы
Напишите Windows-приложение с нуля. Для этого удалите из исходного текста приложения все кроме program, begin, end.
program TestMessages;
Begin
End.
Запустите и посмотрите размер исполняемого файла (около 15 Кб).
Компиляция программы прошла успешно, после запуска ничего не произошло, размер исполняемого файла составляет 17 Кб, что чуть больше, чем ожидалось.
Добавьте цикл обработки сообщений – главное для Windows-приложений. Минимальный код программы см. в Приложении А.
program TestMessages;
Uses
Windows, Messages;
Const
AppName = 'Test';
Var
Window: HWnd; {Ссылка на окно, позволяет однозначно определить каждое окно}
Message: TMsg; {Сообщение – реакция ядра Windows на какое-либо событие}
WindowClass: TWndClass; {Структура класса окна, включает адрес оконной функции, обрабатывающей поступающие от Windows сообщения, атрибуты всех окон, принадлежащих этому классу, т.е. задаются основные свойства класса}
{Специальная оконная функция, обрабатывающая сообщения, посылаемые окну. Вызывается непосредственно ядром Windows (косвенно-вызываемая – callback function). Параметры эквивалентны полям структуры типа TMsg}
function WindowProc (Window: HWnd; Message, WParam: LongInt; LParam: LongInt): LongInt; stdcall;
Begin
WindowProc:= 0;
{Здесь указывается реакция оконной функции на сообщения Windows:}
Case Message of
{Ядро Windows пытается закрыть окно – обработку этого сообщения нельзя опускать}
wm_Destroy:
Begin
{Посылает прикладной программе сообщение wm_Quit код 0 – успешное завершение}
PostQuitMessage (0);
Exit; {Выход из текущей процедуры}
end;
end; //case
{ Все сообщения, не обрабатываемые оконной функцией, передаются функции ядра Windows DefWindowProc}
WindowProc:= DefWindowProc (Window, Message, WParam, LParam); {DefWindowProc обеспечивает обработку тех сообщений окна, которые не обрабатывает прикладная программа}
end;
{Точка входа в программу, которая получает управление от ядра Windows:}
Begin
{Всем полям структуры присваиваются определённые значения (определяются атрибуты окна)}
with WindowClass do begin
Style:= cs_HRedraw or cs_VRedraw; {Стиль окна класса: окно будет перерисовываться при изменении его горизонтальных и вертикальных размеров}
lpfnWndProc:= @WindowProc; {Указатель на оконную функцию, которая будет обрабатывать все сообщения, посылаемые окну}
cbClsExtra:= 0; {Выделенная память, используемая программой по своему усмотрению}
cbWndExtra:= 0; {Выделенная память, используемая программой по своему усмотрению}
hInstance:= 0; {Ссылка на экземпляр программы, используется ядром Windows для однозначного определения сегмента данных экземпляра программы}
hIcon:= LoadIcon (0, idi_Application); {Ссылка на иконку для окна, для отображения минимизированного окна, в данном случае – иконка, соответствующая приложению}
hCursor:= LoadCursor (0, idc_Arrow); {Ссылка на курсор, в данном случае – в виде стрелки}
hbrBackground:= GetStockObject (White_Brush); {Ссылка на шаблон заполнения фона для окна}
lpszMenuName:= ''; { Ссылка на строку с именем меню}
lpszClassName:= AppName; {Имя класса}
end;
{ Регистрация окна с заданными атрибутами. Параметр функции – структура типа TWndClass, содержащая атрибуты окон данного класса}
If RegisterClass (WindowClass) = 0 then
Halt (255); {Регистрация невозможна, завершение работы программы}
Window:= CreateWindow {Создает окно и возвращает ссылку на окно типа HWnd}
(AppName, {Имя класса, к которому принадлежит создаваемое окно}
'Моя форма', {Заголовок окна}
ws_OverlappedWindow, {Стиль окна, в данном случае – комбинация стилей}
cw_UseDefault, {X – начальная позиция верхнего левого угла, в данном случае – значение по умолчанию}
cw_UseDefault, {Y – начальная позиция верхнего левого угла, в данном случае – значение по умолчанию}
800, { Width – начальная ширина окна, в данном случае – значение по умолчанию}
600, {Height – начальная ширина окна, в данном случае – значение по умолчанию}
0, {WndParent – родительское окно данного окна}
0, {Menu – меню, используемое данным окном}
HInstance, {Instance – указывает на экземпляр программы, этот параметр указывается, чтобы оконная функция имела доступ к сегменту данных программы}
nil); {Param – определяет дополнительную информацию, посылаемую через сообщение wm_Create}
{Окно создано, его необходимо отобразить на экране}
ShowWindow (Window, CmdShow); {Отображает или делает невидимым указанное окно}
UpdateWindow (Window); {Указывает прикладной программе, что часть окна нуждается в перерисовке}
{После того, как окно отбражено на экране, управление передаётся циклу обработки сообщений. GetMessage извлекает сообщения из очереди и помещается в структуру типа TMsg.Для всех сообщений, отличных от wm_Quit (завершение работы программы), эта функция возвращает ненулевое значение, и цикл продолжает обработку сообщений}
while GetMessage (Message, 0, 0, 0) do {GetMessage возвращает сообщение из очереди GetMessagePos}
Begin
{TranslateMessage передает структуру типа TMsg ядру Windows для преобразования сообщений о введенных символах}
TranslateMessage (Message); {Переводит сообщение виртуальных клавиш в символьное сообщение}
DispatchMessage (Message); {Передает сообщение оконной функции указанного окна}
{После того, как оконная функция обработала сообщение, управление возвращается в цикл обработки сообщений}
end; {конец цикла обработки сообщений}
Halt (Message.wParam); {Программа завершается}
End.
рис.2. Результат работы программы
5. Задайте окну серый цвет, переписав функцию обработки сообщений следующим образом:
Const
maxx_size = 800;
maxy_size = 600;
function WindowProc (Window: HWnd; Message, WParam: LongInt; LParam: LongInt): LongInt; stdcall;
Var
dc: HDC; { ссылка на контекст, должна использоваться для работы с окном }
MyPaint: TPaintStruct; { структура для работы функций отображения }
Brush: hBrush; { тип "кисть" }
Pen: hPen; { тип "карандаш" }
Begin
WindowProc:= 0;
Case Message of
wm_Destroy:
Begin
PostQuitMessage (0);
Exit; {Выход из текущей процедуры.}
end;
wm_Paint:
Begin
dc:= BeginPaint (Window, MyPaint);
Brush:= CreateSolidBrush (RGB (200, 200, 200)); {кисть}
Pen:= CreatePen (PS_SOLID, 1, RGB (200, 200, 200)); {карандаш }
SelectObject (dc, Brush); {выбираем ссылку для текущего контекста }
SelectObject (dc, Pen);
Rectangle(dc,0,0,maxx_size,maxy_size);
{для нормального функционирования программы необходимо удалить все создаваемые объекты }
DeleteObject (Pen);
DeleteObject (Brush);
EndPaint (Window, MyPaint);
ReleaseDC (Window, dc);
end;
end; // case
{Все сообщения, не обрабатываемые оконной функцией, передаются функции ядра Windows DefWindowProc.}
WindowProc:= DefWindowProc (Window, Message, WParam, LParam); {DefWindowProc обеспечивает обработку тех сообщений окна, которые не обрабатывает прикладная программа.}
end;
Компиляция программы прошла успешно, после запуска программы на выполнение, появилось такое же окно, что и в прошлом задании, но с перекрашенной рабочей областью в серый цвет.
рис.3. Результат работы программы
Постройте запрос на подтверждение закрытия формы, то есть при нажатии кнопкой мыши на кнопке закрытия формы должно выводиться диалоговое окно с сообщением 'Завершить приложение?'. На окне должны быть расположены 2 кнопки: Ok – закрываем форму и Cancel – игнорируем закрытие.
Для этого необходимо добавить обработку сообщения WM_CLOSE, в результате функция обработки сообщений примет вид:
function WindowProc (Window: HWnd; Message, WParam: LongInt; LParam: LongInt): LongInt; stdcall;
Var
dc: HDC;
MyPaint: TPaintStruct;
Brush: hBrush;
Pen: hPen;
Begin
WindowProc:= 0;
Case Message of
wm_Destroy:
Begin
PostQuitMessage (0);
Exit;
end;
wm_Paint:
Begin
dc:= BeginPaint (Window, MyPaint);
Brush:= CreateSolidBrush (RGB (200, 200, 200));
Pen:= CreatePen (PS_SOLID, 1, RGB (200, 200, 200));
SelectObject (dc, Brush);
SelectObject (dc, Pen);
Rectangle(dc,0,0,maxx_size,maxy_size);
DeleteObject (Pen);
DeleteObject (Brush);
EndPaint (Window, MyPaint);
ReleaseDC (Window, dc);
end;
WM_CLOSE:
Begin
{вывод на экран запроса}
If MessageDlg('Завершить приложение?', mtConfirmation,MbOkCancel,0) <> idOK then
exit; {если Ok, то выход}
end;
end;
WindowProc:= DefWindowProc (Window, Message, WParam, LParam);
end;
Для работы MessageDlg() необходимо подключить модуль Dialogs. Теперь после попытки закрытия окна появляется запрос на подтверждение этого действия:
рис.4. Результат работы программы