![]() |
Модераторы: feodorv, GremlinProg, xvr, Fixin |
![]() ![]() ![]() |
|
yngwie19 |
|
|||
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 829 Регистрация: 15.6.2008 Где: Новгород Репутация: нет Всего: нет |
Здравствуйте! В книге Петзольда описывается субклассинг вот на каком примере:
Есть главное окно, в нем создано дочернее окно с классом "scrollbar". У каждого окна есть оконная процедура (я так полагаю что и у окна класса scrollbar тоже). В книге описывается механизм замены оконной процедуры класса scrollbar на свою, для этого делают слежующее:
вот как-то так. У меня вопрос вот в чем, правильно ли Я понимаю, что без субклассинга окно scrollbar обрабатывается в оконной процедуре родительского окна через сообщение WM_VSROLL или WM_HSCROLL соответсвенно, т.е по умолчанию заложего так. А если мы меняем адрес этой процедуры на свою, то она обрабатывается той оконной процедурой, которую мы для нее описали. А если необходимо чтобы какие-то сообщения посылаемые этому окну (scrollbar- у ) обрабатывались процедурой "по-умолчанию", то мы вызываем CallWindowProc() и передаем ей все необходимые параметры. Правильно ли Я понял суть? |
|||
|
||||
mes |
|
|||
любитель ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 7954 Регистрация: 14.1.2006 Репутация: 1 Всего: 250 |
Вобще то правильней не "процедурой по умолчанию", а предыдущей оконой функцией и в примере Вы забыли запомнить эту предыдущую функцию (через GetWindowLong) и в дальнейшем вызвать ее в CallWindowProc : обратите внимание на первый параметр : http://msdn.microsoft.com/en-us/library/ms633571.aspx Это сообщение отредактировал(а) mes - 20.5.2009, 00:18 |
|||
|
||||
yngwie19 |
|
|||
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 829 Регистрация: 15.6.2008 Где: Новгород Репутация: нет Всего: нет |
mes, ну да точно совсем забыл, ну а вообще правильно ли Я все понял?
меня вот что интересует, любое дочернее окно по умолчанию обрабатывается оконной процедурой окна родителя так? а если этот контрол у нас создан в диалоговом окне, то тут можно также менять адрес процедуры на другой? |
|||
|
||||
Cheloveck |
|
|||
![]() Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1578 Регистрация: 26.7.2008 Где: Тула Репутация: 1 Всего: 32 |
нет, не так. У любого окна, дочернего или главного... есть своя процедура обработки. Разница лишь в том, что дочерние окна извещают своих родителей о своих изменениях и статусах... Добавлено через 2 минуты и 52 секунды Более правильно запомнить результат функции SetWindowLong - она вернёт предыдущую процедуру. -------------------- ![]() |
|||
|
||||
Earnest |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 5962 Регистрация: 17.6.2005 Где: Рязань Репутация: 33 Всего: 183 |
Совсем нет. У каждого окна своя процедура. В родительское окно дочернее посылает различные уведомления (такие как WM_COMMAND, WM_NOTIFY, WM_DRAWITEM, ..., скролл-бары посылают WM_SCROLL). А обрабатываемых сообщений сотни. Кроме того, скролл-бары не обязательно являются окнами. Иногда - это просто часть неклиентской области. Например у окон со стилем WS_SCROLL. -------------------- ... |
|||
|
||||
yngwie19 |
|
|||
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 829 Регистрация: 15.6.2008 Где: Новгород Репутация: нет Всего: нет |
Earnest,
ну т.е у всех окон своя оконная процедура, которая по умолчанию описана так (например для ScrollBar - a ):
Правильно Я понял, т.е она ничего не делает кроме как вызывает оконную функцию окна родителя и передает ей параметры? |
|||
|
||||
mes |
|
||||||
любитель ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 7954 Регистрация: 14.1.2006 Репутация: 1 Всего: 250 |
точно, подзабыл.. 100 лет не программил на WinApi. нет, процедура родителя (а в WinApi этому званию соответствует окно, на котором создали дочернее) не вызывается.
Т.е родитель "насладжается" лишь получаемыми сообщениями и никакого другого контакта. Каждое окно вызывает оконную процедуру предка по наследованию т.е есть главная процедура всех окон DefWindowProc () от нее (не важна на прямую или через посредников) отнаследованы: DefDialogWindowProc - которую в конечном итоге должен вызвать контрол желающий быть диалогом DefScrollBarProc () - которую вызывают скролы, DefTextCtrlProc () - .. и так далее. (названия даны условны, и с истинами именами могут не совпадать) При создании нового типа окна, в оконной процедуре мы вызываем DefWindowProc, a при субклассировании фактически создается стек окон процедур, обеспечивающий наследованное поведение, условно такоe : MyWindowProc -> SavedWindowProc () -> ScrolledWindowProcEx () -> ScrolledWindowProc() -> DefScrollWindowProc ();
Разницы нет кто впоследствии будет родителем, важно от кого отнаследовано. P.S. в winApi получается игра слов, упомяннутая выше, поэтому еще раз уточню. грубо: предок при субклассировании - окно (его процедура), от которого мы перенимаем поведение - наследуемся. родитель - окно на котором мы расположим дочернее. эти два понятия не смотря на родственное созвучие и в некоторых случаях могут называться одним и тем же словом, но обозначают совершенно разные (по отношению к рассматриваемому) окна. Это сообщение отредактировал(а) mes - 20.5.2009, 09:16 |
||||||
|
|||||||
yngwie19 |
|
|||
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 829 Регистрация: 15.6.2008 Где: Новгород Репутация: нет Всего: нет |
mes, да что-то не очень понятно, запутано очень или надо кертинку рисовать. Можно где-нибудь на русском про это почитать?
|
|||
|
||||
GremlinProg |
|
||||
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 2706 Регистрация: 9.8.2005 Где: Тюмень Репутация: 99 Всего: 106 |
все будет гораздо проще, если представить оконную процедуру как полиморфное перекрытие класса:
тогда субклассинг - это наследование нового класса CMyScrollBar от CScrollBar, с перекрытием главного метода класса:
я уже приводил похожий пример, return CScrollBar::WndProc(...) - равнозначно CallWindowProc('адрес процедуры окна предка',...) слово родитель тут совсем не к месту, это предок, т.е. класс окна от которого производится субклассинг здесь можно вполне легально использовать термины ООП: инкапсуляция, наследование, полиморфизм хотя полновестное значение тут имеет только термин полиморфизм, т.е. перекрытие WndProc в потомке (CMyScrollBar) чтобы было еще и наследование, субклассинг должен осуществляться еще при регистрации класса окна, т.е. до создания окна (но такой способ перекрытия процедуры окна обычно так и называют: наследование, т.е., помимо доступа к процедуре предка, мы имеем инкапсулированные данные окна и/или класса предка) yngwie19, если понимаешь смысл основных инструментов ООП (инкапсуляция, наследование, полиморфизм), то и с субклассингом все должно быть понятно если нет, то можешь найти достаточно информации на эту тему в других разделах C/C++ -------------------- "Гений всегда разумнее, чем умнее. Ум — это машина, разум — водитель этой машины." |
||||
|
|||||
![]() ![]() ![]() |
Правила форума "C/C++: Системное программирование и WinAPI" | |
|
На данный раздел распространяются Правила форума и Правила раздела С++:Общие вопросы . Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Chipset, Step, Fixin, GremlinProg, xvr. feodorv. |
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей) | |
0 Пользователей: | |
« Предыдущая тема | C/C++: Системное программирование и WinAPI | Следующая тема » |
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |