Приложение CHECK
Для демонстрации техники работы с переключателями мы подготовили исходные тексты приложения CHECK. В своем главном окне (рис. 8.3) это приложение создает кнопку и два переключателя. Первый из этих переключателей обычный, а второй - автоматический.
Рис. 8.3. Главное окно приложения CHECK
При помощи мыши вы можете изменять состояние переключателей с номерами 2 и 3 (первый номер присвоен кнопке с надписью "Переключатели"). Второй переключатель - автоматический и имеет стиль BS_AUTOCHECKBOX, третий - обычный со стилем BS_CHECKBOX.
Если после установки состояния переключателей нажать кнопку, расположенную в нижней части окна приложения, на экране появится диалоговая панель, отображающая текущее состояние переключателей. Эта панель показана на рис. 8.2.
Исходные тексты приложения CHECK приведены в листинге 8.5.
Листинг 8.5. Файл check\check.c
// ================================================= // Определения // =================================================
#define INCL_WIN #define INCL_GPI #define INCL_WINDIALOGS #include <os2.h> #include <stdio.h> #include "check.h"
// Прототип функции окна приложения MRESULT EXPENTRY WndProc(HWND, ULONG, MPARAM, MPARAM);
// ================================================= // Глобальные переменные // =================================================
HAB hab; HWND hWndFrame; HWND hWndClient;
// Идентификаторы кнопок HWND hWndButton1; HWND hWndButton2; HWND hWndButton3;
// Состояние переключателей BOOL fButton2Checked = FALSE; BOOL fButton3Checked = FALSE;
CHAR szAppTitle[] = "CheckBox 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; CHAR szBuf[256];
switch (msg) { // Создаем кнопку и два переключателя case WM_CREATE : { hWndButton1 = WinCreateWindow (hWnd, WC_BUTTON , "Переключатели", WS_VISIBLE | BS_PUSHBUTTON, 0, 0, 0, 0, hWnd, HWND_TOP , BTN1_ID, NULL, NULL);
// Автоматический переключатель hWndButton2 = WinCreateWindow (hWnd, WC_BUTTON , "(2) AutoCheckBox", WS_VISIBLE | BS_AUTOCHECKBOX, 0, 0, 0, 0, hWnd, HWND_TOP , BTN2_ID, NULL, NULL);
// Обычный переключатель hWndButton3 = WinCreateWindow (hWnd, WC_BUTTON , "(3) CheckBox", WS_VISIBLE | BS_CHECKBOX, 0, 0, 0, 0, hWnd, HWND_TOP , BTN3_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 );
WinSetWindowPos (hWndButton3, HWND_TOP , 10, 110, 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_CONTROL : { switch (SHORT1FROMMP (mp1)) { // Если сообщение пришло от автоматического // переключателя, получаем и сохраняем его // текущее состояние case BTN2_ID: { fButton2Checked = (BOOL) WinSendMsg (hWndButton2, BM_QUERYCHECK, MPFROMSHORT(0), NULL); break; }
// Если сообщение пришло от обычного // переключателя, изменяем его состояние // и сохраняем новое состояние // в переменной fButton3Checked case BTN3_ID: { if(fButton3Checked) WinSendMsg (hWndButton3, BM_SETCHECK, MPFROMSHORT(0), NULL);
else WinSendMsg (hWndButton3, BM_SETCHECK, MPFROMSHORT(1), NULL);
fButton3Checked = ~fButton3Checked; break; }
default: break; } return 0; }
// Когда пользователь нажимает кнопку, // определяем и сохраняем состояние // обоих переключателей case WM_COMMAND : { switch (COMMANDMSG(&msg) -> cmd) { case BTN1_ID: { sprintf (szBuf, "Состояние переключаталей:\n" "(3) третий - %d\n(2) второй - %d", fButton3Checked ? 1 : 0, fButton2Checked ? 1 : 0);
WinMessageBox (HWND_DESKTOP, hWnd, szBuf, "Состояние переключателей", 0, MB_INFORMATION | MB_APPLMODAL | MB_MOVEABLE | MB_OK); break; }
default: break; } return 0; }
default: return(WinDefWindowProc (hWnd, msg, mp1, mp2)); } }