Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Создание окна зарегистрированного класса 
:(
    Опции темы
Earnest
Дата 4.3.2010, 15:48 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


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

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



Цитата(Brodyaga @  3.3.2010,  11:31 Найти цитируемый пост)
Мне кажется дело в ID который я передаю в функцию Create. Я туда передаю ID диалога на котором хочу отобразить окно зареганного в системе класса. это ведь верно?

Нет, неверно. В функцию Create нужно передавать ID, который будет присвоен контролу, и по которому ты в любой момент сможешь его достать.
Но я не вижу, где ты его передаешь. Это волшебное число 137 что ли? Если так, то проблема вряд ли в этом.
Ты мог бы посмотреть отладчиком значения переменных ID и hWndCtrl какое именно условие не выполняется.

Кроме того, ранее ты говорил, что вылетаешь на строчек с функцией Create, так причем тут OnCommand? Действительно ли этот вызов находится во фрейме Create (т.е. где-то внутри Create -> посмотри стек). Если так, то похоже, что контрол при создании шлет извещение диалогу (проверь, что this в этот момент показывает на твой диалог), причем шлет его неправильно (не соблюдает соглашения о содержании WPARAM\LPARAM). Или может это твоя подкрутка?

В любом случае это не фатальная ошибка, если нажать Ignore, все должно продолжать работать, но ты этот видимо не пробовал.
Проверь, но в любом случае разобраться с Assert ом надо, ибо он указавает на некошерность поведения. 


--------------------
...
PM   Вверх
Brodyaga
Дата 4.3.2010, 21:26 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 599
Регистрация: 19.1.2008

Репутация: нет
Всего: 2



Цитата

Нет, неверно. В функцию Create нужно передавать ID, который будет присвоен контролу, и по которому ты в любой момент сможешь его достать.
Но я не вижу, где ты его передаешь. Это волшебное число 137 что ли? Если так, то проблема вряд ли в этом.

137 - это id диалога на котором я хочу разместить созданное окно. а как узнать какой id должен быть у контрола? как узнать, что нужно вместо 137 передать?

Цитата

Ты мог бы посмотреть отладчиком значения переменных ID и hWndCtrl какое именно условие не выполняется.

Значение ID почемуто 10003, hWndCtrl тоже не пустое. Следовательно второе условие не выполняется.

Цитата

Кроме того, ранее ты говорил, что вылетаешь на строчек с функцией Create, так причем тут OnCommand? Действительно ли этот вызов находится во фрейме Create (т.е. где-то внутри Create -> посмотри стек). Если так, то похоже, что контрол при создании шлет извещение диалогу (проверь, что this в этот момент показывает на твой диалог), причем шлет его неправильно (не соблюдает соглашения о содержании WPARAM\LPARAM). Или может это твоя подкрутка?

да, в этот момент hwnd равно hwnd моего диалога. никакой подкрутки нет...

Цитата

В любом случае это не фатальная ошибка, если нажать Ignore, все должно продолжать работать, но ты этот видимо не пробовал.
Проверь, но в любом случае разобраться с Assert ом надо, ибо он указавает на некошерность поведения. 

Я это пробовал, всеровно вылетает.
PM MAIL   Вверх
Andrey44
Дата 5.3.2010, 06:20 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1501
Регистрация: 4.12.2006
Где: На работе

Репутация: 12
Всего: 26



Цитата(Brodyaga @  4.3.2010,  21:26 Найти цитируемый пост)
137 - это id диалога на котором я хочу разместить созданное окно. а как узнать какой id должен быть у контрола? как узнать, что нужно вместо 137 передать?

Прочти хотя бы одну книгу по MFC или по WinAPI, тогда не будешь задавать таких вопросов.


--------------------
????? ??, ??????? ?????.  smile 
PM MAIL WWW ICQ   Вверх
Earnest
Дата 5.3.2010, 08:39 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


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

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



Цитата(Brodyaga @  4.3.2010,  22:26 Найти цитируемый пост)
137 - это id диалога на котором я хочу разместить созданное окно. а как узнать какой id должен быть у контрола? 

Любой, ты его сам назначаешь. Странно, если передаешь ты 137, а получаешь 10003... возможно это уведомление от другого контрола? Есть у тебя на диалоге контрол с таким ID? Или это все же этот?
А что касается hWndCtrl - стало быть, не выполняется IsWindow(hWndCtrl), т.е. не знает система такого окна. Нужно выяснить, кто посылает эту хрень. Я стек просила посмотреть.

Цитата(Brodyaga @  4.3.2010,  22:26 Найти цитируемый пост)
Я это пробовал, всеровно вылетает. 

Но ведь в другом месте? Где?

Добавлено через 4 минуты и 14 секунд
Кстати, о птичках... В WinAPI варианте ты никакого ID не передавал! Так зачем это делать в MFC-выарианте? Все параметры должны быть такие же, с учетом разницы hWnd - pWnd! Кто его знает, что у тебя за контрол? Например, тултипы тоже без ID создаются. Передай-ка вместо 137 0. И книжки почитай, не помешает...


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


Опытный
**


Профиль
Группа: Участник
Сообщений: 599
Регистрация: 19.1.2008

Репутация: нет
Всего: 2



Цитата

Кстати, о птичках... В WinAPI варианте ты никакого ID не передавал! Так зачем это делать в MFC-выарианте? Все параметры должны быть такие же, с учетом разницы hWnd - pWnd! Кто его знает, что у тебя за контрол? Например, тултипы тоже без ID создаются. Передай-ка вместо 137 0.

Передавал.. тамже вылетает, с id равным 10003...

Цитата

Любой, ты его сам назначаешь. Странно, если передаешь ты 137, а получаешь 10003... возможно это уведомление от другого контрола? Есть у тебя на диалоге контрол с таким ID? Или это все же этот?

Нету контрола с таким id. Скорее это при создании такой id назначается этому контролу. В варианте с переопределением оконной процедуры и созданием контрола на диалоге с помощью WinApi, тоже после создания в оконную процедуру поступают сообщения WM_COMMAND с 10003 id.

Цитата

А что касается hWndCtrl - стало быть, не выполняется IsWindow(hWndCtrl), т.е. не знает система такого окна. Нужно выяснить, кто посылает эту хрень. Я стек просила посмотреть.


Похоже после вызова этой функции идут сообщения WM_COMMAND в форму

Код

HWND hWnd = ::AfxCtxCreateWindowEx(cs.dwExStyle, cs.lpszClass,
  cs.lpszName, cs.style, cs.x, cs.y, cs.cx, cs.cy,
  cs.hwndParent, cs.hMenu, cs.hInstance, cs.lpCreateParams);


По стеку понять чтото не могу, просто вызов от одной функции к другой передаётся, как посмотреть откуда вызов то был:
Код

>    MyProg.exe!CWnd::OnCommand(unsigned int wParam = 10003, long int lParam = 405527168) Line: 2598, Byte Offsets: 0x104    C++
    MyProg.exe!CWnd::OnWndMsg(unsigned int message = 273, unsigned int wParam = 10003, long int lParam = 405527168, long int* pResult = 0x182bd738) Line: 2066, Byte Offsets: 0x6c    C++
    MyProg.exe!CWnd::WindowProc(unsigned int message = 273, unsigned int wParam = 10003, long int lParam = 405527168) Line: 2052, Byte Offsets: 0x48    C++
    MyProg.exe!AfxCallWndProc(CWnd* pWnd = 0x002c6550, HWND__* hWnd = 0x7c078200, unsigned int nMsg = 273, unsigned int wParam = 10003, long int lParam = 405527168) Line: 283, Byte Offsets: 0x24c    C++
    MyProg.exe!AfxWndProc(HWND__* hWnd = 0x7c078200, unsigned int nMsg = 273, unsigned int wParam = 10003, long int lParam = 405527168) Line: 451, Byte Offsets: 0xe8    C++
    0xf000fffc    

Но думаю вызов посылает контрол диалогу при создании. Потому что при создании самого диалога, он тоже сообщения со своим id посылается родителю(другому, главному диалогу), правда в этот раз id корректный, тот который указан в ресурсе и всё проходит без ошибок.

Цитата

Но ведь в другом месте? Где?

в этом же, просто при нажатии Ignore, программа проходит дальше, но потом снова присылается это сообщение с теми же параметрами и в этом же месте уже вылетает. (В варианте с переопределением оконной процедуры и созданием контрола на диалоге с помощью WinApi оно тоже несколько раз присылается, а после него ещё идут сообщения WM_COMMAND с id=10006 и id=10000)

Это сообщение отредактировал(а) Brodyaga - 5.3.2010, 13:17
PM MAIL   Вверх
Earnest
Дата 5.3.2010, 15:01 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


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

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



Цитата(Brodyaga @  5.3.2010,  14:16 Найти цитируемый пост)
По стеку понять чтото не могу, просто вызов от одной функции к другой передаётся, как посмотреть откуда вызов то был:

Просто смотри дальше вниз, где-то должен быть твой Create.... но иногда среда может врать, съезжает у нее чего-то... я так понимаю, библиотека с контролом не твоя и кода нет.

Цитата(Brodyaga @  5.3.2010,  14:16 Найти цитируемый пост)
, но потом снова присылается это сообщение с теми же параметрами и в этом же месте уже вылетает.

Тоже самое сообщение тоже можно проигнорировать. Нажми Ignore столько раз, сколько нужно - либо пройдешь, либо вылетишь не на ASSERT, а на что-то посерьезнее. Я это к тому, что нужно проверить, стоит ли пытаться обойти эту бяку, или твой контрол вообще нельзя через MFC создавать. Дело в том, что MFC подменяет оконную процедуру, а в контроле может наступить какой-нибудь конфликт в связи с этим.

Можно еще попробовать сделать так: создавать через ::CreateWindow, как ты уже делал, но тоже в OnInitDialog. Нет никакой необходимости ради этого подменять процедуру диалога. Тогда ты получишь hWnd, но можно легко сделать из него CWnd*, если оно надо. Вызывая апишную функцию для создания контрола, ты избегаешь установки хука на создание контрола, подмены процедуры и т.д. Если получится, можно при желании сделать для этого контрола MFC обертку (с собственной функцией Create).



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


Опытный
**


Профиль
Группа: Участник
Сообщений: 599
Регистрация: 19.1.2008

Репутация: нет
Всего: 2



Цитата

Просто смотри дальше вниз, где-то должен быть твой Create.... но иногда среда может врать, съезжает у нее чего-то... я так понимаю, библиотека с контролом не твоя и кода нет.

Это всё что есть. Библиотека не моя, примеры её использования есть только на WinApi.

Цитата

Тоже самое сообщение тоже можно проигнорировать. Нажми Ignore столько раз, сколько нужно - либо пройдешь, либо вылетишь не на ASSERT, а на что-то посерьезнее.

Это первое, что я попробовал. Вылетает именно на ASSERT, так как на следующую после него строку я поставил брекпоинт, после первого игнора на него программа переходит, но после второго вылетает не переходя на поставленный брекпоинт.

Цитата

Можно еще попробовать сделать так: создавать через ::CreateWindow, как ты уже делал, но тоже в OnInitDialog. Нет никакой необходимости ради этого подменять процедуру диалога. Тогда ты получишь hWnd, но можно легко сделать из него CWnd*, если оно надо. Вызывая апишную функцию для создания контрола, ты избегаешь установки хука на создание контрола, подмены процедуры и т.д.

А вот тут самое интересное. Я потому и сталподменять процедуру диалога, так как если это делать в OnInitDialog, то вылетает в том же месте(на ASSERT в wincore.cpp, Ln 2598) с теми же симптомами. А при переопределении оконной процедуры диалога всё работает. Подозреваю, что это изза того, что я не передаю управление старой оконной процедуре с помощью CallWindowProc после своих действий, а при ненужных мне сообщениях передаю управление DefWindowProc.

Кстати при WM_COMMAND туда же сообщение уходит:
Код

...
    case WM_COMMAND: wNotifyCode = HIWORD(wParam);
                                       wID=LOWORD(wParam);


    default: return DefWindowProc(hWnd, msg, wParam, lParam);
...

И всё нормально.

Сейчас попробовал отдать управление старой оконной процедуре диалога. Тоесть после создание окна контрола в WM_INITDIALOG, как и раньше присылаются сообщения WM_COMMAND с id=10003, но в мою переопределённую процедуру, но оттуда я отдаю управление старой процедуре:
Код

...
    case WM_COMMAND: wNotifyCode = HIWORD(wParam);
                                       wID=LOWORD(wParam);
                                       return CallWindowProc(fnOldMyDialogProc,hWnd, msg, wParam, lParam);

    default: return DefWindowProc(hWnd, msg, wParam, lParam);
...

Вылетело с теми же симптомами, что и раньше!(тоесть всё там же на Ln2598). Что скажете?

Это сообщение отредактировал(а) Brodyaga - 5.3.2010, 16:12
PM MAIL   Вверх
Earnest
Дата 9.3.2010, 09:57 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


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

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



Цитата(Brodyaga @  5.3.2010,  17:10 Найти цитируемый пост)
Это первое, что я попробовал. Вылетает именно на ASSERT, так как на следующую после него строку я поставил брекпоинт, после первого игнора на него программа переходит, но после второго вылетает не переходя на поставленный брекпоинт.

Куда вылетает-то? Ты используешь "вылетает" для самых разных ситуаций, попробуй пойми. Есть ASSERT'ы, есть исключения. Дело в том, что обойти первый ассерт довольно легко. Иногда сам факт останова на ASSERT (т.е. появление MessageBox) вызывает дальнейшие проблемы. Ибо нет после того ASSERT'а ничего фатального, на первый взгляд... Но нужно понять точно. Фактически, получается, что контрол посылает WM_COMMAND с LPARAM, которая не является окном... Странно, конечно.
Попробуй обойти так: В диалоге переопредели OnCommand и отфильтруй это сообщение (т.е. если флаг стоит и сообщение от этого контрола сразу выходим). Проще всего сделать это с помощью флага, который будет ставится перед созданием контрола, а потом сниматься. Это чтобы по-быстрому проверить. Если поможет, то можно будет думать о том, чтобы менее криво сделать. 


--------------------
...
PM   Вверх
Brodyaga
Дата 9.3.2010, 18:47 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 599
Регистрация: 19.1.2008

Репутация: нет
Всего: 2



Цитата

Куда вылетает-то? Ты используешь "вылетает" для самых разных ситуаций, попробуй пойми.

Никуда. Просто программа прекращает своё выполнение.

Сделал так:
Код

BOOL CMyDialog::OnCommand(WPARAM wParam,LPARAM lParam)
{
    int wNotifyCode = HIWORD(wParam);
    int wID=LOWORD(wParam);

    HWND hWndCtrl = (HWND)lParam;
    HWND hWndControl=Wnd->GetSafeHwnd();

    if(flag && (wID==10003 || wID==10008))
        return ::DefWindowProc(this->GetSafeHwnd(),WM_COMMAND,wParam,lParam);

    return CDialog::OnCommand(wParam,lParam);
}


Wnd - это объект типа CWnd*, обёртка для моего контрола. Создаю так:
Код

Wnd->Create(WC_RICHINK,NULL,WS_VISIBLE|WS_CHILD|WS_VSCROLL,rc,this,0);


ID равный 10008 включил, так как с ним потом тоже пошли сообщения, при обработке которых CDialog::OnCommand(wParam,lParam), вылетало всё на том же ASSERT'е. Правда после нажатия Ignor в этот раз прога продолжила своё выполнение без проблем.. ну да ладно.. всеровно решил управление ::DefWindowProc передать.
Вообщем так заработало, но что интересно hWndCtrl(ID элемента управления посылающего сообщение) и hWndControl(ID контрола) никогда не равны между собой. hWndCtrl всегда меняется.. тоесть сообщения всегда приходят от разных элементов управления.. Я думал что их контрол должен слать моему диалогу... разве не так?
PM MAIL   Вверх
Earnest
Дата 10.3.2010, 10:58 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


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

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



Строго говоря, да. Но это всего лишь соглашение - что при посылке WM_COMMAND в LPARAM должен быть HWND посылающего контрола. А соглашение можно и нарушить. Это ведь сам контрол делает, т.е. его автор. И чего он там написал - хз. По твоим словам получается, что LPARAM содержит совсем не HWND, а какую-то другую фигню. Осталось непонятным, откуда берутся ид-ры 10003 и 10008, которые не ты назначаешь. Посмотри Спаем на контрол после создания диалога - возможно он содержит вложенные элементы или сам состоит из нескольких частей... Еще интересно, чему равен NotifyCode, число из любопытства.
Кстати, я думаю, что вызов DefWindowProc можно простить, вернуть просто TRUE (или FALSE) - вряд ли там есть какая-то разумная обработка, раз соглашение о параметрах нарушено.


--------------------
...
PM   Вверх
Brodyaga
Дата 10.3.2010, 12:53 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 599
Регистрация: 19.1.2008

Репутация: нет
Всего: 2



Цитата

Еще интересно, чему равен NotifyCode, число из любопытства.

Всегда 0. Хоть с каким ID(10003, 10008)

Также там ещё приходят сообщения с 10006 и 10000, но с ними не вылетает.

Цитата

Посмотри Спаем на контрол после создания диалога - возможно он содержит вложенные элементы или сам состоит из нескольких частей...

Не приходилось таким пользовался, это программа шпион специальная? дайте название конкретной программки тогда
PM MAIL   Вверх
Earnest
Дата 11.3.2010, 11:33 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


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

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



Да так и называется - Spy. Есть в поставке Visual Studio. Очень удобно для исследования окон, как своих, так и чужих.


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


Опытный
**


Профиль
Группа: Участник
Сообщений: 599
Регистрация: 19.1.2008

Репутация: нет
Всего: 2



Боюсь это не поможет... У меня программа запускается на эмуляторе...
PM MAIL   Вверх
Ответ в темуСоздание новой темы Создание опроса
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Visual C++/MFC/WTL | Следующая тема »


 




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


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

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