Процедура окна

Каждое окно имеет соответствующую оконную процедуру - процедуру, которая обрабатывает все сообщения, посланные всем окнам класса. Все аспекты использования окна и его поведения, зависят от того, как реагирует оконная процедура на соответствующие сообщения.

Каждое окно является членом частного класса окон. Класс окна определяет оконную процедуру по умолчанию, которую каждое окно использует для обработки сообщений. Все окна, принадлежащие одному и тому же классу, используют одну и ту же оконную процедуру по умолчанию.

Приложение обычно регистрирует как минимум один новый класс окна и соответствующую ему оконную процедуру. После регистрации класса, приложение может создать много окон этого класса, каждое из которых будет использовать ту же самую оконную процедуру. Поскольку это означает, что несколько источников могут одновременно вызывать один и тот же кусок кода, необходимо с осторожностью подходить к изменению общих ресурсов из оконной процедуры.

Оконная процедура имеет 4 параметра и возвращает число со знаком. Входные параметры состоят из дескриптора окна, идентификатора сообщения и двух параметров сообщения (все те параметры, что и входят в состав структуры MSG, см. таблицу 3, за исключением времени создания сообщения и позиции курсора).

Интерпретация возвращаемого значения зависит от обрабатываемого сообщения, в описании каждого сообщения есть определение возвращаемых значений.

Поскольку возможно рекурсивное вызывание оконной процедуры, важно минимизировать количество локальных переменных, используемых в этих оконных процедурах. При обработке сообщений, приложение должно вызвать внешнюю (по отношению к оконной процедуре) функцию во избежание излишнего использования локальных переменных, которое может вызвать переполнение стека из-за нескольких последовательных рекурсий.

Оконная процедура по молчанию (обычно она называется DefWindowProc) определяет поведение всех окон. Оконная процедура по умолчанию обеспечивает минимальную функциональность окна. Оконная процедура, определенная приложением, должна передать любое не обрабатываемое ей сообщение, процедуре DefWindowProc для обработки, принятой по умолчанию.

Поскольку процедура DefWindowProc вызывается для обеспечения обработки по умолчанию любого сообщения окна, которое не обрабатывается приложением, можно утверждать, что все сообщения будут рано или поздно обработаны (либо приложением, либо процедурой DefWindowProc).

Процедура DefWindowProc вызывается с рядом параметров (таблица 4).

Таблица 4 - Входные параметры процедуры DefWindowProc

Название параметра Тип в С Тип в ассемблере Описание параметра
hWnd, HWND DD Дескриптор окна, которому посылается собщение
Msg, UINT DD Уникальный идентификатор сообщения
wParam, WPARAM DD Параметр сообщения
lParam LPARAM DD Параметр сообщения

Возвращаемое процедурой DefWindowProc значение зависит от обрабатываемого сообщения.

Процедура DefWindowProc определяется как для ANSI (DefWindowProcA), так и для Unicode (DefWindowProcW).

Идентификаторы сообщений используются для переключения на соответствующие процедуры обработки, а параметры сообщений - для уточнения действия сообщения.

Оконная процедура связывается с классом окна при регистрации класса (используется функция RegisterClass, в качестве входного параметра которой используется структура WNDCLASS, содержащая указатель lpfnWndProc на оконную процедуру).

Оконная процедура (обычно называется WindowProc) определяется приложением и обрабатывает сообщения, посланные окну. Тип WNDPROC определяет указатель на эту процедуру.

В таблице 5 приведены входные параметры оконной процедуры.

Таблица 5 - Входные параметры процедуры WindowProc

Название параметра Тип в С Тип в ассемблере Описание параметра
hwnd HWND DD Дескриптор окна
uMsg UINT DD Идентификатор сообщения
wParam, WPARAM DD Параметр сообщения, определяет дополнительную информацию сообщения
lParam LPARAM DD Параметр сообщения, определяет дополнительную информацию сообщения

Возвращаемое значение является результатом обработки сообщения и зависит от посланного сообщения.

Для окончания процесса используется API-функция ExitProcess. В качестве входного параметра функции ExitProcess используется код выхода (целое число), а выходного значения у этой функции нет.

Выход из процесса влечет за собой следующее:

1. Все дескрипторы объектов, открытые процессом закрываются;

2. Все потоки в процессе, за исключением вызывающего потока, прекращают свое выполнение, все подключенные DLL закрываются (входная функция DLL вызывается с параметром DLL_PROCESS_DETACH, после чего выполняется некий завершающий код);

3. Потоки, ожидающие окончания процесса получают сигнал от объектов процесса о его окончании;

4. Потоки, ожидающие окончания потоков процесса получают сигнал от всех потоков процесса о его окончании;

5. Статус процесса изменяется с STILL_ACTIVE на код завершения процесса.

Если неизвестно состояние всех потоков процесса, то предпочтительнее вызывать функцию TerminateProcess (в качестве входных параметров используется дескриптор завершаемого процесса и код завершения процесса).

Для получения кода завершения процесса можно использовать функцию GetExitCodeProcess (в качестве входного параметра используется дескриптор процесса, возвращаемое значение - указатель на код завершения процесса), а для получения кода завершения потока - GetExitCodeThread (в качестве входного параметра используется дескриптор потока, а возвращаемое значение - указатель на код завершения потока).

Использование функции ExitProcess в DLL может повлечь за собой неожиданную системную ошибку или ошибку завершения приложения. Выход из процесса не влечет за собой окончание порожденных процессов. Выход из процесса, не обязательно повлечет за собой удаление объектов процесса из операционной системы. Объекты процесса будут удалены тогда, когда будет закрыт последний дескриптор на процесс.


Понравилась статья? Добавь ее в закладку (CTRL+D) и не забудь поделиться с друзьями:  



double arrow
Сейчас читают про: