Exemple #1
0
void UIIMEdit::InsertImage(BSTR bstrFileName,SIZE size,BOOL isGif)
{
	LPSTORAGE lpStorage = NULL;
	LPOLEOBJECT	lpObject = NULL;
	LPLOCKBYTES lpLockBytes = NULL;
	LPOLECLIENTSITE lpClientSite = NULL;
	GifSmiley::IGifSmileyCtrl* lpAnimator = nullptr;
	HRESULT hr = ::CoCreateInstance(GifSmiley::CLSID_CGifSmileyCtrl, NULL, CLSCTX_INPROC, GifSmiley::IID_IGifSmileyCtrl, (LPVOID*)&lpAnimator);
	if (NULL == lpAnimator || FAILED(hr))
	{
		LOG__(ERR, _T("InsertImage CoCreateInstance failed"));
		goto End;
	}

	COLORREF backColor = (COLORREF)(::GetSysColor(COLOR_WINDOW));
	HWND hwnd = (HWND)((long)m_pManager->GetPaintWindow());
	IRichEditOle *pRichEditOle = m_pRichEditOle;
	if (NULL == pRichEditOle)
		goto End;
	BSTR path = NULL;
	//Create lockbytes
	hr = ::CreateILockBytesOnHGlobal(NULL, TRUE, &lpLockBytes);
	if (FAILED(hr))
	{
		LOG__(ERR, _T("InsertImage CreateILockBytesOnHGlobal failed"));
		goto End;
	}
	//use lockbytes to create storage
	SCODE sc = ::StgCreateDocfileOnILockBytes(lpLockBytes, STGM_SHARE_EXCLUSIVE | STGM_CREATE | STGM_READWRITE, 0, &lpStorage);
	if (sc != S_OK)
	{
		LOG__(ERR, _T("InsertImage StgCreateDocfileOnILockBytes failed"));
		goto End;
	}
	// retrieve OLE interface for richedit   and  Get site
	pRichEditOle->GetClientSite(&lpClientSite);
	try
	{
		//COM operation need BSTR, so get a BSTR
		path = bstrFileName;
		//Load the image
		if (isGif)
			lpAnimator->LoadFromFile(path);
		else
		{
			UInt32 height = (size.cy < GetHeight()) ? size.cy : GetHeight();
			UInt32 width = (size.cx < GetWidth() / 2) ? size.cx : GetWidth() / 2;
			lpAnimator->LoadFromFileSized(path, width, height);
		}
		//Set back color
		OLE_COLOR oleBackColor = (OLE_COLOR)backColor;
		lpAnimator->put_BackColor(oleBackColor);
		//get the IOleObject
		hr = lpAnimator->QueryInterface(IID_IOleObject, (void**)&lpObject);
		if (FAILED(hr))
		{
			LOG__(ERR, _T("InsertImage lpAnimator QueryInterface failed"));
			goto End;
		}
		//Set it to be inserted
		OleSetContainedObject(lpObject, TRUE);
		//to insert into richedit, you need a struct of REOBJECT
		REOBJECT reobject;
		ZeroMemory(&reobject, sizeof(REOBJECT));
		reobject.cbStruct = sizeof(REOBJECT);
		CLSID clsid;
		hr = lpObject->GetUserClassID(&clsid);
		//set clsid
		reobject.clsid = clsid;
		//can be selected
		reobject.cp = REO_CP_SELECTION;
		//content, but not static
		reobject.dvaspect = DVASPECT_CONTENT;
		//goes in the same line of text line
		reobject.dwFlags = REO_BELOWBASELINE;
		//reobject.dwUser = (DWORD)myObject;
		//the very object
		reobject.poleobj = lpObject;
		//client site contain the object
		reobject.polesite = lpClientSite;
		//the storage 
		reobject.pstg = lpStorage;
		SIZEL sizel = { 0 };
		reobject.sizel = sizel;
		LPOLECLIENTSITE lpObjectClientSite = NULL;
		hr = lpObject->GetClientSite(&lpObjectClientSite);
		if (FAILED(hr) || lpObjectClientSite == NULL)
			lpObject->SetClientSite(lpClientSite);
		pRichEditOle->InsertObject(&reobject);
		//redraw the window to show animation
		::RedrawWindow(hwnd, NULL, NULL, RDW_INVALIDATE);
	}
	catch (...)
	{
		LOG__(ERR, _T("InsertImage unknown exeption"));
	}

End:
	if (lpClientSite)
	{
		lpClientSite->Release();
		lpClientSite = nullptr;
	}
	if (lpObject)
	{
		lpObject->Release();
		lpObject = nullptr;
	}
	if (lpLockBytes)
	{
		lpLockBytes->Release();
		lpLockBytes = nullptr;
	}
	if (lpStorage)
	{
		lpStorage->Release();
		lpStorage = nullptr;
	}
	if (lpAnimator)
	{
		lpAnimator->Release();
		lpAnimator = nullptr;
	}
}
void CExRichEditWindowless::InsertGif(LONG gif)
{
	CComQIPtr<IDynamicOleCom> spDyn;
	HRESULT hr = spDyn.CoCreateInstance(STR_PROGID);
	if(SUCCEEDED(hr))
	{
		LPOLEOBJECT lpOleObject = NULL;
		HRESULT hr = spDyn->QueryInterface(IID_IOleObject, (void**)&lpOleObject);

		IUnknownPtr lpUnk = lpOleObject;
		hr = lpUnk->QueryInterface(IID_IOleObject, (LPVOID*)&lpOleObject);
		if (lpOleObject == NULL)
			throw(E_OUTOFMEMORY);
		//hr = lpOleObject->SetClientSite( static_cast<IOleClientSite *>( this ) );
		IViewObject2Ptr lpViewObject;// IViewObject for IOleObject above
		hr = lpOleObject->QueryInterface(IID_IViewObject2, (LPVOID*)&lpViewObject);
		if (hr != S_OK)
		{
			AtlThrow(hr);
		}
		IRichEditOle* pRichEditOle = GetIRichEditOle();
		////获取RichEdit的OLEClientSite
		IOleClientSitePtr lpClientSite;
		hr = pRichEditOle->GetClientSite(&lpClientSite);

		if (hr != S_OK)
		{
			AtlThrow(hr);
		}
		REOBJECT reobject;
		ZeroMemory(&reobject,sizeof(REOBJECT));
		reobject.cbStruct = sizeof(REOBJECT);

		CLSID clsid;
		hr = lpOleObject->GetUserClassID(&clsid);
		if (hr != S_OK)
		{
			AtlThrow(hr);
		}

		reobject.clsid = clsid;
		reobject.cp = -1;
		//reobject.cp = REO_CP_SELECTION;
		reobject.dvaspect = DVASPECT_CONTENT;//DVASPECT_OPAQUE;
		reobject.poleobj = lpOleObject;
		reobject.polesite = lpClientSite;
		//reobject.pstg = lpStorage;
		SIZEL sizel;
		sizel.cx = sizel.cy = 0; // let richedit determine initial size

		Image* img = (Image*)gif;
		SIZEL sizeInPix = {img->GetWidth(), img->GetHeight()};
		SIZEL sizeInHiMetric;
		AtlPixelToHiMetric(&sizeInPix, &sizeInHiMetric);

		reobject.sizel = sizeInHiMetric;
		reobject.dwFlags = REO_BELOWBASELINE|REO_STATIC;//REO_RESIZABLE

		CExRichEditData* pdata = new CExRichEditData;
		pdata->m_dataType = GIF;
		pdata->m_data = (void*)gif;
		reobject.dwUser = (DWORD)pdata;//TODO 用户数据

		lpOleObject->SetClientSite(lpClientSite); 
		hr = pRichEditOle->InsertObject(&reobject);
		lpOleObject->SetExtent(DVASPECT_CONTENT, &sizeInHiMetric);
		OleSetContainedObject(lpOleObject, TRUE);
		lpOleObject->Release();
		spDyn->SetHostWindow((LONG)hwndParent);
		spDyn->InsertGif(gif);
	}
}