本文主要是介绍在RichEdit控件中插入OLE对象(ActiveX控件),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
有时候,我们需要在一个容器中插入各种不同的对象,比如,QQ聊天对话框里可以插入各种静态和动态的图片,甚至还可以插入flash文件,这些都是通过OLE技术来实现的。OLE技术是基于COM的,而COM又是非常复杂的东西,想要学习COM得花很多的时间,《COM技术内幕》,《COM原理和应用》,《INSIDE OLE 2》都是非常好的学习COM和OLE的书,但要把这些书啃完,弄懂,几个月甚至半年都过去了。学习COM是一个郁闷、漫长的过程,虽然进步很慢,但坚持下去会很有意思。如果我们仅仅是使用别人的组件,并将别人的组件插入到自己的容器中,也不是很复杂,下面就是一个例子。
我们以MSDN的ATL Tutorial中创建的组件做为我们要插入的对象(该组件的创建请看MSDN)。
1、创建一个COM客户端基于对话框的工程,命名为Client,按默认选项设置工程。
2、在主对话框中加入一个RichEdit控件,用ClassWizard为添加一个表示该控件的变量,为m_re,记住类型设为control。为主对话框加入一个按钮,ID设为IDC_INSERTPOLYGON,Caption设置为InsertPolygon。
3、在CClientApp::InitInstance()函数中,在创建对话框的代码前加入如下代码:
if (AfxInitRichEdit() == FALSE){return FALSE;}
如果不加入上面的代码,应用程序将无法运行。
4、在Client.cpp中添加头文件
#include "..\\Polygon.h" //DLL模块头文件#include "..\\Polygon_i.c" //接口定义#include "Richole.h"
BOOL CClientDlg::InsertPolygon(IRichEditOle* lpRichEditOle){IStorage* lpStorage = NULL;//存储接口IOleObject* lpOleObject = NULL;//OLE对象LPLOCKBYTES lpLockBytes = NULL;//LOCKBYTEIOleClientSite* lpOleClientSite = NULL; IPolyCtl* lpPolyCtl = NULL; //控件CLSID clsid;REOBJECT reobject;HRESULT hr;if(lpRichEditOle == NULL)return FALSE;//创建PolyCtl对象并获取接口hr = ::CoCreateInstance(CLSID_PolyCtl,NULL,CLSCTX_INPROC,IID_IPolyCtl,(LPVOID*)&lpPolyCtl);if( lpPolyCtl == NULL ){return FALSE;}// USES_CONVERSION;BOOL bRet = TRUE;try{hr = lpPolyCtl->QueryInterface(&lpOleObject);//获得数据对象接口if( hr != S_OK ) AfxThrowOleException(hr);hr = lpOleObject->GetUserClassID(&clsid);if ( hr != S_OK)AfxThrowOleException(hr);hr = ::CreateILockBytesOnHGlobal(NULL, TRUE, &lpLockBytes);//创建LOCKBYTE对象if (hr != S_OK)AfxThrowOleException(hr);ASSERT(lpLockBytes != NULL);hr = ::StgCreateDocfileOnILockBytes(lpLockBytes,//创建复合文档STGM_SHARE_EXCLUSIVE|STGM_CREATE|STGM_READWRITE, 0, &lpStorage);if (hr != S_OK){VERIFY(lpLockBytes->Release() == 0);lpLockBytes = NULL;AfxThrowOleException(hr);}lpRichEditOle->GetClientSite(&lpOleClientSite);ZeroMemory(&reobject, sizeof(REOBJECT));//初始化一个对象 reobject.cbStruct = sizeof(REOBJECT);reobject.clsid = clsid;reobject.cp = REO_CP_SELECTION;reobject.dvaspect = DVASPECT_CONTENT;reobject.dwFlags = REO_BELOWBASELINE;reobject.poleobj = lpOleObject;reobject.polesite = lpOleClientSite;reobject.pstg = lpStorage;hr = lpRichEditOle->InsertObject( &reobject );if (hr != S_OK)AfxThrowOleException(hr);OleSetContainedObject(lpOleObject,TRUE);}catch( COleException* e ){TRACE(_T("OleException code:%d"),e->m_sc);e->Delete();bRet = FALSE;}// release the interfaceif( lpPolyCtl != NULL ) lpPolyCtl->Release();if( lpOleObject != NULL ) lpOleObject->Release();if( lpOleClientSite != NULL ) lpOleClientSite->Release();if( lpStorage != NULL ) lpStorage->Release();return bRet;}6、为InsertPolygon按钮添加响应函数,定义如下:void CClientDlg::OnInsertpolygon() {IRichEditOle* lpRichEditOle = NULL;lpRichEditOle = m_re.GetIRichEditOle();if (lpRichEditOle != NULL){InsertPolygon(lpRichEditOle);lpRichEditOle->Release();}}
5、为对话框类加入私有成员函数BOOL InsertPolygon(IRichEditOle* lpRichEditOle);将该函数定义如下:
这篇关于在RichEdit控件中插入OLE对象(ActiveX控件)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!