Потому что он возвращает экземляр класса CDC, который когда-нибудь будет удалён, но в нём хранится результат ::GetDC , поэтому парный вызов нужен ::ReleaseDC, а не ::DeleteDC.
Код
CDC* dc = wnd->GetDC();
...
wnd->ReleaseDC(dc);
тоже некорректен, т.к. ReleaseDC не обнулит HDC в CDC, и ::DeleteDC всё равно будет лишний раз вызван
Т.е. лучше вообще не использовать CWnd::GetDC , а делать так
Здравствуйте, Alexander G, Вы писали:
AG>Потому что он возвращает экземляр класса CDC, который когда-нибудь будет удалён, но в нём хранится результат ::GetDC , поэтому парный вызов нужен ::ReleaseDC, а не ::DeleteDC.
Обратите внимание, возвращается указатель на CDC. Поэтому выделенное — неверно. Вы же не пытаетесь запихнуть CDC* в умный указатель? Впрочем, если пытаетесь, передайте ему deleter вида ReleaseDC.
F>Обратите внимание, возвращается указатель на CDC. Поэтому выделенное — неверно. Вы же не пытаетесь запихнуть CDC* в умный указатель? Впрочем, если пытаетесь, передайте ему deleter вида ReleaseDC.
Я, кажется, постиг эту магию.
CDC объекты хранятся во временной мапе, и перед вызовами деструкторов для них, хранящиеся хендлы обнуляются (грубоватым хаком).
HANDLE* ph = (HANDLE*)((BYTE*)pTemp + m_nOffset); // after CObject
ASSERT(ph[0] == h || ph[0] == NULL);
ph[0] = NULL;
if (m_nHandles == 2)
{
ASSERT(ph[1] == h || ph[1] == NULL);
ph[1] = NULL;
}
Здравствуйте, flаt, Вы писали:
F>Обратите внимание, возвращается указатель на CDC. Поэтому выделенное — неверно. Вы же не пытаетесь запихнуть CDC* в умный указатель? Впрочем, если пытаетесь, передайте ему deleter вида ReleaseDC.
В MFC функции типа XXX::FromHandle (там у многих классов есть такая статическая функция) возвращают указатель на временные объекты, эти объекты удаляются при следующем вызове OnIdle.
Здравствуйте, SkyKnight, Вы писали:
SK>В MFC функции типа XXX::FromHandle (там у многих классов есть такая статическая функция) возвращают указатель на временные объекты, эти объекты удаляются при следующем вызове OnIdle.