![]() |
|
Модераторы: feodorv, GremlinProg, xvr, Fixin |
![]()
|
|
| Alca |
|
||||||
|
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 3993 Регистрация: 14.6.2006 Репутация: 5 Всего: 50 |
Есть класс:
От него наследую класс CXFrame, потом CXMyFrame. Если создаю окно с помощью ::CreateWindowEx:
то все нормально работает, а если из ресурсов:
то окно содается, но не реагирует ни на какие действия (не идет обработка сообщений), только можно перемещять мышкой. Где-то косяк в методе s_BaseWndProc... Если чего-то в коде не хватает - выложу. Это сообщение отредактировал(а) Alca - 29.7.2009, 15:59 |
||||||
|
|||||||
| GremlinProg |
|
||||
|
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 2706 Регистрация: 9.8.2005 Где: Тюмень Репутация: 99 Всего: 106 |
по-видимому, проблема в самом подходе к объединению функционала диалога и обычного окна в одном сишном классе: если свойство Class в шаблоне указывает на нормальный класс окна, то CreateDialog создает окно уже не класса 32770, а именно этого класса, указанного в свойстве Class ) короче говоря, основная ошибка в функции bIsDialog, она никогда не вернет TRUE вот с этого момента и разбирай функционал дальше: значит для диалога не будет вызвана процедура окна его предка, отсюда - он будет работать как простое окно, ни какой инициализации компонентов из ресурсов оно уже не сделает и т.д. т.е. это не синтаксическая ошибка, а логическая, ты создал окно диалогового класса, но не даешь этому классу с ним работать, полностью перекрыл функционал предка, точнее даже исключил предка из цепочки наследования (т.к. DefWindowProc все же вызываешь) мы ведь уже обсуждали проблему идентификации диалога при суперклассинге, изнутри твоего класса эту проблему решить можно, если сохранять процедуру класса-предка в самом объекте, а в последствии, изучать ее: если она равна DefDlgProc, то это диалог, иначе - нет, конечно, это верно только при условии, что цепочка предков состоит только из одного класса (судя по коду, этого более чем достаточно) т.е. заведи в сишном классе поле
а заполняй его только в методах: bCreateEx, bCreate и bCreateRes для всех методов инициируй его в DefWindowProc, кроме bCreateRes, тут ставь DefDlgProc тогда в s_BaseWndProc вместо компаратора bIsDialog ставь просто вызов
-------------------- "Гений всегда разумнее, чем умнее. Ум — это машина, разум — водитель этой машины." |
||||
|
|||||
| Alca |
|
|||
|
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 3993 Регистрация: 14.6.2006 Репутация: 5 Всего: 50 |
Отладчиком заходил в TRUE. Добавлено через 5 минут и 48 секунд Это сообщение отредактировал(а) Alca - 29.7.2009, 21:02 Присоединённый файл ( Кол-во скачиваний: 8 )
_Screenshot_.PNG 32,97 Kb |
|||
|
||||
| Alca |
|
|||
|
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 3993 Регистрация: 14.6.2006 Репутация: 5 Всего: 50 |
Это сообщение отредактировал(а) Alca - 29.7.2009, 22:37 |
|||
|
||||
| GremlinProg |
|
||||||||
|
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 2706 Регистрация: 9.8.2005 Где: Тюмень Репутация: 99 Всего: 106 |
иначе в твою процедуру окна он не войдет не войдет именно как в процедуру окна, т.к. будет создано стандартное диалоговое окно, класса 32770, а у него процедура окна DefDlgProc
опять смешиваешь диалоговую процедуру и процедуру окна в одну кучу, нельзя назначать одну процедуру в обе эти сущности, т.к. логика у них разная, в случае суперклассинга диалога, последний параметр, передаваемый функции CreateDialog, должен быть NULL!:
в брейкпойнте, у тебя работает диалоговая процедура, а не процедура окна, а между ними огромная разница: http://msdn.microsoft.com/en-us/library/ms645469(VS.85).aspx http://msdn.microsoft.com/en-us/library/ms633573(VS.85).aspx я же объяснял -------------------- "Гений всегда разумнее, чем умнее. Ум — это машина, разум — водитель этой машины." |
||||||||
|
|||||||||
| Alca |
|
||||||
|
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 3993 Регистрация: 14.6.2006 Репутация: 5 Всего: 50 |
Спасибо.
|
||||||
|
|||||||
| Alca |
|
|||
|
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 3993 Регистрация: 14.6.2006 Репутация: 5 Всего: 50 |
Мне хотя бы полноценный примерчик субклассирования с ::CreateDialog (без ::CreateWindowEx)
Добавлено через 12 минут и 3 секунды
Теперь вообще не попадаю в s_BaseWndProc. |
|||
|
||||
| Alca |
|
|||
|
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 3993 Регистрация: 14.6.2006 Репутация: 5 Всего: 50 |
|
|||
|
||||
| GremlinProg |
|
||||||
|
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 2706 Регистрация: 9.8.2005 Где: Тюмень Репутация: 99 Всего: 106 |
хорошо, привожу пример суперклассинга для диалога,
а чтобы ни кого особенно не напрягал объем кода, объясняю: я просто создал обычный проект Win32 Project, так что по большей части, это чуть-чуть подправленный стандартный Win32-шаблон
файл ресурсов:
Добавлено через 1 минуту и 16 секунд да, совсем забыл, файл Resource.h:
-------------------- "Гений всегда разумнее, чем умнее. Ум — это машина, разум — водитель этой машины." |
||||||
|
|||||||
| Alca |
|
|||
|
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 3993 Регистрация: 14.6.2006 Репутация: 5 Всего: 50 |
Попробую чего-то наваять...
|
|||
|
||||
| Alca |
|
|||
|
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 3993 Регистрация: 14.6.2006 Репутация: 5 Всего: 50 |
Что-то нихрена не получается:
|
|||
|
||||
| GremlinProg |
|
|||
|
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 2706 Регистрация: 9.8.2005 Где: Тюмень Репутация: 99 Всего: 106 |
так, в приложении пример того, что получилось
Присоединённый файл ( Кол-во скачиваний: 7 )
InheritedDialog.rar 118,57 Kb-------------------- "Гений всегда разумнее, чем умнее. Ум — это машина, разум — водитель этой машины." |
|||
|
||||
| GremlinProg |
|
|||
|
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 2706 Регистрация: 9.8.2005 Где: Тюмень Репутация: 99 Всего: 106 |
а теперь в приложении сам проект
Присоединённый файл ( Кол-во скачиваний: 9 )
InheritedDialog.rar 29,65 Kb-------------------- "Гений всегда разумнее, чем умнее. Ум — это машина, разум — водитель этой машины." |
|||
|
||||
| GremlinProg |
|
|||
|
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 2706 Регистрация: 9.8.2005 Где: Тюмень Репутация: 99 Всего: 106 |
Alca, загляни в проект, посмотри на его логику, разбери код, повторяю, 95-97% от того, что у меня написано - стандартный проект win32 CreateWindow заменен на CreateDialog + небольшие изменения/дополнения в классе окна, процедуре окна и цикле сообщений Это сообщение отредактировал(а) GremlinProg - 30.7.2009, 16:38 -------------------- "Гений всегда разумнее, чем умнее. Ум — это машина, разум — водитель этой машины." |
|||
|
||||
| Alca |
|
|||
|
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 3993 Регистрация: 14.6.2006 Репутация: 5 Всего: 50 |
Спасибо. У меня этот проект работает. А вот код, который был чуть выше - нет Где я накосячил? Это сообщение отредактировал(а) Alca - 30.7.2009, 16:41 |
|||
|
||||
| GremlinProg |
|
|||
|
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 2706 Регистрация: 9.8.2005 Где: Тюмень Репутация: 99 Всего: 106 |
во первых, не указана процедура окна, не надо так радикально расставлять NULL'ы ), я же писал только о CreateDialog без _m_WndClass.lpfnWndProc класс-потомок просто не будет зарегистрирован во вторых, непонятно, какое имя у этого класса, предполагаю "", судя по тому, как _m_sClassName инициализируется в конструкторе ну и в третьих, т.к. я не вижу твоего шаблона, для суперклассинга диалога требуется четкое соответствие свойства CLASS в шаблоне диалога и имени класса _m_sClassName, т.е., судя по всему, у тебя эти значения должны быть равны и не должны быть пустыми в моем примере, имя класса "Мой диалоговый класс", а оконная процедура для диалога - WndProc -------------------- "Гений всегда разумнее, чем умнее. Ум — это машина, разум — водитель этой машины." |
|||
|
||||
| Alca |
|
||||||||||||||
|
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 3993 Регистрация: 14.6.2006 Репутация: 5 Всего: 50 |
А данная структура должна быть членом класса или не обязательно?
Добавлено @ 20:52
исправил:
Инициализировано:
Добавлено @ 20:54
Добавлено @ 20:59
Самое интересное, что в эту функцию s_BaseWndProc я не попадаю на брейкпоинты, т,е, ваще сюда "не заходиться" Это сообщение отредактировал(а) Alca - 30.7.2009, 21:00 |
||||||||||||||
|
|||||||||||||||
| GremlinProg |
|
|||
|
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 2706 Регистрация: 9.8.2005 Где: Тюмень Репутация: 99 Всего: 106 |
а свойство CLASS в шаблоне диалога?
Добавлено через 2 минуты и 28 секунд нет, не обязательно -------------------- "Гений всегда разумнее, чем умнее. Ум — это машина, разум — водитель этой машины." |
|||
|
||||
| Alca |
|
||||||||
|
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 3993 Регистрация: 14.6.2006 Репутация: 5 Всего: 50 |
Исправил:
Добавлено @ 22:48
Добавлено через 14 минут и 36 секунд Какое сообщение ловить WM_INITDIALOG или WM_NCCREATE?
Это сообщение отредактировал(а) Alca - 30.7.2009, 22:50 |
||||||||
|
|||||||||
| Alca |
|
|||
|
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 3993 Регистрация: 14.6.2006 Репутация: 5 Всего: 50 |
Раньше (до исправлений) у меня сообщения заходили в метку WM_INITDIALOG, а теперь в WM_NCCREATE.
Кажись что-то продвигается. |
|||
|
||||
| GremlinProg |
|
||||
|
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 2706 Регистрация: 9.8.2005 Где: Тюмень Репутация: 99 Всего: 106 |
да, теперь работает процедура окна, тут все сообщения будут приходить
там параметра-то нет, используй CreateDialogIndirectParam, и в последний параметр передай this вообще, это нужно ловить на WM_INITDIALOG, тогда этот параметр придет в lParam если после WM_NCCREATE сразу приходит WM_DESTROY, значит некорректно обрабатываешь WM_NCCREATE, посмотри s_BaseWndProc, она должна передавать сообщение дальше, по цепочке:
-------------------- "Гений всегда разумнее, чем умнее. Ум — это машина, разум — водитель этой машины." |
||||
|
|||||
| Alca |
|
|||
|
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 3993 Регистрация: 14.6.2006 Репутация: 5 Всего: 50 |
|
|||
|
||||
| GremlinProg |
|
|||
|
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 2706 Регистрация: 9.8.2005 Где: Тюмень Репутация: 99 Всего: 106 |
Alca, чтобы особенно не заморачиваться, я предлагаю тебе сделать так:
объясняю: lpInitObject - это статический указатель, который будет хранить объект окна в момент создания окна InitWndProc - это первичная процедура окна, задача которой - принять любое первое сообщение от окна, инициализировать GWL_USERDATA и переставить процедуру окна на BaseProc BaseProc - вторичная процедура окна, эта процедура независимо от стилей окна всегда имеет доступ к корректному GWL_USERDATA, поэтому она просто извлекает этот объект и передает управление его методу WndProc WndProc - это уже не статический метод, в ее обязанности входит управление цепочкой оконных классов, она вызывает CallWindowProc, switch я поставил просто для примера, если тебе надо в этом классе перехватывать какие-нибудь сообщения, а вообще, это можно делать уже в потомках CreateFromResource - делает то же самое, что и у тебя, за исключением того, что перед вызовом CreateDialog устанавливает lpInitObject теперь, от класса XWindow наследуй свои классы, можешь перекрывать метод WndProc в потомках и делать что хошь Добавлено через 3 минуты и 28 секунд делать что хошь с диалоговым окном в парадигме ООП -------------------- "Гений всегда разумнее, чем умнее. Ум — это машина, разум — водитель этой машины." |
|||
|
||||
![]()
|
| Правила форума "C/C++: Системное программирование и WinAPI" | |
|
|
На данный раздел распространяются Правила форума и Правила раздела С++:Общие вопросы . Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Chipset, Step, Fixin, GremlinProg, xvr. feodorv. |
| 0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей) | |
| 0 Пользователей: | |
| « Предыдущая тема | C/C++: Системное программирование и WinAPI | Следующая тема » |
|
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |