- •Лекции 2- 3
- •Библиотека Win32
- •Структура окна
- •В библиотеке Win32 API содержится описание довольно большого количества типов данных, большинство из
- •Библиотека Win32
- •Архитектура,
- •Сообщение - это структура данных, содержащая следующие элементы:
- •Сообщения от внешних источников, например от клавиатуры, адресуются в каждый конкретный момент времени
- •Каркас Win32
- •Параметры функции WinMain:
- •НАЧАЛО
- •Для описания класса окна необходимо заполнить структуру типа WNDCLASSEX или WNDCLASS (старый вариант).
- •После заполнения всех полей данной структуры класса окна необходимо зарегистрировать с помощью функции
- •После успешной регистрации класса окна необходимо создать само окно. Это осуществляется с помощью
- •В случае успешного выполнения функция CreateWindow возвращает дескриптор созданного окна. В случае ошибки
- •После того, как окно успешно создано, его необходимо отобразить используя функции ShowWindow и
- •После создания и отображения окна необходимо организовать цикл получения и обработки сообщений. Для
- •Функция получения сообщения BOOL GetMessage(
- •Функция преобразования сообщения виртуальных клавиш в символьные сообщения
- •Функция обработки сообщения
- •Типовая функция
- •Функция-обработчик
- •Типовой алгоритм
- •Дополнительные
- •Функция перемещения окна
- •Вывод окна на передний план и передача ему управления:
- •Функция получения параметров окна:
- •Окно сообщения
- •Флаг
- •MB_APPLMODAL
- •Пример
- •Начало программы: подключения библиотек, объявление глобальных переменных и
- •Функция регистрации класса родительского окна
- •Функция регистрации класса дочернего окна
- •Функция WinMain
- •Функция обработки сообщений
- •Функция обработки сообщений дочернего окна
- •Передача
- •Пример
- •Текст программы
- •Некоторые функции приема или передачи сообщения
- •Функция передачи данных параметра сообщения (wParam и
- •Функция обработки сообщений по умолчанию. LRESULT DefWindowProc(
- •Функция завершения сеанса работы пользователя: BOOL ExitWindows(DWORD dwReserved, UINT uReserved);
- •Функция получения позиций курсора последнего выбранного сообщения:
- •Функция проверки наличия сообщения в очереди сообщений: BOOL GetMessage(
- •Функция передачи сообщения завершения приложения:
- •Следующая
MB_APPLMODAL |
Окно hwnd переводится в неактивное |
|
состояние на время работы окна |
|
сообщения |
MB_SYSTEMMODAL |
На время работы окна сообщения все |
|
другие приложения в неактивном |
|
состоянии |
MB_TASKMODAL |
На время работы окна сообщения |
|
текущее приложение в неактивном |
|
состоянии. Если hwnd=NULL, то все |
|
перекрывающие окна |
MB_HELP |
Добавляет кнопку «Справка» |
MB_RIGHT |
Текст выравнивается по правому краю |
MB_RTLREADING |
Отображает символы сообщения и текст |
|
заголовка в направлении справа налево |
MB_SETFOREGROUND |
Окно сообщения выдвигается на |
|
передний план |
Пример
Разработать программу, в которой создается родительское окно, изначально развернутое на весь экран. При нажатии левой кнопки мыши над рабочей областью окна создается новое дочернее окно, расположенное по координатам курсора мыши.
Дочернее окно должно автоматически закрываться через 10 секунд с момента его создания. В заголовке окна должно выводится его название и порядковый номер.
Программа не должна позволять создавать одновременно более 10 дочерних окон. Если пользователь попытается это выполнить, то программа должна вывести сообщение о невозможности создания дочернего окна.
Начало программы: подключения библиотек, объявление глобальных переменных и
прототипов функций
#include <windows.h> #include <stdlib.h> #include <stdio.h>
int RegisterParentWindowClass(void); int RegisterChildWindowClass(void);
LRESULT CALLBACK ParentWndProc(HWND, UINT, WPARAM, LPARAM); LRESULT CALLBACK ChildWndProc(HWND, UINT, WPARAM, LPARAM);
char ParentClassName[] = "ParentWindowClass"; char ChildClassName[] = "ChildWindowClass"; HINSTANCE _hInstance;
HWND hwnd_main;
int ChildWindowNum = 0; int ChildWindowCount = 0;
Функция регистрации класса родительского окна
int RegisterParentWindowClass(void)
{
WNDCLASS wc; memset(&wc,0,sizeof(WNDCLASS)); wc.style = CS_VREDRAW | CS_HREDRAW; wc.lpfnWndProc = ParentWndProc; wc.hInstance = _hInstance;
wc.hIcon = LoadIcon(NULL,IDI_APPLICATION); wc.hCursor = LoadCursor(NULL,IDC_ARROW); wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1); wc.lpszMenuName = (LPSTR)NULL; wc.lpszClassName = (LPSTR)ParentClassName;
return RegisterClass(&wc);
}
Функция регистрации класса дочернего окна
int RegisterChildWindowClass(void)
{
WNDCLASS wc; memset(&wc,0,sizeof(WNDCLASS)); wc.style = CS_VREDRAW | CS_HREDRAW; wc.lpfnWndProc = ChildWndProc; wc.hInstance = _hInstance;
wc.hIcon = LoadIcon(NULL,IDI_APPLICATION); wc.hCursor = LoadCursor(NULL,IDC_CROSS); wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1); wc.lpszMenuName = (LPSTR)NULL; wc.lpszClassName = ChildClassName;
return RegisterClass(&wc);
}
Функция WinMain
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd)
{
_hInstance = hInstance; if(!RegisterParentWindowClass()) return -1; if(!RegisterChildWindowClass()) return -1;
hwnd_main = CreateWindow(ParentClassName,(LPSTR)"Main window", WS_OVERLAPPED | WS_SYSMENU, 0,0,500,500,NULL,NULL,hInstance,0);
if(!hwnd_main) return 0; ShowWindow(hwnd_main,SW_SHOWMAXIMIZED); UpdateWindow(hwnd_main);
MSG msg; while(GetMessage(&msg,0,0,0)){ TranslateMessage(&msg); DispatchMessage(&msg);
}
return 0;
}
Функция обработки сообщений
родительского окна
LRESULT CALLBACK ParentWndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
HWND hwnd_child; int x, y; char windowname[21]; switch(message){
case WM_DESTROY: PostQuitMessage(0); break;
case WM_LBUTTONDOWN: if(ChildWindowCount>=10){
MessageBox (hwnd,"Достигнуто максимальное количество дочерних окон!", "Сообщение", MB_OK);
break;
}
y = HIWORD(lParam); x = LOWORD(lParam); sprintf(windowname,"Child window %d",++ChildWindowNum);
hwnd_child = CreateWindow(ChildClassName, windowname, WS_CHILD | WS_CAPTION,
x, y, 100, 100, hwnd_main, NULL, _hInstance,0); if(hwnd_child){ ShowWindow(hwnd_child,SW_SHOW);
UpdateWindow(hwnd_child); }
break;
default: return DefWindowProc(hwnd,message,wParam,lParam);
}
return 0;
}
Функция обработки сообщений дочернего окна
LRESULT CALLBACK ChildWndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch(message){ case WM_CREATE:
ChildWindowCount++;
SetTimer(hwnd,0,10000,NULL);
break;
case WM_TIMER: ChildWindowCount--; DestroyWindow(hwnd);
break;
default: return DefWindowProc(hwnd,message,wParam,lParam);
}
return 0;
}
Передача
Приложения (илисообщенийтдельные окна) могут передавать друг другу сообщения. Для реализации этой возможности спользуются функции: PostMessage и SendMessage.
Прототипы функций:
BOOL PostMessage(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
BOOL SendMessage(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
Параметры:
hWnd – дескриптор окна, которому отсылается сообщение
uMsg – идентификатор сообщения
wParam – значение первого параметра этого сообщения
lParam – значение второго параметра этого сообщения
Отличие PostMessage от SendMessage заключается в том, что функция SendMessage «дожидается» завершения обработки сообщения приемником.
Пример
Реализовать программу, которая определяет: запущено ли приложение предыдущего примера.
Если приложение не запущено, то программа выводит сообщение: «Приложение не запущено» и завершает работу.
Если приложение запущено, то программа предлагает закрыть его и, при утвердительном ответе пользователя, закрывает его.