Программирование для IBM OS/2© Александр Фролов, Григорий ФроловТом 25, М.: Диалог-МИФИ, 1993, 286 стр. 8.2. Приложение BUTTONПриложение BUTTON создает в своем главном окне две кнопки (рис. 8.1). Если пользователь нажимает на одну из них, на экране появляется сообщение с названием нажатой кнопки.
Рис. 8.1. Главное окно приложения BUTTON Исходные тексты приложения приведены в листинге 8.1. Листинг 8.1. Файл button\button.c // ================================================= // Определения // ================================================= #define INCL_WIN #define INCL_GPI #define INCL_WINDIALOGS #include <os2.h> #include "button.h" // Прототип функции окна приложения MRESULT EXPENTRY WndProc(HWND, ULONG, MPARAM, MPARAM); // ================================================= // Глобальные переменные // ================================================= HAB hab; HWND hWndFrame; HWND hWndClient; // Идентификаторы кнопок HWND hWndButton1; HWND hWndButton2; CHAR szAppTitle[] = "Button Demo"; // ================================================= // Главная функция приложения main // ================================================= int main () { HMQ hmq; QMSG qmsg; BOOL fRc; // Флаги для создания окна Frame Window ULONG flFrameFlags = FCF_SYSMENU | FCF_TITLEBAR | FCF_MINMAX | FCF_SIZEBORDER | FCF_SHELLPOSITION | FCF_TASKLIST | FCF_ICON; // Имя класса главного окна CHAR szWndClass[] = "BTNDEMO"; 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); } // Запускаем цикл обработки сообщений 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; switch (msg) { // Создаем две кнопки case WM_CREATE : { hWndButton1 = WinCreateWindow (hWnd, WC_BUTTON , "Кнопка 1", WS_VISIBLE | BS_PUSHBUTTON, 0, 0, 0, 0, hWnd, HWND_TOP , BTN1_ID, NULL, NULL); hWndButton2 = WinCreateWindow (hWnd, WC_BUTTON , "Кнопка 2", WS_VISIBLE | BS_PUSHBUTTON, 0, 0, 0, 0, hWnd, HWND_TOP , BTN2_ID, NULL, NULL); return FALSE; } // Изменяем размер и расположение кнопок case WM_SIZE : { WinSetWindowPos (hWndButton1, HWND_TOP , 10, 10, 200, 50, SWP _SIZE | SWP_MOVE | SWP_ZORDER ); WinSetWindowPos (hWndButton2, HWND_TOP , 10, 70, 200, 50, SWP _SIZE | SWP_MOVE | SWP_ZORDER ); // Перерисовываем окно приложения WinInvalidateRect (hWnd, NULL, TRUE); return 0; } case WM_PAINT : { // Получаем пространство отображения hps = WinBeginPaint (hWnd, NULLHANDLE, &rec); // Закрашиваем область, требующую обновления WinFillRect (hps, &rec, CLR_WHITE); // Возвращаем пространство отображения WinEndPaint (hps); return 0; } case WM_ERASEBACKGROUND : return(MRFROMLONG(1L)); // Это сообщение поступает в функцию окна, // когда пользователь нажимает одну из двух // кнопок case WM_COMMAND : { switch (COMMANDMSG(&msg) -> cmd) { case BTN1_ID: { WinMessageBox (HWND_DESKTOP, hWnd, "Нажата кнопка 1", "Сообщение", 0, MB_INFORMATION | MB_APPLMODAL | MB_MOVEABLE | MB_OK); break; } case BTN2_ID: { WinMessageBox (HWND_DESKTOP, hWnd, "Нажата кнопка 2", "Сообщение", 0, MB_INFORMATION | MB_APPLMODAL | MB_MOVEABLE | MB_OK); break; } default: break; } return 0; } default: return(WinDefWindowProc (hWnd, msg, mp1, mp2)); } } Глобальные переменныеВ области глобальных переменных определены переменные hWndButton1 и hWndButton2, в которых хранятся идентификаторы двух созданных приложением кнопок. Функция mainФункция main не имеет особенностей. Она создает главное окно приложений, очередь сообщений и запускает цикл обработки сообщений. Функция окна WndProcРассмотрим обработку сообщений, поступающих в функцию окна приложения BUTTON. Сообщение WM_CREATEОбработчик сообщения WM_CREATE создает две кнопки, пользуясь для этого функцией WinCreateWindow : hWndButton1 = WinCreateWindow (hWnd, WC_BUTTON , "Кнопка 1", WS_VISIBLE | BS_PUSHBUTTON, 0, 0, 0, 0, hWnd, HWND_TOP , BTN1_ID, NULL, NULL); hWndButton2 = WinCreateWindow (hWnd, WC_BUTTON , "Кнопка 2", WS_VISIBLE | BS_PUSHBUTTON, 0, 0, 0, 0, hWnd, HWND_TOP , BTN2_ID, NULL, NULL); Первая из этих кнопок имеет идентифкатор BTN1_ID, вторая - BTN2_ID. Идентификаторы окон для этих кнопок записываются, соответственно, в глобальные переменные hWndButton1 и hWndButton2. Обратите внимание, что для координат и размеров кнопок указаны нулевые значения. Реальные размеры кнопок будут установлены при обработке сообщения WM_SIZE . Обработчик сообщения WM_CREATE возвращает значение FALSE, разрешая тем самым создание главного окна приложения. Сообщение WM_SIZEОбработчик сообщения WM_SIZE изменяет расположение и размеры двух кнопок, используя для этого функцию WinSetWindowPos : WinSetWindowPos (hWndButton1, HWND_TOP , 10, 10, 200, 50, SWP _SIZE | SWP_MOVE | SWP_ZORDER ); WinSetWindowPos (hWndButton2, HWND_TOP , 10, 70, 200, 50, SWP _SIZE | SWP_MOVE | SWP_ZORDER ); После этого содержимое главного окна перерисовывается. Сообщение WM_PAINTЕдинственная задача обработчика сообщения WM_PAINT заключается в закраске внутренней области окна Client Window при изменении размеров главного окна приложения. Для закраски используется функция WinFillRect . Сообщение WM_COMMANDТак как наше приложение не имеет меню, обработчик сообщения WM_COMMAND анализирует только идентификатор кнопки, пославшей извещающее сообщение. Этот идентификатор извлекается при помощи макрокоманды COMMANDMSG. В зависимости от того, какая кнопка была нажата, обработчик сообщения WM_COMMAND выводит на экран то или иное сообщение. Обратите внимание на параметры функции WinMessageBox , с помощью которой выводится это сообщение: WinMessageBox (HWND_DESKTOP, hWnd,"Нажата кнопка 1", "Сообщение", 0, MB_INFORMATION | MB_APPLMODAL | MB_MOVEABLE | MB_OK); При вызове функции WinMessageBox мы указали флаг MB_APPLMODAL , в результате чего диалоговая панель с сообщением стала модальной в рамках приложения BUTTON. Последнее означает, что работа приложения будет продолжена только после того, как пользователь нажмет расположенную на диалоговой панели кнопку OK. Указав флаг MB_SYSTEMMODAL , можно создать так называемую системную модальную диалоговую панель . Пока пользователь не завершит работу с этой диалоговой панелью, работа системы Presentation Manager будет приостановлена. Системные модальные диалоговые панели используются, например, для отображения критичных сообщений, когда для продолжения работы системы требуется вмешательство пользователя. Файл button.hФайл button.h (листинг 8.2) содержит описание идентификатора главного окна приложения ID_APP_FRAMEWND, а также идентификаторов двух кнопок BTN1_ID и BTN2_ID. Листинг 8.2. Файл button\button.h #define ID_APP_FRAMEWND 1 #define BTN1_ID 100 #define BTN2_ID 101 Файл button.rcВ файле button.rc (листинг 8.3) описана пиктограмма приложения BUTTON. Листинг 8.3. Файл button\button.rc #include <os2.h> #include "button.h" ICON ID_APP_FRAMEWND BUTTON.ICO Файл button.defФайл определения модуля button.def приложения BUTTON приведен в листинге 8.4. Листинг 8.4. Файл button\button.def NAME BUTTON WINDOWAPI DESCRIPTION 'Button Application (C) Frolov A., 1996' HEAPSIZE 4096 STACKSIZE 32768 EXPORTS WndProc |