Как правило, программы, написанные для Windows, используют окна для организации пользовательского интерфейса. Из этого правила могут быть исключения, но в подавляющем большинстве случаев программисту приходится работать с окнами.
Основой оконного графического пользовательского интерфейса Windows является механизм сообщений. Сообщения могут передаваться оконной процедуре немедленно, а могут помещаться в очередь сообщений.
При запуске вашего приложения, Windows создаёт для него очередь сообщений. Очередь сообщений создаётся для каждого потока (thread), но в самом простейшем случае создаётся одна очередь.
При любом действии с окном (изменение размеров и т.д.) Windows помещает в очередь соответствующее сообщение. Формат сообщения соответствует структуре MSG.
typedef
struct tagMSG |
hwnd - хэндл окна получателя сообщения;
message - код сообщения;
wParam - дополнительный параметр сообщения;
lParam - дополнительный параметр сообщения;
time - время отправки сообщения;
pt - координаты курсора мыши в момент отправки сообщения.
Хэндл окна - число идентифицирующее окно. У каждого окна в Windows есть свой хэндл. Практически во всех функциях API требуется указывать хэндл окна.
Сообщения помещаемые в очередь сообщений необходимо правильно извлекать и обрабатывать. Для этого нужно построить цикл обработки сообщений.
MSG msg; |
Рассмотрим функцию GetMessage():
BOOL
GetMessage( |
Функция GetMessage() извлекает сообщение из очереди сообщений и помещает его в структуру lpMsg типа MSG. Если сообщений в очереди нет, то текущий поток переводится в состояние ожидания и досрочно отдает управление другим потокам.
Возвращаемое значение:
Если функция извлекает сообщение отличное от WM_QUIT, то функция
возвращает ненулевое значение.
Если функция извлекает сообщение WM_QUIT, то она возвращает 0.
Если произошла ошибка, то функция возвращает -1.
lpMsg - указатель на структуру куда будет помещено сообщение;
hWnd - хэндл окна для которого извлекается сообщение, если указать 0, то функция GetMessage() будет извлекать сообщения для всех окон;
wMsgFilterMin - нижняя граница диапазона извлечения, например, если указать 10, то будут извлекаться сообщения с кодами сообщений начиная с 10, если указать ноль, то граница отсутствует;
wMsgFilterMax - верхняя граница диапазона извлечения, например, если указать 300, то будут извлекаться сообщения с кодами сообщений до 300, если указать ноль, то граница отсутствует.
Рассмотрим функцию TranslateMessage():
BOOL TranslateMessage(CONST MSG *lpMsg); |
Функция TranslateMessage() транслирует сообщения от клавиатуры. Она переводит сообщения виртуальных клавиш (Virtual-key) в символьные сообщения.
Рассмотрим функцию DispatchMessage():
LONG DispatchMessage(CONST MSG *lpmsg); |
Функция DispatchMessage() отправляет сообщение в оконную процедуру. По сути эта функция и вызывает оконную процедуру.
Оконная процедура - функция обработки событий (сообщений). Она вызывается самой операционной системой Windows и получает ряд параметров: хэндл окна - hWnd, код сообщения - msg и два параметра lParam и wParam. Оконная процедура может иметь любое имя. В нашей программе мы назовём её WndProc.
/* Прототип */
LRESULT CALLBACK WndProc(
HWND hWnd,
UINT msg,
WPARAM wParam,
LPARAM lParam
);
Оконная процедура должна уметь обрабатывать все сообщения, но в
Windows таких сообщений десятки тысяч. Всё сводиться к тому, что ваша оконная
процедура будет обрабатывать только необходимые для вас сообщения, а всё
остальные сообщения будет обрабатывать оконная процедура по умолчанию -
DefWindowProc();
/* Пример оконной процедуры */ LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM
wParam, LPARAM lParam) |
Эта оконная процедура обрабатывает только одно сообщение -
WM_DESTROY, все остальные сообщения обрабатывает оконная процедура по умолчанию.
Замечание. Сообщение WM_DESTROY посылается окну, когда пользователь
пытается закрыть окно.
Оконная процедура обрабатывает сообщения для окон определённого класса.
Оконный класс - класс, на основе которого создаются окна. На базе одного оконного класса можно создать несколько окон. В ОС Windows есть предопределённые классы окон, такие как: кнопки, раскрывающиеся списки, полоски прокрутки и т.д. Для того чтобы создавать окна на основе вашего класса, последний должен быть зарегистрирован в системе функцией RegisterClass() или RegisterClassEx().
Для того чтобы использовать ваш собственный класс окон, вам необходимо заполнить структуру WNDCLASSEX.
typedef
struct _WNDCLASSEX { |
cbSize - размер структуры WNDCLASSEX;
style - битовые флаги, определяющие стиль окна;
lpfnWndProc - адрес оконной процедуры;
cbClsExtra - размер дополнительной памяти класса;
cbWndExtra - размер дополнительной памяти окна;
hInstance - хэндл экземпляра приложения, которому принадлежит оконная процедура;
hIcon - хэндл значка (32x32 пикселя);
hCursor - хэндл курсора окна по умолчанию;
hbrBackground - хэндл кисти окна по умолчанию или цвет фона;
lpszMenuName - оконное меню (имя ресурса);
lpszClassName - имя класса;
hIconSm - хэндл маленького значка (16x16 пикселей).
После заполнения структуры WNDCLASSEX, класс необходимо зарегистрировать в системе. Это делается с помощью функции RegisterClassEx();
WNDCLASSEX wc;
// Заполняем структуру WNDCLASS
// ....
// Регистрируем новый класс
RegisterClassEx(&wc);
Теперь, когда наш класс зарегистрирован в системе, мы можем создавать окна нашего класса.
Создание окна производиться с помощью функции CreateWindow() или CreateWindowEx().
В случае успеха функция CreateWindow() возвращает хэндл нового созданного окна, иначе функция возвращает NULL.
HWND
CreateWindow( |
lpClassName - имя зарегистрированного класса окна;
lpWindowName - заголовок окна;
dwStyle - стиль окна (комбинация флагов);
x - начальное положение по X;
y - начальное положение по Y;
nWidth - ширина окна;
nHeight - высота окна;
hWndParent - хэндл окна родителя;
hMenu - хэндл меню окна;
hInstance - хэндл экземпляра приложения, создающий окно;
lpParam - указатель на параметры для WM_CREATE.
После создания окна его необходимо отобразить на экране. Чтобы окно было показано на экране необходимо вызвать функцию ShowWindow().
ShowWindow(hWnd, SW_SHOW);
/* |
Исходник к статье (Шаблон программы под Windows). Visual C 6.0.
Бардин Павел, http://proger.h10.ru
|
Программирование для чайников.
|