Поиск:

Ответ в темуСоздание новой темы Создание опроса
> непонятная ошибка с hDC, во время работы hDC обнуляется 
V
    Опции темы
serg405
  Дата 6.8.2009, 18:45 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



Очень активно рисую на окне через OnPaint. И иногда в непредсказуемые моменты прога вилетает на ассерте в функциях рисовани типу FileSolidRect() на проверке 
Код

ASSERT(m_hDC != NULL);


Может ли это быть связано с тем, что я dc я получаю через GetDC(), а не через 
Код

CPaint dc(this);


Ище перед вылетом прога иногда выводит сообщение как на рисунке
user posted image

И вот что я вижу в Output.

Код

First-chance exception at 0x7c812afb in SSYS Trader.exe: Microsoft C++ exception: CResourceException at memory location 0x0012cc48..
Warning: Uncaught exception in WindowProc (returning 0).


Странно я ище ни в одном примере не видел чтобы тело onPaint - а брали в try

Это сообщение отредактировал(а) serg405 - 6.8.2009, 19:29
PM MAIL   Вверх
Earnest
Дата 7.8.2009, 07:46 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


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

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



Если ты в рисуешь в OnPaint, то контекст все же нужно получать через CPaintDC, причем один раз на рисование. Дело в том, что не только рисовать нужно, но и некоторые другие действия выполнять; и делает это именно CPaintDC.
Из твоего поста вообще можно понять, что ты получаешь контекст через GetDC КАЖДЫЙ РАЗ.
И вообще, у тебя где-то явная лажа с кодом, раз такая фигня лезет. Что касается ловли исключений в OnPaint, так мало ли что ты не видел. Все зависит от кода рисования. Если он может вызвать исключение, значит, надо ловить. Кстати, CResourseException говорит о том, что ты безбожно разбазариваешь GDI-ресурсы (т.е. на возвращаешь их).


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


Шустрый
*


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

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



Цитата(Earnest @  7.8.2009,  07:46 Найти цитируемый пост)
разбазариваешь GDI-ресурсы (т.е. на возвращаешь их).

Имееш ввиду что не делаю вот так?

Код

CPaintDC dc(this);
// painting
this->ReleaseDC(&dc);


А и кстаит дополнительный вопрос. Зачем седлали GetDC(), если можно во всех функциях кроме OnPaint использовать
Код

CClientDC dc(this);

Кстати здесь тож нужно делать
 
Код

this->ReleaseDC(&dc);

правильно?

Вот ето нашол в MSDN
Цитата

Because only one bitmap can be selected into a device context at a time, you must call ReleaseDC for each call to GetDC.

А если я сделал не так
Код

CDC *pDC = GetDC();
ReleaseDC(pDC);

а вот так
Код

GetDC()->rectangle(....);

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


И дайте ссылку кто может как правильно и грамотно пользоваться CDC CClientDC CPaintDC OnPaint CustomDraw и так далее.  Может есть какаято книга по рисованию в MFC. Потому что MSDN мне чтото мало потогает.

Это сообщение отредактировал(а) serg405 - 7.8.2009, 10:32
PM MAIL   Вверх
GavriKos
Дата 7.8.2009, 10:28 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 220
Регистрация: 8.8.2007
Где: Донецк, Украина

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



1) По поводу ресурсов - это касется не только контекста устройства. Не забывай выгружать кисти, ручки и прочее. Выгружай все ))
2) Лучше приведи полный код, а то действительно непонятно что и как ты используешь для рисования
--------------------
Донецкая группа IT - присоединяемся
PM MAIL ICQ   Вверх
serg405
Дата 7.8.2009, 10:40 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



1)
Цитата

2) Лучше приведи полный код, а то действительно непонятно что и как ты используешь для рисования

Уменя в проекте немерено кода по рисованию пишут его 3 человека каждий по своему. Тоесть суть не в коде а в том что ево много и мы непривильно спользуем ресурсы.

2)
Цитата(GavriKos @  7.8.2009,  10:28 Найти цитируемый пост)
1) По поводу ресурсов - это касется не только контекста устройства. Не забывай выгружать кисти, ручки и прочее. Выгружай все ))


3)Выгружать кисти это значит запоминать старую и возвращать ее? Или просто делетать поинтреы(ну это я и так знаю)?
или нужно самому делетать созданый обэкт ну от допустим обезательно ли делать вот так
Код

CBrush br;
br.CreateSolidBrush(255);
CClientDC dc(this);//
CBrush *oldBr = dc.SelectObject(&br);
//draw
dc.SelectObject(oldBr);//Если я далльше уже не рисую, и этого не сделать будут проблемы? 
br.DeleteObject();//Нужно ли это делать ведь по идеи пир выходе с функции и так удалится.
this->ReleaseDC(&d);// правильно???


4)Кстати а если сделать вот так
Код

dc.SelectObject(&br);
br.DeleteObject();// будут ли проблемы? Если я дальше не рисую.


5)А  вот ище пример. Так правильно?
Код

void CColorPickerEx::OnPaint()
{
    CPaintDC dc(this);

    DrawPicker(&dc);

    ReleaseDC(&dc);//раньше этого не было это я щас дописал.Раньше в  DrawPicker() я делал так CDC *pDC = GetDC(); и не освобождал
}

В DrawPicker просто рисую квадраты круги и так далее.

6) А если я рисую в OnCtrlColor? там в функцию приходит DC я так думаю там эго релизать ненадо? А что будет если я эго релизну?



Это сообщение отредактировал(а) serg405 - 7.8.2009, 11:06
PM MAIL   Вверх
Earnest
Дата 7.8.2009, 13:46 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


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

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



Цитата(serg405 @  7.8.2009,  11:02 Найти цитируемый пост)
Имееш ввиду что не делаю вот так?
CPaintDC dc(this);
// painting
this->ReleaseDC(&dc);

Здесь как раз релизить не надо.
И в случае с ClientDC тоже - это делает деструктор.

А вот здесь
Цитата(serg405 @  7.8.2009,  11:02 Найти цитируемый пост)

GetDC()->rectangle(....);

как раз очень даже надо. Вообще так нельзя делать именно потому, что ты не сохраняешь переменную CDC и непонятно что релизить.

Цитата(serg405 @  7.8.2009,  11:40 Найти цитируемый пост)
3)Выгружать кисти это значит запоминать старую и возвращать ее? Или просто делетать поинтреы(ну это я и так знаю)?

Либо так, либо выбирать в контекст стандартную кисть (StockObject). А потом, разумеется удалять саму кисть (после выгрузки ее из контекста). Причем, если ты используешь автоматические переменные, то они сами разрушатся.

Цитата(serg405 @  7.8.2009,  11:40 Найти цитируемый пост)
4)Кстати а если сделать вот так

dc.SelectObject(&br);
br.DeleteObject();// будут ли проблемы? Если я дальше не рисую.

Еще какие! Нельзя разрушать объект, выбранный в контекст.

Цитата(serg405 @  7.8.2009,  11:40 Найти цитируемый пост)
5)А  вот ище пример. Так правильно?


Цитата(serg405 @  7.8.2009,  11:40 Найти цитируемый пост)
6) А если я рисую в OnCtrlColor? там в функцию приходит DC я так думаю там эго релизать ненадо? А что будет если я эго релизну?

Не надо здесь релизить. А будет неизвестно что и неизвестно когда - неопределенное поведение.

Вообще реилизить нужно только то, что сам создал, это общий принцип.
И с основами C++ и MFC разобраться не помешает.


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


Бывалый
*


Профиль
Группа: Участник
Сообщений: 220
Регистрация: 8.8.2007
Где: Донецк, Украина

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



По поводу литературы... Есть у меня хорошая книга в бумашке, но она харьковского издания, не знаю можно ли нарыть ее в инете. Название до боли простое - Visul c++. В принципе в любой книге именно по вижуалам должно по идее быть рисование. 

На сколько помню из школьных уроков мфс - правило хорошего тона при рисовании - старые объекты для рисования запоминать и потом обратно подключать. Очень спасает такая привычка в ситуации когда в середину рисования надо что то впихнуть свое. 
--------------------
Донецкая группа IT - присоединяемся
PM MAIL ICQ   Вверх
serg405
Дата 7.8.2009, 14:08 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



Цитата(GavriKos @  7.8.2009,  13:57 Найти цитируемый пост)
Название до боли простое - Visul c++

А авторов не подсказеш?
PM MAIL   Вверх
GavriKos
Дата 7.8.2009, 14:24 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 220
Регистрация: 8.8.2007
Где: Донецк, Украина

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



С. В. Глушаков, А.В. Коваль "Visual c++ руководство разработчика"
--------------------
Донецкая группа IT - присоединяемся
PM MAIL ICQ   Вверх
serg405
Дата 7.8.2009, 17:51 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



спасибо за втора. Так ище вопрос

Код

try
{
    CPaintDC dc(this);

    DrawPicker(&dc);

    ReleaseDC(&dc);
}
catch(CResourceException &e)
{
  e.ReportError();
}


Не ловит ничево.
PM MAIL   Вверх
serg405
Дата 10.8.2009, 09:37 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



А кто что скажет на щет такого кода
Код

void CmyWnd::OnPaint()
{
  CWnd::OnPaint();
  return;
}

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


Эксперт
****


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

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



Такой обработчик имеет смысл только в единственном случае: когда CWnd не является прямым предком CMyWnd, и прямой предок (или кто-то из предков) переопределяет OnPaint. Во всех остальных случаях он нафик не нужен. Как и оператор return.


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


Шустрый
*


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

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



не ну у маня там if и другой код по else просто не будет ли какогото подводоного камня. Я сам понимаю что пользы от этого в чистом виде 0.

PM MAIL   Вверх
serg405
Дата 10.8.2009, 20:22 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



Так везде где вызывался GetDC()  все выглыдит вот так
Код

CDC *pDC = GetDC();
Draw(pDC);
ReleasDC(pDC);

Ошыбка не пропала. Осталось впринципе только проверить все SelectObject().
Но я уже начинаю сомневаться что проблема в этом.
Я бы показал сурс но у меня ево немерено и я незнаю где именно все вылетает.
Хочу ище попробовать протрейсать все GetDC и поймать момент когда возникает первый CResourceError.

А у когото вообще такое бывало. Если да то скажыте где нашли ошибку.
PM MAIL   Вверх
Earnest
Дата 11.8.2009, 06:40 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


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

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



Цитата(serg405 @  10.8.2009,  19:05 Найти цитируемый пост)
не ну у маня там if и другой код по else просто не будет ли какогото подводоного камня. Я сам понимаю что пользы от этого в чистом виде 0.

Тогда правильно будет примерно так:
Код

void CMyView::OnPaint()
{
   if (...)
   {
      CWnd::OnPaint();
   }
   else
   {
      CPantDC dc (this);
      ...
   }
}

Т.е. создавать CPaintDC нужно только в коде своей прорисовки, но никак не перед вызовом стандартного метода.

Убери нифиг все GetDC из прорисовки. Вся прорисовка, вызываемая из OnPaint должна получать контекст CPaintDC, инициализируемый здесь же. Перепиши свои функции так, чтобы они получали контекст CDC как параметр, по ссылке, и вызывай из OnPaint или если приспичит - из других мест. Если где-то и нужно контекст через GetDC или CClientDC получать - таких мест не должно быть много. Чаще всего - это прорисовка каких-то временных объектов, скажем, при движении мыши. Но для основной прорисовки должен быть единиый контекст CPaintDC.


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


 




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


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

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