Программирование на C ++, как только мы получим контекстное устройство от GetDC для использования. Что плохого может произойти, если мы выйдем из программы, не обращаясь к ReleaseDC?

7
jondinham 28 Авг 2011 в 11:37

3 ответа

Лучший ответ

Из документов

Функция ReleaseDC освобождает контекст устройства (DC), освобождая его для использования другими приложениями. Эффект функции ReleaseDC зависит от типа DC. Он освобождает только общие и оконные контроллеры домена. Это не влияет на классовые или частные контроллеры домена.

Как видите, это может понадобиться, если другие приложения могут получить доступ к тому же DC.

В любом случае для такого рода вещей рекомендуется использовать идиому RAII C ++. Рассмотрим этот класс:

class ScopedDC
{
   public:
      ScopedDC(HDC handle):handle(handle){}
      ~ScopedDC() { ReleaseDC(handle); }
      HDC get() const {return handle; }
   //disable copying. Same can be achieved by deriving from boost::noncopyable
   private:
      ScopedDC(const ScopedDC&);
      ScopedDC& operator = (const ScopedDC&); 

   private:
      HDC handle;
};

С помощью этого класса вы можете сделать это:

{
   ScopedDC dc(GetDC());
   //do stuff with dc.get();
}  //DC is automatically released here, even in case of exceptions
4
Armen Tsirunyan 28 Авг 2011 в 07:57

Приложение с утечками ресурсов, связанных с GDI, может перестать рисовать что-либо после некоторого времени непрерывной работы. Все окна приложений остаются пустыми, хотя внутренние вызовы GDI возвращают успех. «Приложение перестает рисовать» - это стандартный вопрос на досках сообщений по программированию Windows, когда у программы происходит утечка ресурсов.

4
Alex F 28 Авг 2011 в 09:07

Что плохого может случиться, если мы выйдем из программы , не позвонив в ReleaseDC?

Выход из программы автоматически освобождает все выделенные ресурсы, поэтому я согласен с комментариями Дэвида Хеффернана и Ханса Пассанта: ничего плохого не произойдет.

Выход из рутины, в которой вы использовали GetDC, - это отдельная история. Как уже указывал Армен Цирунян , ReleaseDC должен вызываться после получения контекста устройства общих и оконных контроллеров домена, в противном случае программа может работать в исключительной ситуации нехватки ресурсов из-за роста специального кэша системы для этих контроллеров домена. .

Теперь, может быть удобно узнать, является ли окно, из которого вы получаете DC, обычным или оконным DC. Один из способов получить эту информацию - посмотреть, имеет ли окно контекст частного устройства. См. Документацию о Контекстах устройства отображения :

Контексты частных устройств

... Контексты частных устройств не являются частью системного кеша, поэтому их не нужно освобождать после использования. ... Приложение создает частный контекст устройства, сначала указывая стиль оконного класса CS_OWNDC, когда оно инициализирует член стиля структуры WNDCLASS и вызывает RegisterClass ...

Таким образом, когда класс окна имеет установленный флаг CS_OWNDC, вам не нужно беспокоиться об освобождении DC, потому что он управляется самим окном, а не системным кешем. Вы можете получить этот параметр, вызвав GetClassInfo (Ex).

Но обратите внимание, что освобождение контроллера домена, полученного от GetDC, не влияет на классы или частные контроллеры домена, поэтому всегда разумно вызывать ReleaseDC после GetDC.

2
Community 20 Июн 2020 в 09:12