Отправляет email-рассылки с помощью сервиса Sendsay

Программирование. Форум !!!

CClientDC

Доброй поры суток...

Есть проект, в котором нужно многократно выводить графку...
1. Сам проект основан на CFormView
2. Вывод осуществляется с помошью примерно следующей конструции:

CClientDC pDraw;
pDraw.MoveTo(100,100);
pDraw.LineTo(200,200);

Рисовать-то он рисует, но вот через 2-3 тысячи циклов, вывод заметно
тормозится, а ещё через столько же выдаёт "Запрашиваемый ресурс не
доступен" и внаглую, закрывается...

Если я правильно понимаю, то вся графика выводится поверх старого
контекста...Может, есть какая-то функция, которая бы обнуляла всё
содержимое?

Подскажите, кто знает!
Заранее пасибо!

Павел a.k.a BOER mailto:bo***@p*****.net

Номер выпуска : 4444
Возраст листа : 595 (дней)
Количество подписчиков : 513
Адрес в архиве : http://subscribe.ru/archive/comp.soft.prog.prog/msg/364312
Получить правила : mailto:comp.soft.prog.prog-rules@subscribe.ru
Формат "дайджест" : mailto:comp.soft.prog.prog-digest@subscribe.ru
Формат "каждое письмо" : mailto:comp.soft.prog.prog-normal@subscribe.ru
Формат "читать с веба" : mailto:comp.soft.prog.prog-webonly@subscribe.ru

Ответить   Paul Sun, 8 May 2005 16:43:47 +0300 (#364312)

 

Ответы:

Здравствуйте !


А почему именно на CFormView ?
CFormView служит для несколько иных целей чем вывод графики -
это фактически диалоговое окно, на котором надо размещать
свои элементы управления. Для этого оно и сделано. Если нужно просто
рисовать что то, то гораздо правильнее использовать CScrollView
(там реализованы механизмы пересчета координат с учетом заданных
метрик и текущей позиции скроллинга).


Такая конструкция не прокатит (у CClientDC нет дефолтового конструктора
и надо передавать при его создании какое то окно).
Значит, код приведен не полностью.
Также могу предположить, что pDraw - указатель (отчего же ему быть p...),
следовательно где то под него память должна выделяться. Так вот если
его не убивать, то и контекст операционной системы не освободиться.
Отсюда - утечка ресурсов GDI и такой вот эффект.
То есть не надо делать так:

{
...
CClientDC *pDraw = new CClientDC(this);
pDraw->MoveTo(100,100);
...
}
надо либо так:
{
...
CClientDC dcDraw(this);
dcDraw.MoveTo(100,100);
...
}
тут dcDraw при выходе из функции разрушится.
либо так:
{
...
CClientDC *pDraw = new CClientDC(this);
pDraw->MoveTo(100,100);
delete pDraw;
...
}

И еще контекст, наверно, может не освобождаться если в него выбрать
какие либо объекты GDI, и потом не выбрать в него то что там было ранее.

То есть вот так делать не надо:
{
...
CClientDC dcDraw(this);
CPen pen;
pen.CreatePen(PS_SOLID, 1, RGB(0x00, 0x33, 0x66));
dcDraw.SelectObject(&pen);
dcDraw.MoveTo(100,100);
...
}
надо так:
{
...
CClientDC dcDraw(this);
CPen pen, *pOldPen;
pOldPen = pen.CreatePen(PS_SOLID, 1, RGB(0x00, 0x33, 0x66));
dcDraw.SelectObject(&pen);
dcDraw.MoveTo(100,100);
dcDraw.SelectObject(pOldPen);
...
}


Нет никакого старого контекста. Контекст устройства - абстракция (точнее
даже
механизм абстрагирования от особенностей конкретного устройства). Контекст
создается соответствующими функциями API и уничтожается. Если контексты
создавать, но не освобождать, то система скоро перестанет создавать новые
объекты GDI (есть ограниченный и не особо большой пул объектов - вроде
16384). То есть всего в винде можно создать 16384 перьев/кистей/контекстов/
регионов/... На уровне процесса всего около 10000. Кстати, где то в реестре
есть ключ, в котором указывается максимальное количество объектов GDI на
уровне процесса.

А в Вашем случае ресурсы GDI текут - это очевидно.


--
С уважением, Вахтуров Виктор.
(

Номер выпуска : 4447
Возраст листа : 597 (дней)
Количество подписчиков : 515
Адрес в архиве : http://subscribe.ru/archive/comp.soft.prog.prog/msg/364818
Получить правила : mailto:comp.soft.prog.prog-rules@subscribe.ru
Формат "дайджест" : mailto:comp.soft.prog.prog-digest@subscribe.ru
Формат "каждое письмо" : mailto:comp.soft.prog.prog-normal@subscribe.ru
Формат "читать с веба" : mailto:comp.soft.prog.prog-webonly@subscribe.ru

Ответить   Tue, 10 May 2005 01:39:54 +0400 (#364818)

 

Доброго...Эм, поры суток, Victor.

Вы писали 10 мая 2005 г., 0:39:54:

Victor> А почему именно на CFormView ?
Victor> CFormView служит для несколько иных целей чем вывод графики -
Victor> это фактически диалоговое окно, на котором надо размещать
Victor> свои элементы управления. Для этого оно и сделано. Если нужно просто
Victor> рисовать что то, то гораздо правильнее использовать CScrollView
Victor> (там реализованы механизмы пересчета координат с учетом заданных
Victor> метрик и текущей позиции скроллинга).

Это все понятно, но кроме своих контролов приходилось многократно
выводить результат их работы...От сюда и выбор...

Victor> надо либо так:
Victor> {
Victor> ...
Victor> CClientDC dcDraw(this);
Victor> dcDraw.MoveTo(100,100);
Victor> ...
Victor> }
Victor> тут dcDraw при выходе из функции разрушится.
Самое интересное, что так вначале оно и было, НО при выходе ничего не
разрушалось:(
Victor> либо так:
Victor> {
Victor> ...
Victor> CClientDC *pDraw = new CClientDC(this);
Victor> pDraw->MoveTo(100,100);
Victor> delete pDraw;
Victor> ...
Victor> }
Самый действенный вариант!!!
Victor> И еще контекст, наверно, может не освобождаться если в него выбрать
Victor> какие либо объекты GDI, и потом не выбрать в него то что там было ранее.
Не может, а так оно и есть!!!

Victor> То есть вот так делать не надо:
Victor> {
Victor> ...
Victor> CClientDC dcDraw(this);
Victor> CPen pen;
Victor> pen.CreatePen(PS_SOLID, 1, RGB(0x00, 0x33, 0x66));
Victor> dcDraw.SelectObject(&pen);
Victor> dcDraw.MoveTo(100,100);
Victor> ...
Victor> }
Victor> надо так:
Victor> {
Victor> ...
Victor> CClientDC dcDraw(this);
Victor> CPen pen, *pOldPen;
Victor> pOldPen = pen.CreatePen(PS_SOLID, 1, RGB(0x00, 0x33, 0x66));
Victor> dcDraw.SelectObject(&pen);
Victor> dcDraw.MoveTo(100,100);
Victor> dcDraw.SelectObject(pOldPen);
Victor> ...
Victor> }

Виктор, большое Вам спасибо за информацию и помощь!
ЗЫЖ Из всего выше сказанного могу только посоветовать, всем тем, кому
придется столкнуться с такой проблемой, размещать всё в динамической
памяти, а затем ПРИНУДИТЕЛЬНО удалять...И и использовать двойную
буферизацию.

Павел a.k.a BOER mailto:bo***@p*****.net

Номер выпуска : 4453
Возраст листа : 598 (дней)
Количество подписчиков : 516
Адрес в архиве : http://subscribe.ru/archive/comp.soft.prog.prog/msg/365294
Получить правила : mailto:comp.soft.prog.prog-rules@subscribe.ru
Формат "дайджест" : mailto:comp.soft.prog.prog-digest@subscribe.ru
Формат "каждое письмо" : mailto:comp.soft.prog.prog-normal@subscribe.ru
Формат "читать с веба" : mailto:comp.soft.prog.prog-webonly@subscribe.ru

Ответить   Paul Tue, 10 May 2005 15:13:58 +0300 (#365294)

 

Здравствуйте !


Кстати, только вот сейчас опечатку увидел :(
Надо так:

CClientDC dcDraw(this);
CPen pen, *pOldPen;
pen.CreatePen(PS_SOLID, 1, RGB(0x00, 0x33, 0x66));
pOldPen = dcDraw.SelectObject(&pen);
dcDraw.MoveTo(100,100);
dcDraw.SelectObject(pOldPen);


Я обычно выше приведенный вариант использую - тоже нормально
работает :)

--
С уважением, Вахтуров Виктор.

Номер выпуска : 4455
Возраст листа : 598 (дней)
Количество подписчиков : 516
Адрес в архиве : http://subscribe.ru/archive/comp.soft.prog.prog/msg/365309
Получить правила : mailto:comp.soft.prog.prog-rules@subscribe.ru
Формат "дайджест" : mailto:comp.soft.prog.prog-digest@subscribe.ru
Формат "каждое письмо" : mailto:comp.soft.prog.prog-normal@subscribe.ru
Формат "читать с веба" : mailto:comp.soft.prog.prog-webonly@subscribe.ru

Ответить   Tue, 10 May 2005 02:43:38 +0400 (#365309)