WTL 中使用GDI+ 备忘

时间:2021-12-26 17:12:31

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的相关支持文件:

 

  1. #include <gidplus.h>  
  2. using namespace gdiplus;  
  3. #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;
}