| Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате |
| Форум программистов > Visual C++/MFC/WTL > непонятная ошибка с hDC |
| Автор: serg405 6.8.2009, 18:45 | ||||||
Очень активно рисую на окне через OnPaint. И иногда в непредсказуемые моменты прога вилетает на ассерте в функциях рисовани типу FileSolidRect() на проверке
Может ли это быть связано с тем, что я dc я получаю через GetDC(), а не через
Ище перед вылетом прога иногда выводит сообщение как на рисунке ![]() И вот что я вижу в Output.
Странно я ище ни в одном примере не видел чтобы тело onPaint - а брали в try |
| Автор: Earnest 7.8.2009, 07:46 |
| Если ты в рисуешь в OnPaint, то контекст все же нужно получать через CPaintDC, причем один раз на рисование. Дело в том, что не только рисовать нужно, но и некоторые другие действия выполнять; и делает это именно CPaintDC. Из твоего поста вообще можно понять, что ты получаешь контекст через GetDC КАЖДЫЙ РАЗ. И вообще, у тебя где-то явная лажа с кодом, раз такая фигня лезет. Что касается ловли исключений в OnPaint, так мало ли что ты не видел. Все зависит от кода рисования. Если он может вызвать исключение, значит, надо ловить. Кстати, CResourseException говорит о том, что ты безбожно разбазариваешь GDI-ресурсы (т.е. на возвращаешь их). |
| Автор: serg405 7.8.2009, 10:02 | ||||||||||||
Имееш ввиду что не делаю вот так?
А и кстаит дополнительный вопрос. Зачем седлали GetDC(), если можно во всех функциях кроме OnPaint использовать
Кстати здесь тож нужно делать
правильно? Вот ето нашол в MSDN
А если я сделал не так
а вот так
что тогода релизать, тут я так понимаю ненадо? Или всетаки чтото надо. И дайте ссылку кто может как правильно и грамотно пользоваться CDC CClientDC CPaintDC OnPaint CustomDraw и так далее. Может есть какаято книга по рисованию в MFC. Потому что MSDN мне чтото мало потогает. |
| Автор: GavriKos 7.8.2009, 10:28 |
| 1) По поводу ресурсов - это касется не только контекста устройства. Не забывай выгружать кисти, ручки и прочее. Выгружай все )) 2) Лучше приведи полный код, а то действительно непонятно что и как ты используешь для рисования |
| Автор: Earnest 7.8.2009, 13:46 | ||||||||
Здесь как раз релизить не надо. И в случае с ClientDC тоже - это делает деструктор. А вот здесь как раз очень даже надо. Вообще так нельзя делать именно потому, что ты не сохраняешь переменную CDC и непонятно что релизить.
Либо так, либо выбирать в контекст стандартную кисть (StockObject). А потом, разумеется удалять саму кисть (после выгрузки ее из контекста). Причем, если ты используешь автоматические переменные, то они сами разрушатся.
Еще какие! Нельзя разрушать объект, выбранный в контекст.
Не надо здесь релизить. А будет неизвестно что и неизвестно когда - неопределенное поведение. Вообще реилизить нужно только то, что сам создал, это общий принцип. И с основами C++ и MFC разобраться не помешает. |
| Автор: GavriKos 7.8.2009, 13:57 |
| По поводу литературы... Есть у меня хорошая книга в бумашке, но она харьковского издания, не знаю можно ли нарыть ее в инете. Название до боли простое - Visul c++. В принципе в любой книге именно по вижуалам должно по идее быть рисование. На сколько помню из школьных уроков мфс - правило хорошего тона при рисовании - старые объекты для рисования запоминать и потом обратно подключать. Очень спасает такая привычка в ситуации когда в середину рисования надо что то впихнуть свое. |
| Автор: serg405 7.8.2009, 14:08 |
А авторов не подсказеш? |
| Автор: GavriKos 7.8.2009, 14:24 |
| С. В. Глушаков, А.В. Коваль "Visual c++ руководство разработчика" |
| Автор: serg405 7.8.2009, 17:51 | ||
спасибо за втора. Так ище вопрос
Не ловит ничево. |
| Автор: serg405 10.8.2009, 09:37 | ||
А кто что скажет на щет такого кода
|
| Автор: Earnest 10.8.2009, 12:53 |
| Такой обработчик имеет смысл только в единственном случае: когда CWnd не является прямым предком CMyWnd, и прямой предок (или кто-то из предков) переопределяет OnPaint. Во всех остальных случаях он нафик не нужен. Как и оператор return. |
| Автор: serg405 10.8.2009, 18:05 |
| не ну у маня там if и другой код по else просто не будет ли какогото подводоного камня. Я сам понимаю что пользы от этого в чистом виде 0. |
| Автор: serg405 10.8.2009, 20:22 | ||
Так везде где вызывался GetDC() все выглыдит вот так
Ошыбка не пропала. Осталось впринципе только проверить все SelectObject(). Но я уже начинаю сомневаться что проблема в этом. Я бы показал сурс но у меня ево немерено и я незнаю где именно все вылетает. Хочу ище попробовать протрейсать все GetDC и поймать момент когда возникает первый CResourceError. А у когото вообще такое бывало. Если да то скажыте где нашли ошибку. |
| Автор: Earnest 11.8.2009, 06:40 | ||||
Тогда правильно будет примерно так:
Т.е. создавать CPaintDC нужно только в коде своей прорисовки, но никак не перед вызовом стандартного метода. Убери нифиг все GetDC из прорисовки. Вся прорисовка, вызываемая из OnPaint должна получать контекст CPaintDC, инициализируемый здесь же. Перепиши свои функции так, чтобы они получали контекст CDC как параметр, по ссылке, и вызывай из OnPaint или если приспичит - из других мест. Если где-то и нужно контекст через GetDC или CClientDC получать - таких мест не должно быть много. Чаще всего - это прорисовка каких-то временных объектов, скажем, при движении мыши. Но для основной прорисовки должен быть единиый контекст CPaintDC. |
| Автор: serg405 11.8.2009, 10:16 | ||
Забыл удалить. От лох. Давно у меня такого не было хорошо что на лики посмотрел. Добавлено через 4 минуты я так уже давно и сдела. Проблема была втом что забил делетнуть динамическую кисть. Посмотрел в аемори лики и все прояснилось. А на щет GetDC внутри пейнта я использовал функцию с параметром, но ету же функцию визивал и не только из онпейнт вот при тех други вызовах я и использовал GetDC |