写 ActiveX 控件有时会实现一些 Picture 类型的属性,或者在方法中传递 Picture 类型的参数。在 MFC 里,有一个名为 CPictureHolder 的类可以很方便的帮助程序员做这些工作,但是如果你使用 ATL 或者 BaseCtl 框架开发,则需要自己动手。故把 MFC 里的 CPictureHolder 类抽了出来,使之没有对 MFC 的依赖,以供来者用之。文件名为 picholder.h。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 |
#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__ |