Re: MFC serialization of HICON
Mark,
my sincere apologies.
You are completely right, "serialize_ex.cpp" is not a part of MFC.
I just realize that it was implemented internally.
Following are overloads for HICON and HBITMAP (HBITMAP used by HICON
overload for mask and color bmps)
////////////////////////////////////////////////////////////////////////////////
// Archiving Bitmaps
CArchive& operator<<(CArchive &ar, const HBITMAP &hBitmap)
{
Bitmap bm(hBitmap,NULL);
// Get the class identifier for the PNG encoder.
CLSID pngClsid;
GetEncoderClsid(L"image/png", pngClsid);
//The CStream object will contain the Bitmap data
CStream bmStream(100*1000);
bm.Save(&bmStream,&pngClsid);
bmStream.Serialize(ar);
return ar;
}
CArchive& operator>>(CArchive &ar, HBITMAP &hBitmap)
{
CStream bmStream;
bmStream.Serialize(ar);
Bitmap bm(&bmStream);
Status sResult = bm.GetLastStatus();
if( sResult != Ok )
{
ASSERT(FALSE);
}
hBitmap = NULL;
sResult = bm.GetHBITMAP(Color::Black,(HBITMAP*)&hBitmap);
if( sResult != Ok )
{
ASSERT(FALSE);
}
return ar;
}
////////////////////////////////////////////////////////////////////////////////
// Archiving Icons
CArchive& operator<<(CArchive &ar, const HICON &hIcon)
{
ICONINFO info;
BOOL bResult = ::GetIconInfo(hIcon,&info);
if( !bResult )
{
DWORD dwError = ::GetLastError();
CString s;
s.Format(_T("Error: %d\n"),dwError);
::OutputDebugString(s);
ASSERT(FALSE);
}
ar << info.fIcon;
ar << info.xHotspot;
ar << info.yHotspot;
ar << info.hbmMask;
ar << info.hbmColor;
return ar;
}
CArchive& operator>>(CArchive &ar, HICON &hIcon)
{
ICONINFO info;
ar >> info.fIcon;
ar >> info.xHotspot;
ar >> info.yHotspot;
ar >> info.hbmMask;
ar >> info.hbmColor;
hIcon = ::CreateIconIndirect(&info);
if( hIcon == NULL )
{
DWORD dwError = GetLastError();
CString s;
s.Format(_T("Error: %d\n"),dwError);
::OutputDebugString(s);
ASSERT(FALSE);
}
::DeleteObject(info.hbmMask);
::DeleteObject(info.hbmColor);
return ar;
}
Storing seems to work but when loading, Bitmap bm(&bmStream) crashes.
Bitmap constructor is called in "GdiPlusBitmap.h"
(Bitmap::Bitmap(IN IStream *stream, IN BOOL useEmbeddedColorManagement) and
DllExports::GdipCreateBitmapFromStream(stream, &bitmap); throws but i can not
step in farther.
What makes me uneasy is that all of that code worked before i upgraded to VS
2008. I was using 2005 before.
Thank you again for looking into my issue.
Pawel Kozielski