一、理论基础:
创建COM组件有如下两种方式。
1。在开发过程中,客户程序通常都是通过CoCreateInstance()创建COM对象,但这样创建方式,客户必须知道该COM组件的CLSID或ProgID。COM库通过ID在注册表中找到COM,并加载。通过指针数组调用其内的函数。
2。另一种创建方式,就是通过名字对象(moniker)创建COM对象。名字技术允许客户程序通过符号化的方式创建COM对象,不必须再通过CLSID或ProgID,大大降低了系统的偶合性。
下面对第二种方式进行简单说明:
名字对象,其本身也是一个COM对象,它对通常的COM组件对象提供了符号化的表示方法,同时它对COM组件对象进行了全面的封装。客户只需创建相应的名字对象,然后利用名字对象的绑定功能得到组件对象。名字对象实现了标准的接口IMoniker,客户程序通过IMoniker接口获得组件对象。
例如在客户文档中插入一个电子表格文件:“C:/My Document / My.xls”,其处理过程如下:
1。客户程序首先调用CreateFileMoniker API 函数创建一个文件名字对象,
2。调用名字对象的IMoniker::BindToObject()函数,绑定到Excle.exe,在后台运行,并加载"C:/My Document / My.xls",其绑定的详细过程如下:
2。1通过GetClassFile找到与该电子表格文件相联系的组件对象CLSID
2。1。1CLSID一般保存在文件中,直接从文件读取即可
2。1。2CLSID,也通过该电子表格文件的扩展名“。xls”,到注册表中查找相应的CLSID
2。2找到CLSID,后再调用CoCreateInstance()组件对象
2。3请求组件的IPersistFile指针,然后调用IPersistFile::Load(strFileName)加载电子表格文件。
2。4BindToObject返回
二、在MFC中的实际应用
在MFC中,利用COleClientItem类,将其加载过程封装掩盖起来了。所以,即使你不懂名字对象技术,也不会影响你使用OLE对象。
CView::OnInsertObject()
{
。。。
COleInsertDialog dlg ; //启动OLE插入对话框
if (dlg.DoModal() != IDOK)
return;
BeginWaitCursor();
COLECntrItem* pItem = NULL;
TRY
{
// Create new item connected to this document.
COLEDoc* pDoc = GetDocument();//获得容器指针
ASSERT_VALID(pDoc);
pItem = new COLECntrItem(pDoc);//创建OLE对象
ASSERT_VALID(pItem);
// Initialize the item from the dialog data.
if (!dlg.CreateItem(pItem)) //装载所嵌入的文档
AfxThrowMemoryException(); // any exception will do
ASSERT_VALID(pItem);
if (dlg.GetSelectionType() == COleInsertDialog::createNewItem)
pItem->DoVerb(OLEIVERB_SHOW, this);//激活
略。。。。