Add RAII AutoIconInfo class wrapping ICONINFO Windows struct.
This ensures that we never forget to delete the handles returned by GetIconInfo() and also centralizes the error message given if it fails in a single place. git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@78132 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
@@ -613,6 +613,33 @@ public:
|
|||||||
operator HRGN() const { return (HRGN)GetObject(); }
|
operator HRGN() const { return (HRGN)GetObject(); }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Class automatically freeing ICONINFO struct fields after retrieving it using
|
||||||
|
// GetIconInfo().
|
||||||
|
class AutoIconInfo : public ICONINFO
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
AutoIconInfo() { wxZeroMemory(*this); }
|
||||||
|
|
||||||
|
bool GetFrom(HICON hIcon)
|
||||||
|
{
|
||||||
|
if ( !::GetIconInfo(hIcon, this) )
|
||||||
|
{
|
||||||
|
wxLogLastError(wxT("GetIconInfo"));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
~AutoIconInfo()
|
||||||
|
{
|
||||||
|
if ( hbmColor )
|
||||||
|
::DeleteObject(hbmColor);
|
||||||
|
if ( hbmMask )
|
||||||
|
::DeleteObject(hbmMask);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
// class sets the specified clipping region during its life time
|
// class sets the specified clipping region during its life time
|
||||||
class HDCClipper
|
class HDCClipper
|
||||||
{
|
{
|
||||||
|
@@ -2375,15 +2375,17 @@ static wxImage LoadImageFromResource(const wxString &name, wxBitmapType type)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
ICONINFO info;
|
AutoIconInfo info;
|
||||||
if ( !::GetIconInfo(hIcon, &info) )
|
if ( !info.GetFrom(hIcon) )
|
||||||
{
|
|
||||||
wxLogLastError(wxT("GetIconInfo"));
|
|
||||||
return wxImage();
|
return wxImage();
|
||||||
}
|
|
||||||
|
|
||||||
hBitmap.Init(info.hbmColor);
|
hBitmap.Init(info.hbmColor);
|
||||||
hMask.Init(info.hbmMask);
|
hMask.Init(info.hbmMask);
|
||||||
|
|
||||||
|
// Reset the fields to prevent them from being destroyed, we took
|
||||||
|
// ownership of them.
|
||||||
|
info.hbmColor =
|
||||||
|
info.hbmMask = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if ( type == wxBITMAP_TYPE_CUR_RESOURCE )
|
else if ( type == wxBITMAP_TYPE_CUR_RESOURCE )
|
||||||
|
@@ -488,13 +488,9 @@ bool wxBitmap::CopyFromIconOrCursor(const wxGDIImage& icon,
|
|||||||
// it may be either HICON or HCURSOR
|
// it may be either HICON or HCURSOR
|
||||||
HICON hicon = (HICON)icon.GetHandle();
|
HICON hicon = (HICON)icon.GetHandle();
|
||||||
|
|
||||||
ICONINFO iconInfo;
|
AutoIconInfo iconInfo;
|
||||||
if ( !::GetIconInfo(hicon, &iconInfo) )
|
if ( !iconInfo.GetFrom(hicon) )
|
||||||
{
|
|
||||||
wxLogLastError(wxT("GetIconInfo"));
|
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
|
||||||
|
|
||||||
wxBitmapRefData *refData = new wxBitmapRefData;
|
wxBitmapRefData *refData = new wxBitmapRefData;
|
||||||
m_refData = refData;
|
m_refData = refData;
|
||||||
@@ -508,6 +504,10 @@ bool wxBitmap::CopyFromIconOrCursor(const wxGDIImage& icon,
|
|||||||
refData->m_height = h;
|
refData->m_height = h;
|
||||||
refData->m_depth = wxDisplayDepth();
|
refData->m_depth = wxDisplayDepth();
|
||||||
refData->m_hBitmap = (WXHBITMAP)iconInfo.hbmColor;
|
refData->m_hBitmap = (WXHBITMAP)iconInfo.hbmColor;
|
||||||
|
|
||||||
|
// Reset this field to prevent it from being destroyed by AutoIconInfo,
|
||||||
|
// we took ownership of it.
|
||||||
|
iconInfo.hbmColor = 0;
|
||||||
}
|
}
|
||||||
else // we only have monochrome icon/cursor
|
else // we only have monochrome icon/cursor
|
||||||
{
|
{
|
||||||
@@ -568,7 +568,7 @@ bool wxBitmap::CopyFromIconOrCursor(const wxGDIImage& icon,
|
|||||||
// alpha, so check for this.
|
// alpha, so check for this.
|
||||||
{
|
{
|
||||||
HBITMAP hdib = 0;
|
HBITMAP hdib = 0;
|
||||||
if ( CheckAlpha(iconInfo.hbmColor, &hdib) )
|
if ( CheckAlpha(refData->m_hBitmap, &hdib) )
|
||||||
refData->Set32bppHDIB(hdib);
|
refData->Set32bppHDIB(hdib);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@@ -586,9 +586,6 @@ bool wxBitmap::CopyFromIconOrCursor(const wxGDIImage& icon,
|
|||||||
refData->SetMask(wxInvertMask(iconInfo.hbmMask, w, h));
|
refData->SetMask(wxInvertMask(iconInfo.hbmMask, w, h));
|
||||||
}
|
}
|
||||||
|
|
||||||
// delete the old one now as we don't need it any more
|
|
||||||
::DeleteObject(iconInfo.hbmMask);
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
#else // __WXMICROWIN__ || __WXWINCE__
|
#else // __WXMICROWIN__ || __WXWINCE__
|
||||||
wxUnusedVar(icon);
|
wxUnusedVar(icon);
|
||||||
|
@@ -288,28 +288,20 @@ void ReverseBitmap(HBITMAP bitmap, int width, int height)
|
|||||||
|
|
||||||
HCURSOR CreateReverseCursor(HCURSOR cursor)
|
HCURSOR CreateReverseCursor(HCURSOR cursor)
|
||||||
{
|
{
|
||||||
ICONINFO info;
|
AutoIconInfo info;
|
||||||
if ( !::GetIconInfo(cursor, &info) )
|
if ( !info.GetFrom(cursor) )
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
HCURSOR cursorRev = NULL;
|
|
||||||
|
|
||||||
BITMAP bmp;
|
BITMAP bmp;
|
||||||
if ( ::GetObject(info.hbmMask, sizeof(bmp), &bmp) )
|
if ( !::GetObject(info.hbmMask, sizeof(bmp), &bmp) )
|
||||||
{
|
return NULL;
|
||||||
ReverseBitmap(info.hbmMask, bmp.bmWidth, bmp.bmHeight);
|
|
||||||
if ( info.hbmColor )
|
|
||||||
ReverseBitmap(info.hbmColor, bmp.bmWidth, bmp.bmHeight);
|
|
||||||
info.xHotspot = (DWORD)bmp.bmWidth - 1 - info.xHotspot;
|
|
||||||
|
|
||||||
cursorRev = ::CreateIconIndirect(&info);
|
ReverseBitmap(info.hbmMask, bmp.bmWidth, bmp.bmHeight);
|
||||||
}
|
|
||||||
|
|
||||||
::DeleteObject(info.hbmMask);
|
|
||||||
if ( info.hbmColor )
|
if ( info.hbmColor )
|
||||||
::DeleteObject(info.hbmColor);
|
ReverseBitmap(info.hbmColor, bmp.bmWidth, bmp.bmHeight);
|
||||||
|
info.xHotspot = (DWORD)bmp.bmWidth - 1 - info.xHotspot;
|
||||||
|
|
||||||
return cursorRev;
|
return ::CreateIconIndirect(&info);
|
||||||
}
|
}
|
||||||
|
|
||||||
} // anonymous namespace
|
} // anonymous namespace
|
||||||
|
@@ -663,12 +663,8 @@ wxSize wxGetHiconSize(HICON WXUNUSED_IN_WINCE(hicon))
|
|||||||
#ifndef __WXWINCE__
|
#ifndef __WXWINCE__
|
||||||
if ( hicon )
|
if ( hicon )
|
||||||
{
|
{
|
||||||
ICONINFO info;
|
AutoIconInfo info;
|
||||||
if ( !::GetIconInfo(hicon, &info) )
|
if ( info.GetFrom(hicon) )
|
||||||
{
|
|
||||||
wxLogLastError(wxT("GetIconInfo"));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
HBITMAP hbmp = info.hbmMask;
|
HBITMAP hbmp = info.hbmMask;
|
||||||
if ( hbmp )
|
if ( hbmp )
|
||||||
@@ -678,11 +674,7 @@ wxSize wxGetHiconSize(HICON WXUNUSED_IN_WINCE(hicon))
|
|||||||
{
|
{
|
||||||
size = wxSize(bm.bmWidth, bm.bmHeight);
|
size = wxSize(bm.bmWidth, bm.bmHeight);
|
||||||
}
|
}
|
||||||
|
|
||||||
::DeleteObject(info.hbmMask);
|
|
||||||
}
|
}
|
||||||
if ( info.hbmColor )
|
|
||||||
::DeleteObject(info.hbmColor);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -1736,9 +1736,8 @@ void wxGDIPlusContext::DrawIcon( const wxIcon &icon, wxDouble x, wxDouble y, wxD
|
|||||||
// the built-in conversion fails when there is alpha in the HICON (eg XP style icons), we can only
|
// the built-in conversion fails when there is alpha in the HICON (eg XP style icons), we can only
|
||||||
// find out by looking at the bitmap data whether there really was alpha in it
|
// find out by looking at the bitmap data whether there really was alpha in it
|
||||||
HICON hIcon = (HICON)icon.GetHICON();
|
HICON hIcon = (HICON)icon.GetHICON();
|
||||||
ICONINFO iconInfo ;
|
AutoIconInfo iconInfo ;
|
||||||
// IconInfo creates the bitmaps for color and mask, we must dispose of them after use
|
if (!iconInfo.GetFrom(hIcon))
|
||||||
if (!GetIconInfo(hIcon,&iconInfo))
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
Bitmap interim(iconInfo.hbmColor,NULL);
|
Bitmap interim(iconInfo.hbmColor,NULL);
|
||||||
@@ -1788,8 +1787,6 @@ void wxGDIPlusContext::DrawIcon( const wxIcon &icon, wxDouble x, wxDouble y, wxD
|
|||||||
m_context->DrawImage(image,(REAL) x,(REAL) y,(REAL) w,(REAL) h) ;
|
m_context->DrawImage(image,(REAL) x,(REAL) y,(REAL) w,(REAL) h) ;
|
||||||
|
|
||||||
delete image ;
|
delete image ;
|
||||||
DeleteObject(iconInfo.hbmColor);
|
|
||||||
DeleteObject(iconInfo.hbmMask);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void wxGDIPlusContext::DoDrawText(const wxString& str,
|
void wxGDIPlusContext::DoDrawText(const wxString& str,
|
||||||
|
Reference in New Issue
Block a user