Привет всем.
Такая проблема: в моей функции DrawGraph примерно через 1-2 минуцты работы программы происходит ошибка при очередном создании контекста dc. Функция вызывается на WM_TIMER (он установлен на 10мсек). Привожу код:
Здравствуйте Аноним, Вы писали:
А>Привет всем. А>Такая проблема: в моей функции DrawGraph примерно через 1-2 минуцты работы программы происходит ошибка при очередном создании контекста dc. Функция вызывается на WM_TIMER (он установлен на 10мсек). Привожу код:
А>Вроде бы возвращаю везде все GDI-объекты, удаляю сам dc.... А>В чём трабл??
Здравствуйте Аноним, Вы писали:
А>Привет всем. А>Такая проблема: в моей функции DrawGraph примерно через 1-2 минуцты работы программы происходит ошибка при очередном создании контекста dc. Функция вызывается на WM_TIMER (он установлен на 10мсек). Привожу код:
Попробуй останавливать таймер в OnTimer при прорисовке, и в OnDraw, а потом снова его запускать.
Re: Ошибка при создании CDC, help!
От:
Аноним
Дата:
24.02.02 21:25
Оценка:
Гм, нашёл причину... :super:
void CGraphView::OnTimer(UINT nIDEvent)
{
// TODO: Add your message handler code here and/or call default
// чего-то тут делаю
.............................................
// CDC *pDC = this->GetDC();
// DrawGraph(pDC);this->Invalidate(FALSE);
}
Иначе пожиралась вся память (увидел в TaskManager).
Но вопрос в силе — ПОЧЕМУ!
:)
Роман.
Здравствуйте Dima2, Вы писали:
D>Здравствуйте Аноним, Вы писали:
А>>Привет всем. А>>Такая проблема: в моей функции DrawGraph примерно через 1-2 минуцты работы программы происходит ошибка при очередном создании контекста dc. Функция вызывается на WM_TIMER (он установлен на 10мсек). Привожу код:
А>>Вроде бы возвращаю везде все GDI-объекты, удаляю сам dc.... А>>В чём трабл??
D>Что-то не увидел у тебя вызова ReleaseDC.
Привет Дима. Спасибо за участие :)
а который из них освобождать и от чего? Временному dc я перед выходом возвращаю старые GDI, сам его убиваю ( dc.DeleteDC() ), хотя мне не совсем понятно, зачем это делать, всё равно он при выходе из DrawGraph подчистится.... а в pDC ничего нового не выбираю, а лишь копирую битмап в него из временного... :???:
Re[3]: Ошибка при создании CDC, help!
От:
Аноним
Дата:
24.02.02 21:41
Оценка:
Здравствуйте Dima2, Вы писали:
D>Здравствуйте Аноним, Вы писали:
А>>Гм, нашёл причину... :super:
А>>
А>>Иначе пожиралась вся память (увидел в TaskManager). А>>Но вопрос в силе — ПОЧЕМУ! А>> :) А>>Роман.
D>Роман ответ выше я тебе уже дал. D>Ты не причину нашел, а отрисовываеш с помощью WM_PAINT, а в OnPaint судя по всему у тебя все в порядке.
Спасибо, Дима, так тоже работает :)
Я так понимаю, это нужно делать по той причине, что GetDC() возвращает не указатель, а создаёт его копию и возвращает указатель уже на эту копию?
Роман.
Здравствуйте Аноним, Вы писали:
А>Здравствуйте Dima2, Вы писали:
D>>Здравствуйте Аноним, Вы писали:
А>>>Привет всем. А>>>Такая проблема: в моей функции DrawGraph примерно через 1-2 минуцты работы программы происходит ошибка при очередном создании контекста dc. Функция вызывается на WM_TIMER (он установлен на 10мсек). Привожу код:
А>>>Вроде бы возвращаю везде все GDI-объекты, удаляю сам dc.... А>>>В чём трабл??
D>>Что-то не увидел у тебя вызова ReleaseDC.
А>Привет Дима. Спасибо за участие А>а который из них освобождать и от чего? Временному dc я перед выходом возвращаю старые GDI, сам его убиваю ( dc.DeleteDC() ), хотя мне не совсем понятно, зачем это делать, всё равно он при выходе из DrawGraph подчистится.... а в pDC ничего нового не выбираю, а лишь копирую битмап в него из временного...
C dc у тебя все в порядке и DeleteDC ему ты естественно можеш не делать (это сделает за тебя деструктор CDC), хотя может быть неплохо привыкнуть это делать самому, т.к. если будеш писать на чистом API, то будеш забывать.
Ф-я CreateCompatibleDC создает новый DC совместимый с твоим pDC, но pDC тебе то нужно освободить почитай описание ф-ии GetDC().
А>Я так понимаю, это нужно делать по той причине, что GetDC() возвращает не указатель, а создаёт его копию и возвращает указатель уже на эту копию?
CWnd::GetDC — это тонкая оболочка вокруг функции Win32 API с одноименным названием, которая выдает объект контекста устройства из внутреннего кэша системы. ReleaseDC возвращает объект в кэш. Логика предельно простая: взял — положи на место.
Здравствуйте Аноним, Вы писали:
А>Спасибо, Дима, так тоже работает А>Я так понимаю, это нужно делать по той причине, что GetDC() возвращает не указатель, а создаёт его копию и возвращает указатель уже на эту копию?
Ох, ты что-то такое сказал, что я не понял. Это уже какой-то двойной указатель получается. Да нет все проще GetDC() возвращает просто указатель на временный объект CDC.
Ты можеш создать окно со стилем CS_OWNDC, тогда ты можеш вызвать GetDC (один раз) для получения так называемого "private device context", в этом случае вызывать ReleaseDC не надо (нельзя) и сохраняются все изменения DC, которые ты сделал все время жизни окна.
Здравствуйте Dima2, Вы писали:
D>Ты можеш создать окно со стилем CS_OWNDC, тогда ты можеш вызвать GetDC (один раз) для получения так называемого "private device context", в этом случае вызывать ReleaseDC не надо (нельзя) и сохраняются все изменения DC, которые ты сделал все время жизни окна.
А если у тебя окно не имеет стиля CS_OWNDC, то как правильно сказал Alex Fedotov, твой DC, полученный через GetDC будет являться частью DC кэша системы и в один прекрасный момент ты этот кэш исчерпаеш.
Re[4]: Ошибка при создании CDC, help!
От:
Аноним
Дата:
24.02.02 23:06
Оценка:
Здравствуйте Dima2, Вы писали:
D>Здравствуйте Аноним, Вы писали:
А>>Здравствуйте Dima2, Вы писали:
D>>>Здравствуйте Аноним, Вы писали:
А>>>>Привет всем. А>>>>Такая проблема: в моей функции DrawGraph примерно через 1-2 минуцты работы программы происходит ошибка при очередном создании контекста dc. Функция вызывается на WM_TIMER (он установлен на 10мсек). Привожу код:
А>>>>Вроде бы возвращаю везде все GDI-объекты, удаляю сам dc.... А>>>>В чём трабл??
D>>>Что-то не увидел у тебя вызова ReleaseDC.
А>>Привет Дима. Спасибо за участие :) А>>а который из них освобождать и от чего? Временному dc я перед выходом возвращаю старые GDI, сам его убиваю ( dc.DeleteDC() ), хотя мне не совсем понятно, зачем это делать, всё равно он при выходе из DrawGraph подчистится.... а в pDC ничего нового не выбираю, а лишь копирую битмап в него из временного... :???:
D>C dc у тебя все в порядке и DeleteDC ему ты естественно можеш не делать (это сделает за тебя деструктор CDC), хотя может быть неплохо привыкнуть это делать самому, т.к. если будеш писать на чистом API, то будеш забывать. D>Ф-я CreateCompatibleDC создает новый DC совместимый с твоим pDC, но pDC тебе то нужно освободить почитай описание ф-ии GetDC().
Здравствуйте, Аноним, Вы писали:
А>Привет всем. А>Такая проблема: в моей функции DrawGraph примерно через 1-2 минуцты работы программы происходит ошибка при очередном создании контекста dc. Функция вызывается на WM_TIMER (он установлен на 10мсек). Привожу код: А>void CGraphView::OnTimer(UINT nIDEvent) А>{ А> // TODO: Add your message handler code here and/or call default А> // чего-то тут делаю А>..............................................
А> CDC *pDC = this->GetDC(); А> DrawGraph(pDC); А>}
Answer:
В он OnTimer я не вижу delete pDC (не знаю, может ты освобожбаешь pDC в другом месте — я не смотрел DrawGraph (sorry) ), но я бы сделал так:
void CGraphView::OnTimer(UINT nIDEvent)
{
// TODO: Add your message handler code here and/or call default
// чего-то тут делаю
..............................................
CClientDC dc(this);
DrawGraph(&dc);
}
если у тебя в DrawGraph все в порядке, то будет работать.
Здравствуйте, Nagir, Вы писали:
N>В он OnTimer я не вижу delete pDC (не знаю, может ты освобожбаешь pDC в другом месте — я не смотрел DrawGraph (sorry) ), но я бы сделал так:
Насчет delete я сильно сомневаюсь Правильнее — pDC->ReleaseDC();
N> CClientDC dc(this); N> DrawGraph(&dc);