⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 faceedit.cpp

📁 类似QQ,MSN表情的richedit,用来测试表情控件的
💻 CPP
📖 第 1 页 / 共 2 页
字号:
LONG            lindex;      // (-1)  在数据通过页面边界分割的时候使用
DWORD           tymed;       // 用于数据传输的存储媒体(HGLOBAL,IStream)
} FORMATETC;
FORMATETC结构的成员如下描述:
cfFormat:粘贴板格式,用来表示FORMATETC结构。可以是内建的格式(例如:CF_TEXT或CF_BITMAP)或者用RegisterClipboardFormat注册的自定义格式。
Ptd:指向DVTARGETDEVICE结构,提供已经rendered数据的设备信息。正常的粘贴板操作和拖放操作都是NULL。
dwAspect:描述用户怎么样render数据的大量细节。通常这个是DVASPECT_CONTECT,表示全内容,但也可以描述较少的信息,例如:图标。
Lindex:仅仅在当数据通过页面边界被分割的时候使用,它不用于简单的OLE传输,因此该值几乎总是-1。
Typemed:这是一个有趣的成员;因为其描述了用于存储数据的存储媒体类型。该成员名字自词组“Type of Medium”;该值在window.h中定义的TYMED_XXX等值。
因此有了这个数据结构,OLE已经提供了一个描述消费者什么样的数据已经怎么样render这个数据。
存储OLE数据
结构体STGMEDIUM(STORAGE MEDIUM的缩写)提供一个用来存储数据的容器,因此叫存储媒体:
typedef struct 
{
DWORD tymed;
union
{
HBITMAP        hBitmap;
HMETAFILEPICT  hMetaFilePict;
HENHMETAFILE   hEnhMetaFile;
HGLOBAL        hGlobal;
LPWSTR         lpszFileName;
IStream        *pstm;
IStorage       *pstg;
}; 
IUnknown *pUnkForRelease;
} STGMEDIUM;
这个结构定义看起来比较复杂,但是有用的仅仅三个成员,因为未命名联合合并了所有内容作为一个实体共享同样的存储空间。
1.         tymed:这个成员必须和FORMATETC结构相同,这个成员指定已经存储的媒体类型,例如,全局数据(TYMED_HGLOBAL),IStream(TYPED_ISTREAM)等等。相应的联合中的元素是数据的句柄。
2.         hBitmap/hGlobal等:实际的数据,仅仅他们中的一个是有效的,这依赖于tymed的值。
3.         pUnkForRelease:一个可选的指针,指向IUnknown接口,数据的接收方应该调用其Release方法。当这个字段是NULL时,接收方有责任释放内存句柄。ReleaseStgMedium API调用在这里非常有用,它负责释放STGMEDIUMS的数据内容,因此实际上我们不需要做什么。
STGMEDIUM结构是传统的windows HGLOBAL内存句柄的扩展,同时支持HGLOBAL(且一直是最常用的),同时支持许多其他的类型,最有用的是IStream和IStorage通用COM接口。
总之,结构体FORMATETC和STGMEDIUM一起用来描述和存储OLE数据实体的。FORMATETC通常用来从IDataObject请求指定类型的数据,同时STGMEDIUM结构用来接收和保存请求的数据。
*/
void InsertBitmap(CRichEditCtrl *pRichEdit, HBITMAP hBitmap)	//底层的一个InsertBitmap
{
	STGMEDIUM stgm;                  //提供用于数据传输操作的通用化全局内存句柄
	stgm.tymed = TYMED_GDI;    // Storage medium = HBITMAP handle
	stgm.hBitmap = hBitmap;
	stgm.pUnkForRelease = NULL; // Use ReleaseStgMedium

/*	WCHAR wchar[10] = {'1','1','.','g','i','f'};
	STGMEDIUM stgm;   
	stgm.tymed = TYMED_MFPICT;
//	stgm.lpszFileName=filename;
	stgm.lpszFileName = wchar;
//	stgm.hGlobal = hMetaPict.m_pPicture;
//	stgm.hGlobal = hMetaPict;
	stgm.pUnkForRelease = NULL;*/

	
	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;
	/*FORMATETC fm;
	fm.cfFormat = TYMED_MFPICT;
	fm.ptd = NULL;
	fm.dwAspect = DVASPECT_CONTENT;
	fm.lindex = -1;
	fm.tymed = TYMED_ISTREAM;*/


	/*
	{	TYMED_HGLOBAL	= 1,
	TYMED_FILE	= 2,
	TYMED_ISTREAM	= 4,
	TYMED_ISTORAGE	= 8,
	TYMED_GDI	= 16,
	TYMED_MFPICT	= 32,
	TYMED_ENHMF	= 64,
	TYMED_NULL	= 0
	*/
	//创建输入数据源

/*	FORMATETC   fmtetc;   
	STGMEDIUM   stg;   
	fmtetc.cfFormat   = m_cfImageFile;   
	fmtetc.dwAspect   =   DVASPECT_CONTENT;   
	fmtetc.ptd   =   NULL;   
	fmtetc.tymed   =   TYMED_ISTREAM;   
	fmtetc.lindex   =   -1;   

	WCHAR   filename[256];   
	MultiByteToWideChar(CP_ACP,     
		MB_PRECOMPOSED,     
		(LPCSTR)m_szFileName,     
		m_szFileName.GetLength(),     
		(LPWSTR)filename,     
		sizeof(filename));   

	stg.tymed=TYMED_ISTREAM;   
	stg.lpszFileName=filename;//lpszFileName;   

	COleDataSource*   pSource=new   COleDataSource();   

	pSource->CacheData(m_cfImageFile,   &stg,   &fmtetc);  */ 

	IStorage *pStorage; //IStorage是结构或存储的文件接口。通过IStorage可以操作结构化存储的文件。   
	//分配内存
	LPLOCKBYTES lpLockBytes = NULL;
	SCODE sc = ::CreateILockBytesOnHGlobal(NULL, TRUE, &lpLockBytes);
	if (sc != S_OK)
		AfxThrowOleException(sc);
	ASSERT(lpLockBytes != NULL);	
	sc = ::StgCreateDocfileOnILockBytes(lpLockBytes,
		STGM_SHARE_EXCLUSIVE|STGM_CREATE|STGM_READWRITE, 0, &pStorage);
	if (sc != S_OK)
	{
		VERIFY(lpLockBytes->Release() == 0);
		lpLockBytes = NULL;
		AfxThrowOleException(sc);
	}
	ASSERT(pStorage != NULL);	

	//设置Ole数据
	COleDataSource *pDataSource = new COleDataSource;
	pDataSource->CacheData(CF_BITMAP, &stgm);


	LPDATAOBJECT lpDataObject = (LPDATAOBJECT)pDataSource->GetInterface(&IID_IDataObject);//OleGetClipboard(&lpDataObject);
	//获取RichEdit的OLEClientSite
	LPOLECLIENTSITE lpClientSite;
	pRichEdit->GetIRichEditOle()->GetClientSite( &lpClientSite );	
	//创建OLE对象            ???如何设置lpDataObject 和 fm ?????? pStorage ?????
	IOleObject *pOleObject;
	sc = OleCreateStaticFromData(lpDataObject,IID_IOleObject,OLERENDER_FORMAT,
		&fm,lpClientSite,pStorage,(void **)&pOleObject);	
	if(sc!=S_OK)
		AfxThrowOleException(sc);
	//插入OLE对象





	REOBJECT reobject;
	ZeroMemory(&reobject, sizeof(REOBJECT));
	reobject.cbStruct = sizeof(REOBJECT);
	CLSID clsid;
	sc = pOleObject->GetUserClassID(&clsid);
	if (sc != S_OK)
		AfxThrowOleException(sc);	
	reobject.clsid = clsid;
	reobject.cp = REO_CP_SELECTION;
	reobject.dvaspect = DVASPECT_CONTENT;
	reobject.poleobj = pOleObject;
	reobject.polesite = lpClientSite;
	reobject.pstg = pStorage;
	HRESULT hr = pRichEdit->GetIRichEditOle()->InsertObject( &reobject );
	delete pDataSource;
}

void CFaceEdit::InsertFace(CString strPicPath)
{
}
void CFaceEdit::SetFaceToText()
{
	CString str;
	GetWindowText(str);
	int count = vecFace.size();
	for(int i = 0;i < count;i ++)
	{
		str.Insert(vecFace[i].nPos,m_pSymbol[vecFace[i].nFaceIndex]);
	}
}

void CFaceEdit::ClearFace()
{

	vecFace.clear();
}


/*LPPICTURE   gpPicture;   
//   This   function   loads   a   file   into   an   IStream.   
void   LoadPictureFile(LPCTSTR   szFile)   
{   
	//   open   file   
	HANDLE   hFile   =   CreateFile(szFile,   GENERIC_READ,   0,   NULL,   OPEN_EXISTING,   0,   NULL);   
	_ASSERTE(INVALID_HANDLE_VALUE   !=   hFile);   

	//   get   file   size   
	DWORD   dwFileSize   =   GetFileSize(hFile,   NULL);   
	_ASSERTE(-1   !=   dwFileSize);   

	LPVOID   pvData   =   NULL;   
	//   alloc   memory   based   on   file   size   
	HGLOBAL   hGlobal   =   GlobalAlloc(GMEM_MOVEABLE,   dwFileSize);   
	_ASSERTE(NULL   !=   hGlobal);   

	pvData   =   GlobalLock(hGlobal);   
	_ASSERTE(NULL   !=   pvData);   

	DWORD   dwBytesRead   =   0;   
	//   read   file   and   store   in   global   memory   
	BOOL   bRead   =   ReadFile(hFile,   pvData,   dwFileSize,   &dwBytesRead,   NULL);   
	_ASSERTE(FALSE   !=   bRead);   
	GlobalUnlock(hGlobal);   
	CloseHandle(hFile);   

	LPSTREAM   pstm   =   NULL;   
	//   create   IStream*   from   global   memory   
	HRESULT   hr   =   CreateStreamOnHGlobal(hGlobal,   TRUE,   &pstm);   
	_ASSERTE(SUCCEEDED(hr)   &&   pstm);   

	//   Create   IPicture   from   image   file   
	if   (gpPicture)   
		gpPicture->Release();   
	hr   =   ::OleLoadPicture(pstm,   dwFileSize,   FALSE,   IID_IPicture,   (LPVOID   *)&gpPicture);   
	_ASSERTE(SUCCEEDED(hr)   &&   gpPicture);   
	pstm->Release();   

	InvalidateRect(ghWnd,   NULL,   TRUE);   
}   


。。。。。。   

  case   WM_PAINT:   
	  hdc   =   BeginPaint(hWnd,   &ps);   
	  if   (gpPicture)   
	  {   
		  //   get   width   and   height   of   picture   
		  long   hmWidth;   
		  long   hmHeight;   
		  gpPicture->get_Width(&hmWidth);   
		  gpPicture->get_Height(&hmHeight);   
		  //   convert   himetric   to   pixels   
		  int   nWidth =   MulDiv(hmWidth,   GetDeviceCaps(hdc,   LOGPIXELSX),   HIMETRIC_INCH);   
		  int   nHeight =   MulDiv(hmHeight,   GetDeviceCaps(hdc,   LOGPIXELSY),   HIMETRIC_INCH);   
		  RECT   rc;   
		  GetClientRect(hWnd,   &rc);   
		  //   display   picture   using   IPicture::Render   
		  gpPicture->Render(hdc,   0,   0,   nWidth,   nHeight,   0,   hmHeight,   hmWidth,   -hmHeight,   &rc);   
	  }   
	  EndPaint(hWnd,   &ps);   
	  break;*/
void CFaceEdit::InsertBitmap(CString szFileName)
{
	USES_CONVERSION;
	LPLOCKBYTES m_lpLockBytes = NULL;
	IStorage *m_lpStorage;
	SCODE sc = ::CreateILockBytesOnHGlobal(NULL, TRUE, &m_lpLockBytes);
	if (sc != S_OK)
		AfxThrowOleException(sc);
	ASSERT(m_lpLockBytes != NULL);
	sc = ::StgCreateDocfileOnILockBytes(m_lpLockBytes,STGM_SHARE_EXCLUSIVE|STGM_CREATE|STGM_READWRITE, 0, &m_lpStorage);
	if (sc != S_OK)
	{
		VERIFY(m_lpLockBytes->Release() == 0);
		m_lpLockBytes = NULL;
		AfxThrowOleException(sc);
	 }
	IOleObject *m_lpObject;
	 sc = ::OleCreateFromFile(CLSID_NULL, T2COLE(szFileName),IID_IUnknown, OLERENDER_DRAW, NULL, NULL,
		  m_lpStorage, (void **)&m_lpObject);
	if ( sc != S_OK )
	{
		return;
	}
/*	if (m_lpObject != NULL)
	{
		LPUNKNOWN lpUnk = m_lpObject;
		m_lpObject = GetInterface(lpUnk, IOleObject);
		lpUnk->Release();
		if (m_lpObject == NULL)
			AfxThrowOleException(E_OUTOFMEMORY);
	}
	m_lpViewObject = GetInterface(m_lpObject, IViewObject2);
	if (m_lpViewObject == NULL)
		return;
	LPADVISESINK lpAdviseSink = (LPADVISESINK)GetInterface(&IID_IAdviseSink);
	VERIFY(m_lpViewObject->SetAdvise(DVASPECT_CONTENT, 0, lpAdviseSink) == S_OK);*/
	m_lpObject->SetHostNames(T2COLE(AfxGetAppName()),T2COLE(_T("Test")));
	OleSetContainedObject(m_lpObject, TRUE);
	CHARRANGE cr;
	this->GetSel( cr );
	cr.cpMin = cr.cpMax -1;
	this->SetSel( cr );
	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;
	this->GetIRichEditOle()->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 = this->GetIRichEditOle()->InsertObject( &reo );
}

void CFaceEdit::InsertGif(CString filename)
{
	/*IRichEditOle ReOle;
	IOleClientSite OleSite;
	IStorage       Storage;
    ILockBytes     LockBytes;
    IOleObject     OleObject;
	REOBJECT         ReObj;
    IGifAnimator    Animator;
	ReOle = GetRichEditOle(hRichEdit);
	ReOle.GetClientSite(OleSite);
	OleCheck(CreateILockBytesOnHGlobal(0, True, LockBytes));
	OleCheck(StgCreateDocfileOnILockBytes(LockBytes,
		STGM_SHARE_EXCLUSIVE || STGM_CREATE || STGM_READWRITE, 0, Storage));
	Animator = IUnknown(CreateComObject(CLASS_GifAnimator));
	Animator.LoadFromFile(PWideChar(WideString(FileName)));
	OleCheck(Animator.QueryInterface(IID_IOleObject, OleObject));
	OleCheck(OleSetContainedObject(OleObject, True));
	FillChar(ReObj, Sizeof(ReObj), 0);
	ReObj.cbStruct := Sizeof(ReObj);
	OleCheck(OleObject.GetUserClassID(ReObj.clsid));
	ReObj.cp := REO_CP_SELECTION;
	ReObj.dvaspect := DVASPECT_CONTENT;
	ReObj.dwFlags := REO_STATIC or REO_BELOWBASELINE;
	ReObj.dwUser := 0;
	ReObj.poleobj := OleObject;
	ReObj.polesite := OleSite;
	ReObj.pstg := Storage;
	ReObj.sizel.cx := 0;
	ReObj.sizel.cy := 0;
	ReOle.InsertObject(ReObj);*/
 
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -