Программирование для IBM OS2

         

Приложение CLOCK


В приложении CLOCK, которое представляет собой цифровые часы, мы показываем текущее время. Показания часов обновляются раз в секунду, для чего используется сообщение WM_TIMER .

Окно нашего приложения не имеет рамки и сразу после запуска приложения появляется в левом нижнем углу экрана. С помощью левой клавиши мыши вы можете перенести это окно в любое удобное для вас место экрана (рис. 7.1).

Рис. 7.1. Окно приложения CLOCK на поверхности рабочего стола

Исходный текст приложения CLOCK представлен в листинге 7.5.

Листинг 7.5. Файл clock\clock.c

// ================================================= // Определения // =================================================

#define INCL_WIN #define INCL_GPI #define INCL_WINDIALOGS #include <os2.h> #include <string.h> #include <stdio.h> #include "clock.h"

// Прототип функции окна приложения MRESULT EXPENTRY WndProc(HWND, ULONG, MPARAM, MPARAM);

// ================================================= // Глобальные переменные // =================================================

HAB hab; HWND hWndFrame; HWND hWndClient;

CHAR szAppTitle[] = "Clock Application";

// Координаты курсора мыши в момент нажатия // левой клавиши мыши SHORT cxPoint; SHORT cyPoint;

// Координаты курсора мыши в момент отпускания // левой клавиши мыши SHORT cxNewPoint; SHORT cyNewPoint;

// Признак начала процесса перемещения окна BOOL fDrag = FALSE;

// Идентификаторы указателей мыши HPOINTER hptr, hptr1;



// Размеры символов выбранного шрифта SHORT cxChar, cyChar, cyDesc;

// ================================================= // Главная функция приложения main // =================================================

int main () { HMQ hmq; QMSG qmsg; BOOL fRc; FONTMETRICS fm; HPS hps;

// Флаги для создания окна Frame Window . // Окно не имеет орагнов управления и // рамки для изменения размеров ULONG flFrameFlags = FCF_TASKLIST | FCF_ICON;

// Имя класса главного окна CHAR szWndClass[] = "TIMERBEEP";

hab = WinInitialize (0); if(hab == NULLHANDLE) { WinMessageBox (HWND_DESKTOP, HWND_DESKTOP, "Ошибка инициализации", "Ошибка", 0, MB_ICONHAND | MB_OK); return(-1); }


// Создаем очередь сообщений hmq = WinCreateMsgQueue (hab, 0); if(hmq == NULLHANDLE) { WinMessageBox (HWND_DESKTOP, HWND_DESKTOP, "Ошибка при создании очереди сообщений", "Ошибка", 0, MB_ICONHAND | MB_OK); WinTerminate (hab); return(-1); }

// Регистрация главного окна приложения fRc = WinRegisterClass (hab, szWndClass, (PFNWP)WndProc, 0, 0); if(fRc == FALSE) { WinMessageBox (HWND_DESKTOP, HWND_DESKTOP, "Ошибка при регистрации класса главного окна", "Ошибка", 0, MB_ICONHAND | MB_OK); WinDestroyMsgQueue (hmq); WinTerminate (hab);

return(-1); }

// Создаем главное окно приложения hWndFrame = WinCreateStdWindow (HWND_DESKTOP, WS_VISIBLE , &flFrameFlags, szWndClass, szAppTitle, 0, 0, ID_APP_FRAMEWND, &hWndClient); if(hWndFrame == NULLHANDLE) { WinMessageBox (HWND_DESKTOP, HWND_DESKTOP, "Ошибка при создании главного окна", "Ошибка", 0, MB_ICONHAND | MB_OK); WinDestroyMsgQueue (hmq); WinTerminate (hab);

return(-1); }

// Получаем пространство отображения hps = WinGetPS (hWndFrame);

// Выбираем в пространство отображения шрифт // с фиксированной шириной символов SetCourierFont(hps);

// Определяем метрики шрифта GpiQueryFontMetrics(hps, (LONG)sizeof(fm), &fm);

cxChar = fm.lAveCharWidth; cyChar = fm.lMaxBaselineExt; cyDesc = fm.lMaxDescender;

// Устанавливаем шрифт, выбранный в пространство // отображения по умолчанию ResetFont(hps);

// Возвращаем пространство отображения WinReleasePS (hps);

// Устанавливаем новые размеры и расположение // главного окна приложения WinSetWindowPos (hWndFrame, HWND_TOP , 0, 0, 10 * cxChar, cyChar + cyDesc, SWP _SIZE | SWP_MOVE | SWP_ZORDER );

// Запускаем цикл обработки сообщений while(WinGetMsg (hab, &qmsg, 0, 0, 0)) WinDispatchMsg (hab, &qmsg);

WinDestroyWindow(hWndFrame); WinDestroyMsgQueue (hmq); WinTerminate (hab); return(0); }

// ================================================= // Функция главного окна приложения // =================================================



MRESULT EXPENTRY WndProc( HWND hWnd, ULONG msg, MPARAM mp1, MPARAM mp2) { HPS hps; RECTL rec; SWP swp; CHAR pszBuf[256]; DATETIME dt;

switch (msg) { case WM_CREATE : { // Запускаем таймер с интервалом 1000 мс WinStartTimer (hab, hWnd, ID_APP_TIMER, 1000);

// Загружаем идентификаторы курсоров мыши hptr = WinLoadPointer(HWND_DESKTOP, NULLHANDLE, ID_APP_POINTER);

hptr1 = WinLoadPointer(HWND_DESKTOP, NULLHANDLE, ID_APP_POINTER1);

return FALSE; }

case WM_DESTROY : { // Останавливаем таймер WinStopTimer (hab, hWnd, ID_APP_TIMER);

// Удаляем курсоры мыши WinDestroyPointer (hptr); WinDestroyPointer (hptr1); return 0; }

// Когда приходит сообщение от таймера, // перерисовываем главное окно приложения case WM_TIMER : { WinInvalidateRect (hWnd, NULL, TRUE); return 0; }

case WM_PAINT : { // Получаем пространство отображения hps = WinBeginPaint (hWnd, NULLHANDLE, &rec);

// Определяем размеры главного окна WinQueryWindow Rect(hWnd, &rec);

// Определяем дату и время DosGetDateTime(&dt);

sprintf (pszBuf, "%02d:%02d:%02d", dt.hours, dt.minutes, dt.seconds);

// Устанавливаем шрифт для отображения SetCourierFont(hps);

// Выводим текст в центре окна WinDrawText (hps, -1, pszBuf, &rec, 0L, 0L, DT_WORDBREAK | DT_CENTER | DT_VCENTER | DT_TEXTATTRS | DT_ERASERECT);

// Восстанавливаем шрифт ResetFont(hps);

// Освобождаем пространство отображения WinEndPaint (hps); return 0; }

case WM_ERASEBACKGROUND : return(MRFROMLONG(1L));

// Когда пользователь нажимает левую клавишу // мыши, запоминаем координаты курсора и // выдвигаем окно приложения на передний план case WM_BUTTON1DOWN : { cxPoint = MOUSEMSG(&msg) -> x; cyPoint = MOUSEMSG(&msg) -> y;

// Изменяем расположение окна по оси Z WinSetWindowPos (hWndFrame, HWND_TOP , 0, 0, 0, 0, SWP _ZORDER );

// Устанавливаем признак перемещения // главного окна приложения fDrag = TRUE;

// Захватываем мышь WinSetCapture (HWND_DESKTOP, hWnd); return 0; }

// При отпускании левой клавиши мыши сбрасываем // признак перемещения окна case WM_BUTTON1UP : { // Сбрасываем признак перемещения // главного окна приложения fDrag = FALSE;



// Освобождаем мышь WinSetCapture (HWND_DESKTOP, NULLHANDLE); return 0; }

// Это сообщение приходит при перемещении курсора // мыши case WM_MOUSEMOVE : { // Если включен признак перемещения, определяем // новые координаты курсора и передвигаем окно if(fDrag) { // Выбираем указатель в виде закрытой руки WinSetPointer (HWND_DESKTOP, hptr1);

cxNewPoint = MOUSEMSG(&msg) -> x; cyNewPoint = MOUSEMSG(&msg) -> y;

// Определяем текущие координаты окна WinQueryWindow Pos(hWndFrame, &swp);

// Передвигаем окно WinSetWindowPos (hWndFrame, HWND_TOP , swp.x + (cxNewPoint - cxPoint), swp.y + (cyNewPoint - cyPoint), 0, 0, SWP _MOVE ); }

else // Выбираем указатель в виде открытой руки WinSetPointer (HWND_DESKTOP, hptr);

return (MRESULT)TRUE; }

// Если пользователь сделал двойной щелчок левой // клавише мыши, завершаем работу приложения case WM_BUTTON1DBLCLK : { WinPostMsg (hWnd, WM_QUIT , 0L, 0L); return 0; }

default: return(WinDefWindowProc (hWnd, msg, mp1, mp2)); } }

// ================================================= // Выбор шрифта с фиксированной шириной символов // =================================================

void SetCourierFont(HPS hps) { FATTRS fat;

// Заполняем структуру описанием нужного // нам шрифта fat.usRecordLength = sizeof(FATTRS); strcpy(fat.szFacename ,"Courier"); fat.fsSelection = 0; fat.lMatch = 0L; fat.idRegistry = 0; fat.usCodePage = 850; fat.lMaxBaselineExt = 12L; fat.lAveCharWidth = 12L; fat.fsType = 0; fat.fsFontUse = FATTR_FONTUSE_NOMIX;

// Создаем логический шрифт, имеющий идентификатор 1L GpiCreateLogFont(hps, NULL, 1L, &fat);

// Выбираем созданный шрифт в пространство отображения GpiSetCharSet (hps, 1L); }

// ================================================= // Установка шрифта, выбранного в пространство // отображения по умолчанию // ================================================= void ResetFont(HPS hps) { GpiSetCharSet (hps, LCID_DEFAULT); GpiDeleteSetId(hps, 1L); }


Содержание раздела