GetDC(null) sanity check...Will this DC ever get released?
I'm running some legacy code that eventually fails on GetDC(null). It will return NULL with GetLastError() returning 0. The documention I've read says that the culprit is a GDI resource leak somewhere.
Fair enough.
A lot of the code has calls to GetDC() like so:
Code:
m_hOldBmp = (HBITMAP) ::SelectObject(GetDC(), m_hBmp);
// and
m_hBmp = ::CreateDIBSection(GetDC(), (BITMAPINFO*) &bmih, DIB_RGB_COLORS, NULL,NULL, 0 );
I can't find in the documentation if the DC returned from these GetDC() calls will ever be released. They aren't being released in the code. I've run handle leak profilers and nothing is amiss. However, sure enough, after enough hours, the software will fail and all calls to GetDC() will return NULL.
Is calling GetDC() as the parameter to a method like this good practice? Should something different be done here?
Re: GetDC(null) sanity check...Will this DC ever get released?
Quote:
Originally Posted by
mega Kluge
I'm running some legacy code that eventually fails on GetDC(null). It will return NULL with GetLastError() returning 0. The documention I've read says that the culprit is a GDI resource leak somewhere.
Fair enough.
A lot of the code has calls to GetDC() like so:
Code:
m_hOldBmp = (HBITMAP) ::SelectObject(GetDC(), m_hBmp);
// and
m_hBmp = ::CreateDIBSection(GetDC(), (BITMAPINFO*) &bmih, DIB_RGB_COLORS, NULL,NULL, 0 );
I can't find in the documentation if the DC returned from these GetDC() calls will ever be released. They aren't being released in the code. I've run handle leak profilers and nothing is amiss. However, sure enough, after enough hours, the software will fail and all calls to GetDC() will return NULL.
Is calling GetDC() as the parameter to a method like this good practice? Should something different be done here?
I have no idea where you searched for docs about GetDC() and whether "the DC ... will ever be released", however MSDN claims it clear enough:
Quote:
After painting with a common DC, the ReleaseDC function must be called to release the DC. Class and private DCs do not have to be released. ReleaseDC must be called from the same thread that called GetDC. The number of DCs is limited only by available memory.
Re: GetDC(null) sanity check...Will this DC ever get released?
Quote:
Is calling GetDC() as the parameter to a method like this good practice?
No. See Victor's post #2.
Quote:
Should something different be done here?
For every GetDC() used, there must be a corresponding ReleaseDC() as per the MSDN documentation. See https://msdn.microsoft.com/en-us/lib...(v=vs.85).aspx re ReleaseDC().
Often you'll find code that at the start of a function/block obtains a DC with GetDC() and then at the end of the function/block calls ReleaseDC(). Note that ReleaseDC() requires both the DC handle and the windows handle. Note that even in the case of errors occurring from tested API return values, once GetDC() has been called, then ReleaseDC() still needs to be called. If you're using c++, then a RAII class can be used to obtain a DC and to ensure that ReleaseDC() is always called correctly.
PS Is GetDC() as used in the code in post #1 defined in the program elsewhere - as the standard Windows GetDC() takes a parameter of type HWND?
For a simple c++ class for DC, consider
Code:
class MyDC
{
public:
MyDC(HWND win) : hwnd(win), dc(::GetDC(win)) {}
~MyDC()
{
::ReleaseDC(hwnd, dc);
}
MyDC(const MyDC&) = delete;
MyDC& operator=(const MyDC&) = delete;
HDC GetDC() const
{
return dc;
}
private:
HDC dc;
HWND hwnd;
};
and useage
Code:
...
MyDC mydc(hwnd);
...
m_hOldBmp = (HBITMAP) ::SelectObject(mydc.GetDC(), m_hBmp);
...
Re: GetDC(null) sanity check...Will this DC ever get released?
Thanks gentleman. I see now the cause of my confusion and the probable source of the problem. There are handwritten GetDC() methods (as in 2kaud's example) sprinkled close together with MS GetDC() methods. (The handwritten method properly releases the DC in the destructor.) These are used all over the place, close together, and easily mixed up. (At least by me.) Some of the calls to MS DC are used in the same manner and are definitely not being released leading to problems after a period of continuous processing.
I appreciate your time. Sometimes getting outside input helps tremedously.