Приложение WINTREE
Наше следующее приложение называется WINTREE. Оно создает два окна верхнего уровня и одно дочернее окно (рис. 2.1), демонстрируя древовидную структуру родительских отношений между окнами.
Рис. 2.1. Окна, создаваемые приложением WINTREE
Изучая это приложение, вы научитесь создавать дочерние окна, а также сможете изучить поведение таких окон, сравнив их с поведением окон верхнего уровня.
Исходный текст приложения WINTREE показан в листинге 2.1.
Листинг 2.1. Файл wintree\wintree.c
// =================================================== // Определения // ===================================================
#define INCL_WIN #define INCL_GPI #define INCL_WINDIALOGS #include <os2.h> #include <stdio.h> #include "wintree.h"
// Прототип функции окна приложения MRESULT EXPENTRY WndProc1(HWND, ULONG, MPARAM, MPARAM); MRESULT EXPENTRY WndProc2(HWND, ULONG, MPARAM, MPARAM); MRESULT EXPENTRY WndProcChild(HWND, ULONG, MPARAM, MPARAM);
// ================================================== // Глобальные переменные // ==================================================
// Идентификатор Anchor-block HAB hab;
// Идентификатор первого и второго окна Frame Window HWND hWndFrame1; HWND hWndFrame2;
// Идентификатор дочернего окна HWND hWndChildFrame;
// Идентификатор первого и второго окна Client Window HWND hWndClient1; HWND hWndClient2;
// Идентификатор окна Client Window дочернего окна HWND hWndChildClient;
// Заголовки окон CHAR szAppTitle1[] = "Windows Tree Demo 1"; CHAR szAppTitle2[] = "Windows Tree Demo 2"; CHAR szChildTitle[] = "Child Window";
// =================================================== // Главная функция приложения 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;
// Флаги для создания дочернего окна ULONG flFrameChildFlags = FCF_SYSMENU | FCF_TITLEBAR | FCF_MINMAX | FCF_SIZEBORDER;
// Имена классов для создаваемых окон CHAR szWndClass1[] = "WINTREE1"; CHAR szWndClass2[] = "WINTREE2"; CHAR szWndClassChild[] = "WINTREECHILD";
// Инициализация приложения 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, szWndClass1, (PFNWP)WndProc1, 0, 0);
if(fRc == FALSE) { WinMessageBox (HWND_DESKTOP, HWND_DESKTOP, "Ошибка при регистрации класса главного окна", "Ошибка", 0, MB_ICONHAND | MB_OK); WinDestroyMsgQueue (hmq); WinTerminate (hab);
return(-1); }
// Регистрация класса второго окна fRc = WinRegisterClass (hab, szWndClass2, (PFNWP)WndProc2, 0, 0);
if(fRc == FALSE) { WinMessageBox (HWND_DESKTOP, HWND_DESKTOP, "Ошибка при регистрации класса главного окна", "Ошибка", 0, MB_ICONHAND | MB_OK); WinDestroyMsgQueue (hmq); WinTerminate (hab);
return(-1); }
// Регистрация класса дочернего окна fRc = WinRegisterClass (hab, szWndClassChild, (PFNWP)WndProcChild, 0, 0);
if(fRc == FALSE) { WinMessageBox (HWND_DESKTOP, HWND_DESKTOP, "Ошибка при регистрации класса главного окна", "Ошибка", 0, MB_ICONHAND | MB_OK); WinDestroyMsgQueue (hmq); WinTerminate (hab);
return(-1); }
// Создаем главное окно приложения hWndFrame1 = WinCreateStdWindow (HWND_DESKTOP, WS_VISIBLE , &flFrameFlags, szWndClass1, szAppTitle1, 0, 0, ID_APP_FRAMEWND, &hWndClient1);
if(hWndFrame1 == NULLHANDLE) { WinMessageBox (HWND_DESKTOP, HWND_DESKTOP, "Ошибка при создании главного окна", "Ошибка", 0, MB_ICONHAND | MB_OK);
WinDestroyMsgQueue (hmq); WinTerminate (hab);
return(-1); }
// Создаем второе окно hWndFrame2 = WinCreateStdWindow (HWND_DESKTOP, WS_VISIBLE , &flFrameFlags, szWndClass2, szAppTitle2, 0, 0, ID_APP_FRAMEWND, &hWndClient1);
if(hWndFrame2 == NULLHANDLE) { WinMessageBox (HWND_DESKTOP, HWND_DESKTOP, "Ошибка при создании второго окна", "Ошибка", 0, MB_ICONHAND | MB_OK);
WinDestroyWindow(hWndFrame1); WinDestroyMsgQueue (hmq); WinTerminate (hab);
return(-1); }
// Создаем дочернее окно hWndChildFrame = WinCreateStdWindow (hWndFrame2, WS_VISIBLE , &flFrameChildFlags, szWndClassChild, szChildTitle, 0, 0, ID_CHILDWND, &hWndChildClient);
if(hWndChildFrame == NULLHANDLE) { WinMessageBox (HWND_DESKTOP, HWND_DESKTOP, "Ошибка при создании дочернего окна", "Ошибка", 0, MB_ICONHAND | MB_OK);
WinDestroyWindow(hWndFrame2); WinDestroyWindow(hWndFrame1); WinDestroyMsgQueue (hmq); WinTerminate (hab);
return(-1); }
// Устанавливаем начальные размеры и // расположение дочернего окна WinSetWindowPos (hWndChildFrame, HWND_TOP , 10, 10, 200, 200, SWP _ACTIVATE | SWP_SIZE | SWP_SHOW | SWP_MOVE );
// Устанавливаем пиктограмму для дочернего окна WinSendMsg (hWndChildFrame, WM_SETICON , (MPARAM)WinQuerySysPointer (HWND_DESKTOP, SPTR_APPICON, FALSE), NULL);
// Запускаем цикл обработки сообщений while(WinGetMsg (hab, &qmsg, 0, 0, 0)) WinDispatchMsg (hab, &qmsg);
// Уничтожаем главное окно приложения WinDestroyWindow(hWndFrame1);
// Удаляем очередь сообщений и вызываем // функцию WinTerminate WinDestroyMsgQueue (hmq); WinTerminate (hab);
// Возвращаем управление операционной системе return(0); }
// ================================================== // Функция главного окна приложения // ==================================================
MRESULT EXPENTRY WndProc1(HWND hWnd, ULONG msg, MPARAM mp1, MPARAM mp2) { CHAR szMsg[100];
switch (msg) { case WM_ERASEBACKGROUND : return(MRFROMLONG(1L));
case WM_BUTTON1DOWN : { sprintf (szMsg, "(x, y) = (%ld, %ld)", SHORT1FROMMP (mp1), SHORT2FROMMP (mp1));
WinMessageBox (HWND_DESKTOP, hWnd, szMsg, "Координаты курсора мыши (окно 1)", 0, MB_INFORMATION | MB_OK); }
default: return(WinDefWindowProc (hWnd, msg, mp1, mp2)); } }
// ================================================== // Функция второго окна приложения // ==================================================
MRESULT EXPENTRY WndProc2( HWND hWnd, ULONG msg, MPARAM mp1, MPARAM mp2) { CHAR szMsg[100];
switch (msg) { case WM_ERASEBACKGROUND : return(MRFROMLONG(1L));
case WM_BUTTON1DOWN : { sprintf (szMsg, "(x, y) = (%ld, %ld)", SHORT1FROMMP (mp1), SHORT2FROMMP (mp1));
WinMessageBox (HWND_DESKTOP, hWnd, szMsg, "Координаты курсора мыши (окно 2)", 0, MB_INFORMATION | MB_OK); }
default: return(WinDefWindowProc (hWnd, msg, mp1, mp2)); } }
// ================================================== // Функция дочернего окна // ==================================================
MRESULT EXPENTRY WndProcChild(HWND hWnd, ULONG msg, MPARAM mp1, MPARAM mp2) { CHAR szMsg[100];
switch (msg) { case WM_ERASEBACKGROUND : return(MRFROMLONG(1L));
case WM_BUTTON1DOWN : { sprintf (szMsg, "(x, y) = (%ld, %ld)", SHORT1FROMMP (mp1), SHORT2FROMMP (mp1));
WinMessageBox (HWND_DESKTOP, hWnd, szMsg, "Координаты курсора мыши (дочернее окно)", 0, MB_INFORMATION | MB_OK); }
default: return(WinDefWindowProc (hWnd, msg, mp1, mp2)); } }