to 无俗则刚
因为有特别的原因,所以必须实现这样的功能.谢谢你的意见.
下面有一段从网上找的VC的例子,可是偶不懂VC,所以还请懂VC的帮忙转换成DELPHI,万分感谢,分数不够,另开贴再加!
VC原文如下:
有时候,我们需要在一个容器中插入各种不同的对象,比如,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"
5、为对话框类加入私有成员函数BOOL InsertPolygon(IRichEditOle* lpRichEditOle);将该函数定义如下:
BOOL CClientDlg::InsertPolygon(IRichEditOle* lpRichEditOle)
{
IStorage* lpStorage = NULL;//存储接口
IOleObject* lpOleObject = NULL;//OLE对象
LPLOCKBYTES lpLockBytes = NULL;//LOCKBYTE
IOleClientSite* 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 interface
if( 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();
}
}
7、运行效果图如下:
如果你有自己的控件,可以按上述的方法插入。