CWnd::GetDC
От: Alexander G Украина  
Дата: 12.08.16 10:27
Оценка:
CWnd::GetDC, получается, вызывать нет смысла.

Потому что он возвращает экземляр класса CDC, который когда-нибудь будет удалён, но в нём хранится результат ::GetDC , поэтому парный вызов нужен ::ReleaseDC, а не ::DeleteDC.

Код

CDC* dc = wnd->GetDC();
...
wnd->ReleaseDC(dc);


тоже некорректен, т.к. ReleaseDC не обнулит HDC в CDC, и ::DeleteDC всё равно будет лишний раз вызван

Т.е. лучше вообще не использовать CWnd::GetDC , а делать так

CWindowDC dc(wnd);
Русский военный корабль идёт ко дну!
Re: CWnd::GetDC
От: flаt  
Дата: 12.08.16 12:27
Оценка:
Здравствуйте, Alexander G, Вы писали:

AG>Потому что он возвращает экземляр класса CDC, который когда-нибудь будет удалён, но в нём хранится результат ::GetDC , поэтому парный вызов нужен ::ReleaseDC, а не ::DeleteDC.


Обратите внимание, возвращается указатель на CDC. Поэтому выделенное — неверно. Вы же не пытаетесь запихнуть CDC* в умный указатель? Впрочем, если пытаетесь, передайте ему deleter вида ReleaseDC.
Re[2]: CWnd::GetDC
От: Alexander G Украина  
Дата: 12.08.16 13:24
Оценка:
Здравствуйте, flаt, Вы писали:


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;
        }
Русский военный корабль идёт ко дну!
Re[2]: CWnd::GetDC
От: SkyKnight Швейцария https://github.com/dmitrigrigoriev/
Дата: 17.10.16 07:53
Оценка:
Здравствуйте, flаt, Вы писали:

F>Обратите внимание, возвращается указатель на CDC. Поэтому выделенное — неверно. Вы же не пытаетесь запихнуть CDC* в умный указатель? Впрочем, если пытаетесь, передайте ему deleter вида ReleaseDC.

В MFC функции типа XXX::FromHandle (там у многих классов есть такая статическая функция) возвращают указатель на временные объекты, эти объекты удаляются при следующем вызове OnIdle.
github.com/dmitrigrigoriev/
Re[3]: CWnd::GetDC
От: flаt  
Дата: 17.10.16 13:19
Оценка:
Здравствуйте, SkyKnight, Вы писали:

SK>В MFC функции типа XXX::FromHandle (там у многих классов есть такая статическая функция) возвращают указатель на временные объекты, эти объекты удаляются при следующем вызове OnIdle.


Хм. То есть, их нельзя сохранить у себя?
Re[4]: CWnd::GetDC
От: AlexGin Беларусь  
Дата: 18.10.16 07:01
Оценка:
Здравствуйте, flаt, Вы писали:

F>Здравствуйте, SkyKnight, Вы писали:


SK>>В MFC функции типа XXX::FromHandle (там у многих классов есть такая статическая функция) возвращают указатель на временные объекты, эти объекты удаляются при следующем вызове OnIdle.


F>Хм. То есть, их нельзя сохранить у себя?

То есть — они временные:
http://stackoverflow.com/questions/1504507/what-is-the-lifetime-of-a-cwnd-obtained-from-cwndfromhandle
http://forums.codeguru.com/showthread.php?111627-CWnd-FromHandle
а уже где, как и сколько времени их хранить — решать по месту
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.