Учебное пособие: Подклассы окон
Сейчас нам надо рассмотреть один интересный прием - порождение подкласса окон. Часто бывает так, что возможностей, предоставляемых окном того или иного стандартного класса Вам не хватает, а создавать эквивалентный стандартному класс с небольшими отличиями слишком сложно. В этом случае было бы удобно научиться создавать дополнительные классы окон, основанные на уже известных классах.
Именно это и называется порождением подкласса окон. Основная идея заключается в использовании собственной функции обработки сообщений, которая выполняла бы требуемую обработку, отличную от стандартной. При этом в качестве процедуры обработки сообщений по умолчанию должна выступать процедура, определенная в уже существующем классе.
Для реализации этого метода нам надо сделать три вещи:
· узнать адрес процедуры обработки сообщений заданного окна (или заданного класса).
· научиться вызывать нужную процедуру вместо процедуры обработки сообщений по умолчанию.
· сделать так, что бы сообщения обрабатывала написанная нами процедура, а не определенная в классе.
Первую и третью задачи удобно решать с помощью функции
LONG SetWindowLong( hWnd, GWL_WNDPROC, lpfnNewProc );
эта функция одновременно устанавливает новый адрес процедуры обработки сообщений и возвращает адрес прежней функции. Конечно, когда мы передаем адрес новой процедуры обработки сообщений он должен быть адресом связанной с нашим приложением функции, то есть он должен быть возвращен процедурой MakeProcInstance.
Теперь нам надо только организовать обращение к старой процедуре обработки сообщений вместо процедуры по умолчанию (DefWindowProc). Сделать это непосредственно мы не можем, так как при вызове оконной процедуры мы должны связать ее с приложением, зарегистрировавшем этот класс. Вместо этого нам надо воспользоваться функцией:
LONG CallWindowProc( lpfnProc, hWnd, wMsg, wPar, lPar );
Итак, приведем небольшой пример:
static HANDLE hInstance;
static FARPROC lpfnNewProc;
static FARPROC lpfnOldProc;
LONG WINAPI ChildProc( HWND, UINT, UINT, LONG );
// функция обработки сообщений главного окна
LONG WINAPI _export WinProc(
HWND hWnd, UINT wMsg, UINT wPar, LONG lPar
) {
static HWND hChild;
switch ( wMsg ) {
case WM_CREATE:
lpfnNewProc= MakeProcInstance( (FARPROC)ChildProc, hInstance );
hChild= CreateWindow(
“BUTTON”, “Btn A”,
BS_PUSHBUTTON | WS_CHILD | WS_VISIBLE,
10,10, 50,50,
hWnd, 0, hInstance, NULL
--> ЧИТАТЬ ПОЛНОСТЬЮ <--