winapi SelectObject - DeleteObject - когда нужно удалять обьект

140
30 декабря 2019, 09:00

Вопрос в удалении HGDIOBJ результата возвращаемого функцией SelectObject(..). Из MSDN документации вообще не очевидно когда надо удалять, там указывается понятие замещать - что не во всех случаях очевидно. Например такой код:

    HDC hdcMem = ::CreateCompatibleDC(hdc);
    HGDIOBJ hgdi = ::SelectObject(hdcMem, hbmp);
    GetObject(hbmp, sizeof(bitmap), &bitmap);
    ::StretchBlt(..., hdcMem, ...);
    /// ... много всякого всего ...
    ::DeleteObject(hgdi); // <- он тут нужен?
    ::DeleteDC(hdcMem);

или

    hdcc = ::CreateCompatibleDC(NULL);
    hobj = ::SelectObject(hdcc, hbmp);
    GetDIBits(hdcc, hbmp, ...);
    SetDIBits(hdcc, hbmp, ...);
    /// ... много всякого всего ...
    ::DeleteObject(hobj);  // <- он тут нужен?
    ::DeleteDC(hdcc);

Эта функция возвращает ранее выбранный объект указанного типа. Приложение должно всегда заменять новый объект оригинальным объектом по умолчанию после завершения рисования новым объектом.

https://docs.microsoft.com/ru-ru/windows/desktop/api/wingdi/nf-wingdi-selectobject

Answer 1

Удалять необходимо только те объекты GDI, которые вы сами создали. И удалять их можно только после того, как вы их "отселектили" из GDI контекста. Системные GDI объекты удалять нельзя.

В ваших примерах оба удаления некорректны. Удалять эти объекты нельзя - это системные объекты "по умолчанию", которые находились в контекстах до того, как вы выбрали туда свой объект hbmp. Я уверен, что попытки удаления таких системных объектов, не приведут ни к каким негативным последствиям - DeleteObject просто ничего не сделает. Но все равно это бессмысленная и некорректная операция.

Вместо удаления вам, как сказано в документации, надо выбрать эти объекты обратно в контекст

::SelectObject(hdcMem, hgdi);
::DeleteDC(hdcMem);
// ...
::SelectObject(hdcc, hobj);
::DeleteDC(hdcc);

Эти SelectObject, возможно, не обязательны, если вы все равно собираетесь следующим же шагом уничтожать эти контексты через DeleteDC. Но я бы все-таки их выполнял чисто из соображений аккуратности.

READ ALSO
Не получается создать службу виндовс

Не получается создать службу виндовс

Делаю лабораторную работуНужно создать программу, которая будет реализовывать со стороны сервера разные функции (создание документа, обновление...

172
Использование new

Использование new

В нескольких примерах на просторах сети можно найти следующие вещиДопустим имеем несколько определений:

165
Задача на С++ олимпиадная

Задача на С++ олимпиадная

Вокруг ведущего стоит N человек, которые пронумерованы по часовой стрелку числами от 1 до NВедущий, начиная с первого отсчитывает M человек...

163
Как вывести определенную часть файла?

Как вывести определенную часть файла?

Пишу несложную базу данных (использую простоtxt файлы) на c++ Вот так выглядят данные в файле

205