导读:
写 ActiveX 控件有时会实现一些 Picture 类型的属性,或者在方法中传递 Picture 类型的参数。在 MFC 里,有一个名为 CPictureHolder 的类可以很方便的帮助程序员做这些工作,但是如果你使用 ATL 或者 BaseCtl 框架开发,则需要自己动手。故把 MFC 里的?CPictureHolder 类抽了出来,使之没有对 MFC 的依赖,以供来者用之。文件名为 picholder.h。
#ifndef __PICHOLDER_H__
#define __PICHOLDER_H__
/*
Demo code:
1. IDL code
[id(1)] HRESULT GetPicture([out, retval] LPPICTUREDISP *pVal);
[id(2)] HRESULT SetPicture([in] LPPICTUREDISP newVal);
2. C++ code
CPictureHolder m_pic;
STDMETHOD(GetPicture)(LPPICTUREDISP *pVal)
{
LPPICTUREDISP pPic = m_pic.GetPictureDispatch();
if(pPic != NULL)
*pVal = pPic;
return pPic ? S_OK : E_FAIL;
}
STDMETHOD(SetPicture)(LPPICTUREDISP newVal)
{
m_pic.SetPictureDispatch(newVal);
return S_OK;
}
Note:
When you compile an .idl file with IFontDisp or IPictureDisp as parameters
of methods in Visual C++ 5.0 or Visual C++ 6.0, you get a MIDL2039 warning.
This is due to a bug in Ocidl.idl source. You must add the dual attribute
to the interface declarations for IFontDisp and IPictureDisp.
Microsoft has confirmed this to be a bug.
This problem was corrected in Microsoft Visual C++ .NET.
// */
#ifndef ASSERT
#ifdef ATLASSERT
#define ASSERT ATLASSERT
#else
#define ASSERT sizeof
#endif // ATLASSERT
#endif // ASSERT
__inline
DWORD _Release(LPUNKNOWN* lplpUnknown)
{
ASSERT(lplpUnknown != NULL);
if(*lplpUnknown != NULL)
{
DWORD dwRef = (*lplpUnknown)->Release();
*lplpUnknown = NULL;
return dwRef;
}
return 0;
}
#define RELEASE(lpUnk) _Release((LPUNKNOWN*)&lpUnk)
class CPictureHolder
{
public:
LPPICTURE m_pPict;
public:
CPictureHolder() : m_pPict(NULL)
{
}
~CPictureHolder()
{
RELEASE(m_pPict);
}
BOOL CreateEmpty()
{
RELEASE(m_pPict);
PICTDESC pdesc;
pdesc.cbSizeofstruct = sizeof(pdesc);
pdesc.picType = PICTYPE_NONE;
return SUCCEEDED(::OleCreatePictureIndirect(&pdesc, IID_IPicture, FALSE, (LPVOID*)&m_pPict));
}
BOOL CreateFromBitmap(HBITMAP hbm, HPALETTE hpal = NULL, BOOL bTransferOwnership = FALSE)
{
RELEASE(m_pPict);
PICTDESC pdesc;
pdesc.cbSizeofstruct = sizeof(pdesc);
pdesc.picType = PICTYPE_BITMAP;
pdesc.bmp.hbitmap = hbm;
pdesc.bmp.hpal = hpal;
return SUCCEEDED(::OleCreatePictureIndirect(&pdesc, IID_IPicture, bTransferOwnership, (LPVOID*)&m_pPict));
}
BOOL CreateFromMetafile(HMETAFILE hmf, int xExt, int yExt, BOOL bTransferOwnership = FALSE)
{
RELEASE(m_pPict);
PICTDESC pdesc;
pdesc.cbSizeofstruct = sizeof(pdesc);
pdesc.picType = PICTYPE_METAFILE;
pdesc.wmf.hmeta = hmf;
pdesc.wmf.xExt = xExt;
pdesc.wmf.yExt = yExt;
return SUCCEEDED(::OleCreatePictureIndirect(&pdesc, IID_IPicture, bTransferOwnership, (LPVOID*)&m_pPict));
}
BOOL CreateFromIcon(HICON hIcon, BOOL bTransferOwnership = FALSE)
{
RELEASE(m_pPict);
PICTDESC pdesc;
pdesc.cbSizeofstruct = sizeof(pdesc);
pdesc.picType = PICTYPE_ICON;
pdesc.icon.hicon = hIcon;
return SUCCEEDED(::OleCreatePictureIndirect(&pdesc, IID_IPicture, bTransferOwnership, (LPVOID*)&m_pPict));
}
LPPICTUREDISP GetPictureDispatch()
{
LPPICTUREDISP pPictDisp = NULL;
if((m_pPict != NULL) &&SUCCEEDED(m_pPict->QueryInterface(IID_IPictureDisp, (LPVOID*)&pPictDisp)))
{
ASSERT(pPictDisp != NULL);
}
return pPictDisp;
}
void SetPictureDispatch(LPPICTUREDISP pDisp)
{
LPPICTURE pPict = NULL;
if(m_pPict != NULL)
m_pPict->Release();
if((pDisp != NULL) &&SUCCEEDED(pDisp->QueryInterface(IID_IPicture, (LPVOID*)&pPict)))
{
ASSERT(pPict != NULL);
m_pPict = pPict;
}
else
{
m_pPict = NULL;
}
}
void Render(HDC hdc, const RECT& rcRender, const RECT& rcWBounds)
{
if(m_pPict != NULL)
{
long hmWidth;
long hmHeight;
m_pPict->get_Width(&hmWidth);
m_pPict->get_Height(&hmHeight);
m_pPict->Render(hdc, rcRender.left, rcRender.top,
rcRender.right - rcRender.left, rcRender.bottom - rcRender.top, 0, hmHeight-1,
hmWidth, -hmHeight, &rcWBounds);
}
}
short GetType()
{
short sPicType = (short)PICTYPE_UNINITIALIZED;
if(m_pPict != NULL)
{
m_pPict->get_Type(&sPicType);
}
return sPicType;
}
};
#endif // __PICHOLDER_H__
本文转自
http://sluttery.spaces.live.com/blog/cns!3569FEA80C717FD4!173.entry
写 ActiveX 控件有时会实现一些 Picture 类型的属性,或者在方法中传递 Picture 类型的参数。在 MFC 里,有一个名为 CPictureHolder 的类可以很方便的帮助程序员做这些工作,但是如果你使用 ATL 或者 BaseCtl 框架开发,则需要自己动手。故把 MFC 里的?CPictureHolder 类抽了出来,使之没有对 MFC 的依赖,以供来者用之。文件名为 picholder.h。
#ifndef __PICHOLDER_H__
#define __PICHOLDER_H__
/*
Demo code:
1. IDL code
[id(1)] HRESULT GetPicture([out, retval] LPPICTUREDISP *pVal);
[id(2)] HRESULT SetPicture([in] LPPICTUREDISP newVal);
2. C++ code
CPictureHolder m_pic;
STDMETHOD(GetPicture)(LPPICTUREDISP *pVal)
{
LPPICTUREDISP pPic = m_pic.GetPictureDispatch();
if(pPic != NULL)
*pVal = pPic;
return pPic ? S_OK : E_FAIL;
}
STDMETHOD(SetPicture)(LPPICTUREDISP newVal)
{
m_pic.SetPictureDispatch(newVal);
return S_OK;
}
Note:
When you compile an .idl file with IFontDisp or IPictureDisp as parameters
of methods in Visual C++ 5.0 or Visual C++ 6.0, you get a MIDL2039 warning.
This is due to a bug in Ocidl.idl source. You must add the dual attribute
to the interface declarations for IFontDisp and IPictureDisp.
Microsoft has confirmed this to be a bug.
This problem was corrected in Microsoft Visual C++ .NET.
// */
#ifndef ASSERT
#ifdef ATLASSERT
#define ASSERT ATLASSERT
#else
#define ASSERT sizeof
#endif // ATLASSERT
#endif // ASSERT
__inline
DWORD _Release(LPUNKNOWN* lplpUnknown)
{
ASSERT(lplpUnknown != NULL);
if(*lplpUnknown != NULL)
{
DWORD dwRef = (*lplpUnknown)->Release();
*lplpUnknown = NULL;
return dwRef;
}
return 0;
}
#define RELEASE(lpUnk) _Release((LPUNKNOWN*)&lpUnk)
class CPictureHolder
{
public:
LPPICTURE m_pPict;
public:
CPictureHolder() : m_pPict(NULL)
{
}
~CPictureHolder()
{
RELEASE(m_pPict);
}
BOOL CreateEmpty()
{
RELEASE(m_pPict);
PICTDESC pdesc;
pdesc.cbSizeofstruct = sizeof(pdesc);
pdesc.picType = PICTYPE_NONE;
return SUCCEEDED(::OleCreatePictureIndirect(&pdesc, IID_IPicture, FALSE, (LPVOID*)&m_pPict));
}
BOOL CreateFromBitmap(HBITMAP hbm, HPALETTE hpal = NULL, BOOL bTransferOwnership = FALSE)
{
RELEASE(m_pPict);
PICTDESC pdesc;
pdesc.cbSizeofstruct = sizeof(pdesc);
pdesc.picType = PICTYPE_BITMAP;
pdesc.bmp.hbitmap = hbm;
pdesc.bmp.hpal = hpal;
return SUCCEEDED(::OleCreatePictureIndirect(&pdesc, IID_IPicture, bTransferOwnership, (LPVOID*)&m_pPict));
}
BOOL CreateFromMetafile(HMETAFILE hmf, int xExt, int yExt, BOOL bTransferOwnership = FALSE)
{
RELEASE(m_pPict);
PICTDESC pdesc;
pdesc.cbSizeofstruct = sizeof(pdesc);
pdesc.picType = PICTYPE_METAFILE;
pdesc.wmf.hmeta = hmf;
pdesc.wmf.xExt = xExt;
pdesc.wmf.yExt = yExt;
return SUCCEEDED(::OleCreatePictureIndirect(&pdesc, IID_IPicture, bTransferOwnership, (LPVOID*)&m_pPict));
}
BOOL CreateFromIcon(HICON hIcon, BOOL bTransferOwnership = FALSE)
{
RELEASE(m_pPict);
PICTDESC pdesc;
pdesc.cbSizeofstruct = sizeof(pdesc);
pdesc.picType = PICTYPE_ICON;
pdesc.icon.hicon = hIcon;
return SUCCEEDED(::OleCreatePictureIndirect(&pdesc, IID_IPicture, bTransferOwnership, (LPVOID*)&m_pPict));
}
LPPICTUREDISP GetPictureDispatch()
{
LPPICTUREDISP pPictDisp = NULL;
if((m_pPict != NULL) &&SUCCEEDED(m_pPict->QueryInterface(IID_IPictureDisp, (LPVOID*)&pPictDisp)))
{
ASSERT(pPictDisp != NULL);
}
return pPictDisp;
}
void SetPictureDispatch(LPPICTUREDISP pDisp)
{
LPPICTURE pPict = NULL;
if(m_pPict != NULL)
m_pPict->Release();
if((pDisp != NULL) &&SUCCEEDED(pDisp->QueryInterface(IID_IPicture, (LPVOID*)&pPict)))
{
ASSERT(pPict != NULL);
m_pPict = pPict;
}
else
{
m_pPict = NULL;
}
}
void Render(HDC hdc, const RECT& rcRender, const RECT& rcWBounds)
{
if(m_pPict != NULL)
{
long hmWidth;
long hmHeight;
m_pPict->get_Width(&hmWidth);
m_pPict->get_Height(&hmHeight);
m_pPict->Render(hdc, rcRender.left, rcRender.top,
rcRender.right - rcRender.left, rcRender.bottom - rcRender.top, 0, hmHeight-1,
hmWidth, -hmHeight, &rcWBounds);
}
}
short GetType()
{
short sPicType = (short)PICTYPE_UNINITIALIZED;
if(m_pPict != NULL)
{
m_pPict->get_Type(&sPicType);
}
return sPicType;
}
};
#endif // __PICHOLDER_H__
本文转自
http://sluttery.spaces.live.com/blog/cns!3569FEA80C717FD4!173.entry