Click here to Skip to main content
15,074,394 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
I read elsewhere that someone gave an example that locked up their program. I am interested in if it is a C++11 cleanup problem. They are using C++11, 32 bit windows, codeblocks 17.12 . Moving an image around on a window. Calling the function that contains this line often.

SelectObject(hdcWorkingBackBuffer, CreateCompatibleBitmap(hdc, prc->right, prc->bottom));


Thanks.

What I have tried:

Google Search. MSDN. Looking for logic to this.
Posted
Updated 13-Aug-21 5:33am

If that line of code is repeatedly executed then Windows could run out of handles. Every SelectObject call needs a corresponding DeleteObject to release the resource back to the system.
   
Comments
Member 15078716 13-Aug-21 12:17pm
   
Thank you. I still do not know why when I have this line inside of a proceedure then C++11 does not do an automatic cleanup or does not release the resource back to the system. I thought that C++11 did this automatically.

Maybe it is better to make certain that I hard code the release of resources my self in case C++11 (or the compiler) misses it.
Richard MacCutchan 13-Aug-21 12:41pm
   
This is nothing to do with C++. SelectObject is a pure Win32 (i.e plain C code) resource call so C++ has no knowledge of it. There is also the issue that you are not saving the object returned by the call, or saving the HBITMAp, so you have two resource leaks which can (if you run it enough times) cause the Windows lockup. What you should be doing is something like:
HBITMAP bm = CreateCompatibleBitmap(...);
HOBJECT obj = SelectObject(hDC, bm) // save the original object returned by this call
// do the other GUI operations
SelectObject(hDC, obj); // restore the original object to the DC
DeleteObject(bm);

And don't forget to call DeletObject on any others you created.


Sorry about the reposts, the editor keeps screwing up the formatting.
As Richard stated, it is possible. This is an instance where the automatic construction/destruction mechanism of C++ can come in very handy. The late Paul DiLascia used to write about the concept of excursion classes and this is an ideal candidate for one. I use them often and I made one specifically for selecting objects.

Here is a partial listing of it that uses handles and not their MFC counterparts :
C++
class CSelectObject
{
public:
    CSelectObject()                                 {}
    CSelectObject( HDC hDC, HGDIOBJ hObject, bool autodelete=false )
    {
        Select( hDC, hObject, autodelete );
    }

    void Select( HDC hDC, HGDIOBJ hObject, bool autodelete=false )
    {
        m_hDC = hDC;
        m_hOldObject = SelectObject( hDC, hObject );
        m_Delete = autodelete;
    }

    virtual ~CSelectObject()
    {
        if( m_hDC )
            SelectObject( m_hDC, m_hOldObject );
        if( m_Delete )
            DeleteObject( m_hOldObject );
    }

protected:
    HGDIOBJ m_hOldObject        { nullptr };
    HDC     m_hDC               { nullptr };
    bool    m_Delete            { false };
};
if used for this case the code could look like this :
C++
auto hbmp = CreateCompatibleBitmap( hdc, prc->right, prc->bottom );
CSelectObject selbmp( hdcWorkingBackBuffer, hmp, true );
// more code goes here
When the selbmp object falls out of scope the previous handle will be selected back into the context and the bitmap object will be deleted.
   
Comments
Member 15078716 13-Aug-21 12:17pm
   
Is your example more cross platform than using

HBITMAP hbm1 = CreateCompatibleBitmap(hdc, prc->right, prc->bottom);
SelectObject(hdcWorkingBackBuffer, hbm1);
DeleteObject(hbm1);

?

And, would your example use more cpu and/or memory?

Thank you.
Rick York 13-Aug-21 13:18pm
   
I am not sure what "more cross platform than using ..." means. This technique can be modified to work on any platform with any type of objects. It's somewhat less useful on platforms that don't work like windows where various types of objects are selected to be active at various times.

As for using more CPU and/or memory : the class has three simple members that use less than 20 bytes on a 64-bit system and no new resources. That means very little memory use and there won't be enough CPU use to worry about.
Richard MacCutchan 13-Aug-21 12:48pm
   
+5; neat solution.
Rick York 13-Aug-21 13:18pm
   
Thank you.

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)




CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900