void CTestflexgridDlg::OnSelectbmp()
{
IDispatch* pDisp = 0;
PICTDESC pictDesc;
memset(&pictDesc, 0, sizeof(pictDesc));
pictDesc.cbSizeofstruct = sizeof(pictDesc);
pictDesc.bmp.hpal = 0;
UpdateData(TRUE);
switch(m_nPicture)
{
case 0:
{
pictDesc.bmp.hbitmap = m_ctlYellow.GetBitmap();
pictDesc.picType = PICTYPE_BITMAP;
HRESULT hr;
hr = OleCreatePictureIndirect(&pictDesc,
IID_IDispatch,
FALSE,
(void**)&pDisp);
if(SUCCEEDED(hr))
{
ExamineIPicture(pDisp);
m_flexgrid.SetRefCellPicture(pDisp);
pDisp->Release();
} else
{
AfxMessageBox("Couldn't create the/
Picture interface");
}
}
break;
case 1:
{
// Similar treatment for this bitmap
}
break;
case 2:
{
// Similar treatment for this bitmap
}
break;
default :
break;
}
}
Figure 3 Displaying the Icon
void CTestflexgridDlg::DoIcon()
{
HICON hIcon;
hIcon = ::LoadIcon(AfxGetApp()->m_hInstance,
MAKEINTRESOURCE(IDC_ANICON));
if(hIcon)
{
pictDesc.icon.hicon = hIcon;
pictDesc.picType = PICTYPE_ICON;
HRESULT hr;
hr = OleCreatePictureIndirect(&pictDesc,
IID_IDispatch,
FALSE,
(void**)&pDisp);
if(SUCCEEDED(hr))
{
m_flexgrid.SetRefCellPicture(pDisp);
pDisp->Release();
} else
{
AfxMessageBox("Couldn't create the icon interface");
}
}
Figure 4 The PICTDESC Structure
typedef struct tagPICTDESC
{
UINT cbSizeOfStruct;
UINT picType;
union
{
struct
{
HBITMAP hbitmap;
HPALETTE hpal;
} bmp;
struct
{
HMETAFILE hmeta;
int xExt;
int yExt;
} wmf;
struct
{
HICON hicon;
} icon;
struct
{
HENHMETAFILE hemf;
} emf;
};
} PICTDESC;
Figure 6 The IPicture Interface
IPicture : public IUnknown
{
HRESULT get_Handle(OLE_HANDLE *pHandle) = 0;
HRESULT get_hPal(OLE_HANDLE *phPal) = 0;
HRESULT get_Type(SHORT *pType) = 0;
HRESULT get_Width(OLE_XSIZE_HIMETRIC *pWidth) = 0;
HRESULT get_Height(OLE_YSIZE_HIMETRIC *pHeight) = 0;
HRESULT Render(HDC hDC, LONG x, LONG y,
LONG cx, LONG cy,
OLE_XPOS_HIMETRIC xSrc,
OLE_YPOS_HIMETRIC ySrc,
OLE_XSIZE_HIMETRIC cxSrc,
OLE_YSIZE_HIMETRIC cySrc,
LPCRECT pRcWBounds) = 0;
HRESULT set_hPal(OLE_HANDLE hPal) = 0;
HRESULT get_CurDC(HDC *phDC) = 0;
HRESULT SelectPicture(HDC hDCIn, HDC *phDCOut,
OLE_HANDLE *phBmpOut) = 0;
HRESULT get_KeepOriginalFormat(BOOL *pKeep) = 0;
HRESULT put_KeepOriginalFormat(BOOL keep) = 0;
HRESULT PictureChanged(void) = 0;
HRESULT SaveAsFile(LPSTREAM pStream,
BOOL fSaveMemCopy,
LONG *pCbSize) = 0;
HRESULT get_Attributes(DWORD *pDwAttr) = 0;
};
Figure 7 Connecting to the Property Notification Sink
struct CPropertyNotifySinkImpl : public IPropertyNotifySink
{
ULONG m_cRef;
CPropertyNotifySinkImpl()
{
m_cRef = 0;
}
STDMETHODIMP QueryInterface(REFIID riid, void** ppv)
{
if(riid == IID_IUnknown ||
riid == IID_IPropertyNotifySink)
{
*ppv = static_cast<IPropertyNotifySink*>(this);
((IUnknown*)*ppv)->AddRef();
return S_OK;
} else
{
*ppv = 0;
return E_NOINTERFACE;
}
}
STDMETHODIMP_(ULONG) AddRef()
{
return m_cRef++;
}
STDMETHODIMP_(ULONG) Release()
{
m_cRef--;
if(m_cRef == 0)
{
return 0;
} else
{
return m_cRef;
}
}
STDMETHODIMP OnChanged(DISPID dispid)
{
CString str;
str.Format("Changed Property #%ld", dispid);
AfxMessageBox(str);
return S_OK;
}
STDMETHODIMP OnRequestEdit(DISPID dispid)
{
return S_FALSE;
}
};
// Global instance of the property notification sink
CPropertyNotifySinkImpl g_propNotifySink;
IPropertyNotifySink* g_pPropNotifySink =
static_cast<IPropertyNotifySink*>(&g_propNotifySink);
DWORD g_cookie;
void SetupConnection(IUnknown* pUnk)
{
IConnectionPointContainer* pCPC = 0;
HRESULT hr = pUnk->QueryInterface(&pCPC);
if(SUCCEEDED(hr))
{
IEnumConnectionPoints* pECP = 0;
IConnectionPoint* pCP = 0;
hr = pCPC->FindConnectionPoint(IID_IPropertyNotifySink,
&pCP);
if(SUCCEEDED(hr))
{
hr = pCP->Advise(g_pPropNotifySink,
&g_cookie);
pCP->Release();
}
pCPC->Release();
}
}
void TeardownConnection(IUnknown* pUnk)
{
IConnectionPointContainer* pCPC = 0;
HRESULT hr = pUnk->QueryInterface(&pCPC);
if(SUCCEEDED(hr))
{
IConnectionPoint* pCP = 0;
hr = pCPC->FindConnectionPoint(__uuidof(pCPC),
&pCP);
if(SUCCEEDED(hr))
{
pCP->Unadvise(g_cookie);
pCP->Release();
}
pCPC->Release();
}
}
Figure 8 Saving an Image to a Stream
void SaveThePicture(IUnknown* pUnk)
{
IPicture* pPicture = 0;
HRESULT hr = pUnk->QueryInterface(&pPicture);
if(SUCCEEDED(hr))
{
IStorage* pStg = 0;
hr = ::StgCreateDocfile(L"c:\\picttest",
STGM_SHARE_EXCLUSIVE |
STGM_CREATE |
STGM_READWRITE,
0, &pStg);
if(SUCCEEDED(hr))
{
IStream* pStream = 0;
hr = pStg->CreateStream(L"PICTURE",
STGM_SHARE_EXCLUSIVE |
STGM_CREATE |
STGM_READWRITE,
0, 0, &pStream);
if(SUCCEEDED(hr))
{
hr = pPicture->SaveAsFile(pStream,
TRUE, // save mem copy
NULL);
pStream->Release();
}
pStg->Release();
}
pPicture->Release();
}
}
Figure 9 Loading an Image from a Stream
void CTestflexgridDlg::OnLoadsavedbitmap()
{
IStorage* pStg = 0;
HRESULT hr;
hr = ::StgOpenStorage(L"c:\\picttest",
NULL,
STGM_SHARE_EXCLUSIVE |
STGM_READ,
NULL, 0, &pStg);
if(SUCCEEDED(hr))
{
IStream* pStream = 0;
hr = pStg->OpenStream(L"PICTURE", NULL,
STGM_SHARE_EXCLUSIVE |
STGM_READ,
0, &pStream);
if(SUCCEEDED(hr))
{
IDispatch* pDispatch;
hr = ::OleLoadPicture(pStream,
0, // read entire stream
TRUE,
IID_IDispatch,
(void**)&pDispatch);
if(SUCCEEDED(hr))
{
m_flexgrid.SetRefCellPicture(pDispatch);
pDispatch->Release();
}
pStream->Release();
}
pStg->Release();
}
}