GetDC(null) sanity check...Will this DC ever get released?
CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 4 of 4

Thread: GetDC(null) sanity check...Will this DC ever get released?

  1. #1
    Join Date
    Jun 2002
    Location
    Monte Carlo
    Posts
    129

    Question 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?

  2. #2
    VictorN's Avatar
    VictorN is offline Super Moderator Power Poster
    Join Date
    Jan 2003
    Location
    Wallisellen (ZH), Switzerland
    Posts
    18,998

    Re: GetDC(null) sanity check...Will this DC ever get released?

    Quote Originally Posted by mega Kluge View Post
    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:
    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.
    Victor Nijegorodov

  3. #3
    2kaud's Avatar
    2kaud is offline Super Moderator Power Poster
    Join Date
    Dec 2012
    Location
    England
    Posts
    5,837

    Re: GetDC(null) sanity check...Will this DC ever get released?

    Is calling GetDC() as the parameter to a method like this good practice?
    No. See Victor's post #2.

    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);
    ...
    Last edited by 2kaud; September 10th, 2017 at 06:23 AM. Reason: TyPo
    All advice is offered in good faith only. All my code is tested (unless stated explicitly otherwise) with the latest version of Microsoft Visual Studio (using the supported features of the latest standard) and is offered as examples only - not as production quality. I cannot offer advice regarding any other c/c++ compiler/IDE or incompatibilities with VS. You are ultimately responsible for the effects of your programs and the integrity of the machines they run on. Anything I post, code snippets, advice, etc is licensed as Public Domain https://creativecommons.org/publicdomain/zero/1.0/ and can be used without reference or acknowledgement. Also note that I only provide advice and guidance via the forums - and not via private messages!

    C++17 Compiler: Microsoft VS2017 (15.4.4)

  4. #4
    Join Date
    Jun 2002
    Location
    Monte Carlo
    Posts
    129

    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.

Tags for this Thread

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  


Windows Mobile Development Center


Click Here to Expand Forum to Full Width

This a Codeguru.com survey!


On-Demand Webinars (sponsored)