Какие плохие вещи могут случиться без обращения к ReleaseDC? - PullRequest
7 голосов
/ 28 августа 2011

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

Ответы [ 3 ]

4 голосов
/ 28 августа 2011

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

4 голосов
/ 28 августа 2011

С документы

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

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

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

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
2 голосов
/ 28 августа 2011

Какие плохие вещи могут случиться, если мы выйдем из программы без вызова ReleaseDC?

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

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

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

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

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

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

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

...