- •Часть IV
- •Глава 25
- •224 Глава 25
- •226 Глава 25
- •Глава 26
- •230 ____Глава 26
- •232 Глава 26
- •234 Глава 26
- •236 Глава 26
- •238 Глава 26
- •240 Глава 26
- •242 Глава 26
- •Глава 27
- •Virtual void InitMainWindow();//Замещаем функцию InitMainWindow
- •246 Глава 27
- •248 Глава 27
- •250 Глава 27
- •252 . Глава27
- •Глава 28 Диалоговые окна
- •256 Глава 28
- •258 Глава 28
- •260 Глава 28
- •262 Глава 28
- •264 Глава 28
- •266 Глава 28
- •268 Глава 28
- •Глава 29
- •270 Глава 29
- •272 Глава 29
- •274 Глава 29
- •276 Глава 29
- •278 Глава 29
- •280 Глава 29
- •282 Глава 29
Глава 27
Обработка сообщений Windows
Исходный текст программы календаря-часов
На рис. 27.1. приведен результат работы приложения 27-1.
//Приложение 27-1. Обработка сообщений Windows
//Файл 27-1.срр
#include <owl\framewin.h>
#include <time.h>
/*Класс приложения, производный от Tapplication*/
class MyApp:public TApplication{
public:
Virtual void InitMainWindow();//Замещаем функцию InitMainWindow
};
//Класс главного окна, производный от TFrameWindow class MyWindow:public TFrameWindow{ private:
char szText[27];//Поле для даты, пробелов слева и справа и завершающего public:
MyWindow(TWindow*,const char far*);//Конструктор класса MyWindow
void Paint(TDC&,bool,TRect&);//Переопределяем функцию Paint
void EvGetMinMaxInfо(MINMAXINFO far&);//Объявляем функции обработки
void EvTimer(UINT);//сообщений WM_MINMAXINFO, HM_TIMER
int EvCreate(CREATESTRUCT far&);//и WM_CREATE
void OutTime();//Прикладная функция получения времени
~MyWindow();//Деструктор класса MyWindow
DECLARE_RESPONSE_TABLE(MyWindow);//Объявляем таблицу откликов
}; DEFINE_RESPONSE_TABLE1(MyWindow,TFrameWindow) //Начинаем таблицу откликов
EV_CREATE //Описываем состав
EV_WM_GETMINMAXINFO, //таблицы
EV_WM_TIMER, //откликов
END_RESPONSE_TABLE; //Завершаем таблицу откликов
/*Конструктор класса MyWindow*/ MyWindow::MyWindow(TWindow*parent,const char far* title):
TframeWindow(parent,title){
Attr.X=0;Attr.Y=0;//Задаем координаты окна
Attr.W=0;Attr.H=0;//Задаем начальные размеры окна
Attr.ExStyle=WS_EX_TOPMOST;//Назначаем главное окно окном переднего плана
} /*Деструктор класса MyWindow*/
MyWindow::~MyWindow(){
Обработка сообщений Windows 245
KillTimer(1); } /*Функции откликов на сообщения*/
int MyWindow::EvCreate(CREATESTRUCT far&){
SetTimerd,1000) ;//Устанавливаем таймер на частоту 1с
OutTime() ; //Сразу же выводим в окно текущее время
return 0;
} void MyWindow::EvGetMinMaxInfо(MINMAXINFO far & mmi){
mmi.ptMinTrackSize.x=185; mmi.ptMinTrackSize.y=45; mmi.ptMaxTrackSize.x=185;
mmi.ptMaxTrackSize.y=45;
} void MyWindow::EvTimer(UINT){
OutTime();
}
/*Функция OutTime() чтения и преобразования текущего времени*/ void MyWindow::OutTime (){
tm* tmTime;//Указатель на структуру для хранения времени
time_t sec=time(NULL);//Получение числа секунд от 01.01.1970
tmTime=localtime(&sec);//Преобразование в формат даты/времени
strcpy(szText," ");//Один пробел в начале для красоты
strcat(szText,asctime(tmTime));//Преобразование в коды ASCII
szText[strlen(szText)-1]='\0';//Замена завершающего CR на нуль
Invalidate();//Инициирование перерисовки рабочей области окна
}
/*3амещающая функция Paint()*/ void MyWindow::Paint(TDC&dc,bool,TRect&){
dc.TextOut(0,0,szText);
}
/*3амещакщая функция InitMainWindow() */ void MyApp::InitMainWindow(){
MyWindow* myWin=new MyWindow(0,"Текущее время");
SetMainWindow(myWin);
}
/*Главная функция приложения OwlMain*/ int OwlMain(int,char*[]){
MyApp* myApp=new MyApp;
return myApp->Run();
}
Таблица откликов и функции обработки сообщений
В предыдущей главе уже отмечалось, что для обработки сообщения WM_PAINT, имеющего особую важность, в OWL предусмотрена упрощенная процедура, заключающаяся в предоставлении программисту функции-заглушки Paint(), которую можно заместить прикладной функцией с тем же именем. В замещающей функции Paint() оказывается доступен контекст устройства dc, что дает возможность использовать для вывода в окно приложения весь богатый набор функций GDI.
Для обработки других сообщений Windows (от мыши, пунктов меню, таймера и т.д.) в программе необходимо предусмотреть следующие элементы:
Объявление в классе главного окна таблицы откликов (макрос DECLARE_RESPONSE_TABLE)
Саму таблицу откликов (макросы DEFINE_RESPONSE_TABLE1 и END_RESPONSE_TABLE, a также помещаемые между ними макросы, определяющие конкретные сообщения)
Набор функций, обрабатывающих по заданным алгоритмам описанные в таблице откликов сооб щения Windows
Таблица откликов объявляется, как элемент класса главного окна с помощью макроса DECLARE_RESPONSE_TABLE, с именем нашего конкретного класса в качестве параметра. При расши рении этого макроса в класс главного окна включается объявление указателя entries[] на массив струк турных пакетов данных, используемых для вызова конкретных функций отклика, а также прототип слу жебной функции Find(), с помощью которой осуществляется нахождение в таблице откликов элемента, соответствующего пришедшему сообщению. Расширение указанного макроса содержится в заголовоч ном файле include\owl\eventhan.h, который наряду со многими другими файлами .h автоматически под ключается к компилируемому файлу приложения при выполнении директивы #include framewin.h. По скольку в расширении макроса присутствуют "собственные" спецификаторы доступа (private и public), его можно располагать в любой секции класса, однако после этого макроса необходимо соответствую-