最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

c++ - WM_CTLCOLORSTATIC but how to release hdc - Stack Overflow

programmeradmin1浏览0评论

I followed a Microsoft example for using WM_CTLCOLORSTATIC but am curious as to how to use DeleteObject.

If DeleteObject is placed after the return then it never gets used. Yet in the windows documentation it says you must DeleteObject. It mentions a dialog box being destroyed but that is not applicable to my case here.

I am trying to correct the background color in a couple of STATIC text box objects.

    case WM_CTLCOLORSTATIC:
    {
        hdc = ( HDC ) wParam;
        if ( lParam == ( LPARAM ) *phwndTextBox )
        {
            SetTextColor ( hdc, 0x000000 );
            SetBkColor ( hdc, 0xBEBEBE );
            return ( LRESULT ) CreateSolidBrush ( 0xBEBEBE );
 // Alternative     return ( LRESULT ) GetStockObject ( LTGRAY_BRUSH );
        }
        if ( lParam == ( LPARAM ) *phwndinfoBox01 )
        {
            SetTextColor ( hdc, 0x000000 );
            SetBkColor ( hdc, colorbkgnd01 );
            return ( LRESULT ) CreateSolidBrush ( colorbkgnd01 );
 // alternative     return ( LRESULT ) GetStockObject ( WHITE_BRUSH );
        }
    } break;

The code is being run in a callback function for a child window and I seem to be suffering a resource leak. I can see that the code would keep creating brushes here every time WM_CTLCOLORSTATIC is invoked. Apart from that I get the result I am looking for. If I use GetStockObject ( WHITE_BRUSH ) for instance it doesn't work the way I expect but I don't get the resource leak. I can't follow the logic if there is any. Any advice or help would be appreciated.

I followed a Microsoft example for using WM_CTLCOLORSTATIC but am curious as to how to use DeleteObject.

If DeleteObject is placed after the return then it never gets used. Yet in the windows documentation it says you must DeleteObject. It mentions a dialog box being destroyed but that is not applicable to my case here.

I am trying to correct the background color in a couple of STATIC text box objects.

    case WM_CTLCOLORSTATIC:
    {
        hdc = ( HDC ) wParam;
        if ( lParam == ( LPARAM ) *phwndTextBox )
        {
            SetTextColor ( hdc, 0x000000 );
            SetBkColor ( hdc, 0xBEBEBE );
            return ( LRESULT ) CreateSolidBrush ( 0xBEBEBE );
 // Alternative     return ( LRESULT ) GetStockObject ( LTGRAY_BRUSH );
        }
        if ( lParam == ( LPARAM ) *phwndinfoBox01 )
        {
            SetTextColor ( hdc, 0x000000 );
            SetBkColor ( hdc, colorbkgnd01 );
            return ( LRESULT ) CreateSolidBrush ( colorbkgnd01 );
 // alternative     return ( LRESULT ) GetStockObject ( WHITE_BRUSH );
        }
    } break;

The code is being run in a callback function for a child window and I seem to be suffering a resource leak. I can see that the code would keep creating brushes here every time WM_CTLCOLORSTATIC is invoked. Apart from that I get the result I am looking for. If I use GetStockObject ( WHITE_BRUSH ) for instance it doesn't work the way I expect but I don't get the resource leak. I can't follow the logic if there is any. Any advice or help would be appreciated.

Share Improve this question edited Nov 19, 2024 at 12:41 wohlstad 30.4k17 gold badges61 silver badges94 bronze badges asked Nov 19, 2024 at 12:40 PeterSPeterS 112 bronze badges 3
  • The MSDN documentation explains when you should call DeleteObject in this situation: "The brush must be destroyed by a call to the DeleteObject function when it is no longer needed, typically when the associated dialog box is destroyed." link – Eljay Commented Nov 19, 2024 at 12:52
  • 1 When you call CreateSolidBrush you become responsible for this GDI object. Failure to clean up produces a resource leak. You would typically clean up during WM_NCDESTROY message processing. A simpler way is to return a DC_BRUSH stock object instead, adjusting the color via SetDCBrushColor. You don't need to clean up stock objects. – IInspectable Commented Nov 19, 2024 at 16:22
  • Implicit is that you'll need this brush again soon, whenever you'll get a paint message. So making it static is normal, delete when the window gets deleted. – Hans Passant Commented Nov 19, 2024 at 17:58
Add a comment  | 

1 Answer 1

Reset to default 0

When you use CreateSolidBrush(), you are the owner of the HBRUSH and must free it when you are done using it. This is even stated in the WM_CTLCOLORSTATIC documentation:

If the application returns a brush that it created (for example, by using the CreateSolidBrush or CreateBrushIndirect function), the application must free the brush. If the application returns a system brush (for example, one that was retrieved by the GetStockObject or GetSysColorBrush function), the application does not need to free the brush.

So, you need to save the brushes you create so you can free them at a later time, for example:

HBRUSH hBrushForTextBox, hBrushForInfoBox;

...

case WM_CREATE:
{
    hBrushForTextBox = CreateSolidBrush ( 0xBEBEBE );
    hBrushForInfoBox = CreateSolidBrush ( colorbkgnd01 );
    break;
}

case WM_DESTROY:
{
    DeleteObject( hBrushForTextBox );
    DeleteObject( hBrushForInfoBox );
    break;
}

case WM_CTLCOLORSTATIC:
{
    ...
    if ( lParam == ( LPARAM ) *phwndTextBox )
    {
        ...
        return ( LRESULT ) hBrushForTextBox;
    }
    if ( lParam == ( LPARAM ) *phwndinfoBox01 )
    {
        ...
        return ( LRESULT ) hBrushForInfoBox;
    }
} break;
发布评论

评论列表(0)

  1. 暂无评论