Согласно MSDNКак GDI :: DeleteObject точно работает
Функция DeleteObject удаляет логическое перо, кисть, шрифт, растровый, область или палитру, освобождая все системные ресурсы, связанные с объекта. После удаления объекта указанный дескриптор уже не является действительным.
Таким образом, один (я) подумал бы, что как только DeleteObject будет выполнен, ручка больше не действует. но что происходит с объектами, полученными :: GetObject(), когда я удаляю объект перед сохранением их с помощью других вызовов WinAPI?
HFONT hFont = reinterpret_cast<HFONT>(::SendMessage(hwndCtrl, WM_GETFONT, 0, 0));
if (nullptr == hFont)
{
LOG_ERROR(L"Invalid font specified");
return false;
}
LOGFONT font = { 0 };
if (0 == ::GetObject(hFont, sizeof(font), &font))
{
LOG_ERROR(L"Failed getting font");
return false;
}
font.lfHeight = nSize;
::DeleteObject(hFont);
HFONT hFontEx = ::CreateFontIndirect(&font);
LPARAM lparam = MAKELPARAM(TRUE, 0);
WPARAM wparam = (WPARAM)(hFontEx);
SendMessage(hwndCtrl, WM_SETFONT, wparam, lparam);
Как показано в следующем примере, если я решил удалить мой HFONT, перед отправкой нового сообщения с помощью SendMessage, я бы получить некоторые неожиданные результаты, когда другие элементы управления получает измененные их шрифт, как будто я вызвал утечку ручек.
GetObject() не возвращает объект, он возвращает описание объекта. LOGFONT в случае шрифта. Удаление шрифта не приводит к недействительности этой структуры. Ваш код прослушивается, вы уничтожаете шрифт, который вы не создали. Несчастные случаи являются довольно неизбежными. Вам нужно будет зависеть от того окна, в которое вы отправляете сообщение WM_SETFONT, чтобы знать, как управлять дескриптором шрифта самостоятельно. Ожидается, что это будет сделано правильно. Удалите вызов DeleteObject(), это ошибка. –