Поиск:

Ответ в темуСоздание новой темы Создание опроса
> как правильно пересоздавать контролы/диалоги 
:(
    Опции темы
_hunter
  Дата 29.6.2006, 10:36 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Участник Клуба
Сообщений: 8564
Регистрация: 24.6.2003
Где: Europe::Ukraine:: Kiev

Репутация: 5
Всего: 98



Добрый день.

Понадобилось пересоздать диалог. Делаю это так:
Код

    m_TopPanel->DestroyWindow();//пересоздаваемый контрол
    delete m_TopPanel;

    CTopPanel* newTopPanel = new CTopPanel();//наследник от CDialogBar
    newTopPanel->Create(this, IDD_TOP_PANEL, CBRS_ALIGN_TOP, IDD_TOP_PANEL);
    newTopPanel->SetParent(this);
    newTopPanel->ShowWindow(SW_SHOWNORMAL);
    newTopPanel->RedrawWindow();
    RedrawWindow();

    m_TopPanel = newTopPanel;

но при этом на строке newTopPanel->Create() бросается assertion "Error: no data exchange control with ID " из CDataExchange::PrepareCtrl() 


--------------------
Tempora mutantur, et nos mutamur in illis...
PM ICQ   Вверх
Earnest
Дата 29.6.2006, 12:58 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Экс. модератор
Сообщений: 5962
Регистрация: 17.6.2005
Где: Рязань

Репутация: 87
Всего: 183



Не совсем понятно: что значит "пересоздавать"? Ты ведь просто создаешь динамически панель.
Но в любом случае, ошибка о которой ты пишешь, возникает,  когда не находится контрол по ID. Проверь предложения DDX_ в DoDataExchange, там упоминается какой-то ид-р, не сущетвующий в диалоговом ресурсе.

А зачем делать SetParent(this)? Ты и так передаешь в Create this в качестве парента.
  


--------------------
...
PM   Вверх
_hunter
Дата 29.6.2006, 13:14 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Участник Клуба
Сообщений: 8564
Регистрация: 24.6.2003
Где: Europe::Ukraine:: Kiev

Репутация: 5
Всего: 98



у меня на диалоге лежит панель. я ее хочу удалить и создать заново.
(в VCL это проще было...)

так в первый раз она создается нормально...

P.S.
перед пересозданием я вызываю AfxSetResourceHandle, но все ID в ресурсах совпадают... 


--------------------
Tempora mutantur, et nos mutamur in illis...
PM ICQ   Вверх
Earnest
Дата 29.6.2006, 14:32 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Экс. модератор
Сообщений: 5962
Регистрация: 17.6.2005
Где: Рязань

Репутация: 87
Всего: 183



Цитата(_hunter @  29.6.2006,  14:14 Найти цитируемый пост)
я ее хочу удалить и создать заново.

Из другого ресурса? Иначе зачем удалять и снова создавать то же самое.

Цитата(_hunter @  29.6.2006,  14:14 Найти цитируемый пост)
перед пересозданием я вызываю AfxSetResourceHandle

Зачем? Ресурсы в разных модулях лежат?

Цитата(_hunter @  29.6.2006,  14:14 Найти цитируемый пост)
но все ID в ресурсах совпадают...  

Значит, не все. Исключение, о котором ты писал, возбуждается, если GetDlgItem (ID) возвращает 0, что бывает тогда, когда такого поля нет.
Чтобы проверить, закомментируй соответствующее предложение DDX_ в DoDataExchange, а потом посмотри Спаем, совпадают ли ид-ры полей с ожидаемыми. 


--------------------
...
PM   Вверх
_hunter
Дата 29.6.2006, 17:05 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Участник Клуба
Сообщений: 8564
Регистрация: 24.6.2003
Где: Europe::Ukraine:: Kiev

Репутация: 5
Всего: 98



от Assertion' а избавился (там, оказывается невидимая панель с кучей контролов на панели лежала).
но теперь из OnCmdMsg (CWnd::OnCommand()) Unhandled exception бросается. причем по стеку одни .dll а в Output' e предпоследняя строка "Access violation reading location 0x0000001f" 


--------------------
Tempora mutantur, et nos mutamur in illis...
PM ICQ   Вверх
Earnest
Дата 30.6.2006, 07:27 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Экс. модератор
Сообщений: 5962
Регистрация: 17.6.2005
Где: Рязань

Репутация: 87
Всего: 183



Debug->Exceptions: поставь опцию "When exception is thrown" в позицию "Break into debugger". Скорее всего, для Win32Exceptions. По-крайней мере должен увидеть где возникает исключение.
  


--------------------
...
PM   Вверх
_hunter
Дата 30.6.2006, 11:44 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Участник Клуба
Сообщений: 8564
Регистрация: 24.6.2003
Где: Europe::Ukraine:: Kiev

Репутация: 5
Всего: 98



поставил. помогло мало smile
исключение кидается из comctl32.dll
по стеку последняя функция CWnd::OnCommand (из wincore.h) и потом одни .dll
а отладчик останавливается на закрывающей } OnCommand (после OnCmdMsg) 


--------------------
Tempora mutantur, et nos mutamur in illis...
PM ICQ   Вверх
Earnest
Дата 30.6.2006, 13:01 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Экс. модератор
Сообщений: 5962
Регистрация: 17.6.2005
Где: Рязань

Репутация: 87
Всего: 183



У тебя это происходит после какой-то пользовательской команды (т.е. ты что-то делаешь - на кнопку жмешь или текст меняешь) или на IdleUpdate (это если ничего не делаешь, а оно вылетает сразу после отображения)?
В первом случае проще: ставим точку прерывания на обработчик этой команды, и прослеживаем.
Во втором случае, после вылета вернись по стеку назад до OnCommand и посмотри параметры сообщения: нужно выяснить чей это Update. Потом тоже самое: ставим точку прерывания на этот обработчик, и идем от него вглубь. Если обработчика нет, то можно поставить условную точку прерывания прямо в OnCommand.

Если хочешь, кинь проект, попробую найти вечером. А то по телефону сложно лечить. smile

Добавлено @ 13:03 
Еще, если ты работаешь в 6й студии, проверь обработчики команд на соответствие ожидаемым сигнатурам: очень частая ошибка. 


--------------------
...
PM   Вверх
_hunter
Дата 3.7.2006, 13:45 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Участник Клуба
Сообщений: 8564
Регистрация: 24.6.2003
Где: Europe::Ukraine:: Kiev

Репутация: 5
Всего: 98



Цитата(Earnest @  30.6.2006,  13:01 Найти цитируемый пост)
Если хочешь, кинь проект, попробую найти вечером.

был бы очень благодарен.
тестовый проект 


--------------------
Tempora mutantur, et nos mutamur in illis...
PM ICQ   Вверх
_hunter
Дата 3.7.2006, 14:10 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Участник Клуба
Сообщений: 8564
Регистрация: 24.6.2003
Где: Europe::Ukraine:: Kiev

Репутация: 5
Всего: 98



причем в тестовом проекте глок проявляетяс только при переключении мышью. причем не всегда (т.е. при запуске одного и того же .exe-шника может как проявиться так и нет). причем если переключать колесиком -- глюк проявляется чаще... 


--------------------
Tempora mutantur, et nos mutamur in illis...
PM ICQ   Вверх
Earnest
Дата 3.7.2006, 15:52 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Экс. модератор
Сообщений: 5962
Регистрация: 17.6.2005
Где: Рязань

Репутация: 87
Всего: 183



У меня не получилось свалить. Правда, мне пришлось переключиться на Использование Shared MFC DLL и, соответственно, Runtime DLL (я никогда не использую статические библиотеки, поэтому не ставлю их). И доставить не смогла - то ли дистрибутив не тот, то ли еще что... в общем, не получилось. Возможно разное поведение связано с этим.

Но  у тебя там есть нехороший код, который, теоретически, может иногда приводить к неприятностям: из CTopPanel::OnCbnSelchangeLanguages посылается синхронное сообщение, в результате которого панель может быть уничтожена. Т.е. в момент выхода из этой функции панели уже нет, а эта функция не последняя в стеке... а там есть и виртуальные функции...
Посылай сообщение PostMessage, тогда уничтожение панели будет происходить уже после выхода из обработчика OnCommand.
И еще, не очень здорово, что ты выделяешь память в одном месте (в вышеупомянутой функции), а освобождаешь - совсем в другом месте. Если бы проходило SendMessage, то вообще нет необходимости выделять память и что-то копировать: локальные переменные будут жить до выхода из SendMessage, так что их вполне можно использовать. Но, конечно, не при переходе к PostMessage. Я бы привязала язык не к строкам, а к стандартным LANGID, которые являются целыми и спокойно передаются в WPARAM или LPARAM. Т.е. в списке языков к строкам привязать соответствующие LANGID как ItemData, и дальше работать уже с ними. Через LANGID от системы можно получить массу полезной информации... Кроме того, это даст возможность заполнять список языков на разных языках. 


--------------------
...
PM   Вверх
_hunter
Дата 3.7.2006, 16:08 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Участник Клуба
Сообщений: 8564
Регистрация: 24.6.2003
Где: Europe::Ukraine:: Kiev

Репутация: 5
Всего: 98



блин. таки в SendMessage была проблема (почему-то в голове отложилось что это асинхронный вызов).
спасибо.

насчет LANGID подумаю... 


--------------------
Tempora mutantur, et nos mutamur in illis...
PM ICQ   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Visual C++/MFC/WTL | Следующая тема »


 




[ Время генерации скрипта: 0.0789 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.