WTL 中使用GDI+ 备忘
#include <gdiplus.h>
using namespace Gdiplus;
#pragma comment(lib, "gdiplus.lib")
_tWinMain
{
HRESULT hRes = ::CoInitialize(NULL);
GdiplusStartupInput gdiplusStartupInput;
ULONG_PTR gdiplusToken;
GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL);
。。。。。。
// uninitialize GDI+
GdiplusShutdown(gdiplusToken);
::CoUninitialize();
}
在vs直接建立的win32工程里直接添加GdiPlus的相关支持文件:
- #include <gidplus.h>
- using namespace gdiplus;
- #pragma comment(lib, "gdiplus.lib")
编译器会报几百个错误,都是些什么"缺少类型说明符",语法错误或者标识符错误之类的.
一般这种情况都是由于头文件引用缺少一些特殊的支持,或者引用顺序错误导致的.
网上的解决办法一般有两种:
1.关闭#include <windows.h>前面的WIN32_LEAN_AND_MEAN定义;
2.在导入GdiPlus支持文件之前添加#include <comdef.h>.
richedit 插入图片
BOOL CImageDataObject::InsertGraphic( IRichEditOle* pRichEditOle,CString strFilename )
{
LPSTORAGE m_lpStorage; // provides storage for m_lpObject
LPLOCKBYTES m_lpLockBytes; // part of implementation of m_lpStorage
LPOLEOBJECT m_lpObject; // in case you want direct access to the OLE object
LPVIEWOBJECT2 m_lpViewObject;// IViewObject for IOleObject above
CLSID clsid;
SCODE sc; //ret value
sc = ::CreateILockBytesOnHGlobal(NULL, TRUE, &m_lpLockBytes);
if (sc != S_OK)
throw(sc);
ATLASSERT(m_lpLockBytes != NULL);
sc = ::StgCreateDocfileOnILockBytes(m_lpLockBytes,
STGM_SHARE_EXCLUSIVE|STGM_CREATE|STGM_READWRITE, 0, &m_lpStorage);
if (sc != S_OK)
{
ATLVERIFY(m_lpLockBytes->Release() == 0);
m_lpLockBytes = NULL;
throw(sc);
}
// attempt to create the object
sc = ::OleCreateFromFile(CLSID_NULL, strFilename,
IID_IUnknown, OLERENDER_DRAW, NULL, NULL,
m_lpStorage, (void **)&m_lpObject);
if ( sc != S_OK )
{
TCHAR * lpMsgBuf;
::FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_SYSTEM, NULL,
::GetLastError(),
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
(LPTSTR) &lpMsgBuf, 0, NULL );
CString msg( lpMsgBuf );
msg = strFilename;
MessageBox(NULL,_T("haha"), msg, MB_OK );
::LocalFree( lpMsgBuf );
return FALSE;
}
// m_lpObject is currently an IUnknown, convert to IOleObject
if (m_lpObject != NULL)
{
LPUNKNOWN lpUnk = m_lpObject;
lpUnk->QueryInterface(IID_IOleObject, (LPVOID*)&m_lpObject);
lpUnk->Release();
if (m_lpObject == NULL)
throw(E_OUTOFMEMORY);
}
// cache the IViewObject interface
m_lpObject->QueryInterface(IID_IViewObject2, (LPVOID*)&m_lpViewObject);
if (m_lpViewObject == NULL)
return FALSE;
OleSetContainedObject(m_lpObject, TRUE);
REOBJECT reo;
memset( &reo, 0, sizeof( reo ) );
reo.cbStruct = sizeof( reo );
CLSID classID;
if ( m_lpObject->GetUserClassID( &classID ) != S_OK)
classID = CLSID_NULL;
reo.clsid = classID;
reo.cp = REO_CP_SELECTION;
reo.poleobj = m_lpObject;
reo.pstg = m_lpStorage;
LPOLECLIENTSITE lpClientSite;
pRichEditOle->GetClientSite( &lpClientSite );
reo.polesite = lpClientSite;
SIZEL sizel;
sizel.cx = sizel.cy = 0; // let richedit determine initial size
reo.sizel = sizel;
reo.dvaspect = DVASPECT_CONTENT;
reo.dwFlags = REO_RESIZABLE;
reo.dwUser = 0;
HRESULT hr = pRichEditOle->InsertObject( &reo );
m_lpViewObject->Release();
m_lpLockBytes->Release();
m_lpStorage->Release();
m_lpObject->Release();
return TRUE;
}
// returns true on success, false on failure
bool CImageDataObject::InsertBitmap(IRichEditOle* pRichEditOle, HBITMAP hBitmap)
{
SCODE sc;
// Get the image data object
//
CImageDataObject *pods = new CImageDataObject;
LPDATAOBJECT lpDataObject;
pods->QueryInterface(IID_IDataObject, (void **)&lpDataObject);
pods->SetBitmap(hBitmap);
// Get the RichEdit container site
//
IOleClientSite *pOleClientSite;
pRichEditOle->GetClientSite(&pOleClientSite);
// Initialize a Storage Object
//
IStorage *pStorage;
LPLOCKBYTES lpLockBytes = NULL;
sc = ::CreateILockBytesOnHGlobal(NULL, TRUE, &lpLockBytes);
if (sc != S_OK) {
pOleClientSite->Release();
return false;
}
sc = ::StgCreateDocfileOnILockBytes(lpLockBytes,
STGM_SHARE_EXCLUSIVE|STGM_CREATE|STGM_READWRITE, 0, &pStorage);
if (sc != S_OK) {
lpLockBytes = NULL;
pOleClientSite->Release();
return false;
}
// The final ole object which will be inserted in the richedit control
//
IOleObject *pOleObject;
pOleObject = pods->GetOleObject(pOleClientSite, pStorage);
if (pOleObject == NULL) {
pStorage->Release();
pOleClientSite->Release();
return false;
}
// all items are "contained" -- this makes our reference to this object
// weak -- which is needed for links to embedding silent update.
OleSetContainedObject(pOleObject, TRUE);
// Now Add the object to the RichEdit
//
REOBJECT reobject;
ZeroMemory(&reobject, sizeof(REOBJECT));
reobject.cbStruct = sizeof(REOBJECT);
CLSID clsid;
sc = pOleObject->GetUserClassID(&clsid);
if (sc != S_OK) {
pOleObject->Release();
pStorage->Release();
pOleClientSite->Release();
return false;
}
reobject.clsid = clsid;
reobject.cp = REO_CP_SELECTION ;
reobject.dvaspect = DVASPECT_CONTENT;
reobject.poleobj = pOleObject;
reobject.polesite = pOleClientSite;
reobject.pstg = pStorage;
reobject.dwFlags = REO_BELOWBASELINE;
// Insert the bitmap at the current location in the richedit control
//
sc = pRichEditOle->InsertObject(&reobject);
// Release all unnecessary interfaces
//
pOleObject->Release();
pOleClientSite->Release();
lpLockBytes->Release();
pStorage->Release();
lpDataObject->Release();
if (sc != S_OK)
return false;
else
return true;
}
void CImageDataObject::SetBitmap(HBITMAP hBitmap)
{
STGMEDIUM stgm;
stgm.tymed = TYMED_GDI; // Storage medium = HBITMAP handle
stgm.hBitmap = hBitmap;
stgm.pUnkForRelease = NULL; // Use ReleaseStgMedium
FORMATETC fm;
fm.cfFormat = CF_BITMAP; // Clipboard format = CF_BITMAP
fm.ptd = NULL; // Target Device = Screen
fm.dwAspect = DVASPECT_CONTENT; // Level of detail = Full content
fm.lindex = -1; // Index = Not applicaple
fm.tymed = TYMED_GDI; // Storage medium = HBITMAP handle
this->SetData(&fm, &stgm, TRUE);
}
IOleObject *CImageDataObject::GetOleObject(IOleClientSite *pOleClientSite, IStorage *pStorage)
{
SCODE sc;
IOleObject *pOleObject;
sc = ::OleCreateStaticFromData(this, IID_IOleObject, OLERENDER_FORMAT,
&m_format, pOleClientSite, pStorage, (void **)&pOleObject);
if (sc != S_OK)
pOleObject = NULL;
return pOleObject;
}
HBITMAP LoadAnImage(char* FileName)
{
// Use IPicture stuff to use JPG / GIF files
IPicture* p;
IStream* s;
IPersistStream* ps;
HGLOBAL hG;
void* pp;
FILE* fp;
// Read file in memory
fp = fopen(FileName,"rb");
if (!fp)
return NULL;
fseek(fp,0,SEEK_END);
int fs = ftell(fp);
fseek(fp,0,SEEK_SET);
hG = GlobalAlloc(GPTR,fs);
if (!hG)
{
fclose(fp);
return NULL;
}
pp = (void*)hG;
fread(pp,1,fs,fp);
fclose(fp);
// Create an IStream so IPicture can
// CreateStreamOnHGlobal(hG,false,&s);
if (!s)
{
GlobalFree(hG);
return NULL;
}
OleLoadPicture(s,0,false,IID_IPicture,(void**)&p);
if (!p)
{
s->Release();
GlobalFree(hG);
return NULL;
}
s->Release();
GlobalFree(hG);
HBITMAP hB = 0;
p->get_Handle((unsigned int*)&hB);
// Copy the image. Necessary, because upon p's release,
// the handle is destroyed.
HBITMAP hBB = (HBITMAP)CopyImage(hB,IMAGE_BITMAP,0,0,
LR_COPYRETURNORG);
p->Release();
return hBB;
}