Учебное пособие: Подклассы окон
// заменяем процедуру обработки сообщений дочернего окна
lpfnOldProc= (FARPROC)SetWindowLong(
hChild,GWL_WNDPROC,(LONG)lpfnNewProc
);
break;
case WM_DESTROY:
DestroyWindow( hChild );
FreeProcInstance( lpfnNewProc );
break;
...
}
return DefWindowProc( hWnd, wMsg, wPar, lPar );
}
LONG WINAPI _export ChildProc(
HWND hWnd, UINT wMsg, UINT wPar, LONG lPar
) {
// специфичная обработка сообщений
// и вызов прежней функции, а не функции DefWindowProc
return CallWindowProc( lpfnOldProc, hWnd, wMsg, wPar, lPar );
}
Конечно, рассмотренный нами вариант не единственный. Так, например, мы можем заменять функцию обработки сообщений не окна, а класса. Тогда все вновь создаваемые окна этого класса будут применять нашу процедуру. Для этого мы должны использовать функцию
LONG SetClassLong( hWnd, GCW_WNDPROC, lpfnNewProc );
Что неудобно, так это то, что мы должны сначала создать окно, а только затем заменять процедуру обработки сообщений. Мы можем поступить и иначе - сначала узнать адрес процедуры обработки сообщений, используя функцию
GetClassInfo( hInstance, lpszClassName, lpWndClass );
которая заполняет структуру WNDCLASS информацией о данном классе, а затем создать свой класс, который будет применять вместо процедуры обработки сообщений по умолчанию процедуру этого класса.
Связывание данных с окном
При работе с окнами очень часто возникает необходимость хранения данных, связанных с окном. Часто это приходится делать при работе с дочерними окнами, особенно при порождении подклассов окон, когда в таких связанных данных удобно сохранять адреса процедур обработки сообщений и пр. При этом не должно возникать вопросов с разделением данных между двумя окнами одного класса.
Для такого связывания в Windows предусмотрено два разных метода. Первый метод основан на выделении дополнительного пространства для данных пользователя в структуре, описывающей окно или класс окон. Этот способ достаточно эффективен, но ограниченно применим, так как выделенное пространство статично и не может изменить свой размер.
Для использования данных окна (или класса) мы должны, при регистрации класса окон указать размеры дополнительного пространства, выделяемого в струткуре окна (поле .cbWndExtra структуры WNDCLASS) и в структуре класса (поле .cbClsExra). При выделении пространства оно автоматически обнуляется. Подробнее об этом смотри лекцию 2.
Для доступа к элементам описаний класса и окна можно применять функции: