一个用于嵌入可嵌入 OLE 对象的 COM 类(DLL)






4.45/5 (7投票s)
2005年8月24日
1分钟阅读

60673

1416
一个嵌入可嵌入 OLE 对象的 COM 类 (DLL)。
引言
使用 MFC,我们可以轻松开发一个 ActiveX 容器应用程序,但遗憾的是,它只能与文档/视图架构作为可执行文件一起工作。 如果您想嵌入一个可嵌入的 OLE 对象,但您的程序不是一个可执行程序,并且必须是一个 DLL(例如,对于许多类型的插件,它们作为 DLL 文件工作),那么这篇文章将为您提供帮助。
使用代码
它非常简单易用。 这个 COM 对象只有三个方法,Create
、Open
和 OnSize
。
- 您必须声明接口,并添加其工作所在的包含文件(注意:此 COM 对象将作为子窗口工作)。
在测试器中,我将其作为元素添加到
CTesterDlg
中。#include "..\emboleobjctrl\emboleobjctrl_i.h" IEmbOleObjControl * m_pCtrl;
- 将对象指针初始化为
NULL
CtesterDlg::CtesterDlg(CWnd* pParent /*=NULL*/) :CDialog(CtesterDlg::IDD, pParent) { m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME); m_pCtrl = NULL; }
- 创建实例并创建窗口
void CtesterDlg::ObBnClickedCreate() { if(m_pCtrl) //if the object exists then quit return; HRESULT hr = ::CoCreateInstance(CLSID_EmbOleObjControl, NULL,CLSCTX_ALL,IID_IEmbOleObjControl, (void **)&m_pCtrl); if(SUCCEEDED(hr)) { HWND hWnd; GetDlgItem(IDC_STATICOWNER,&hWnd); m_pCtrl->Create(hWnd); //create needs a parameter as the control's container window, } }
- 打开特定的文件和特定的 OLE 服务器
void CtesterDlg::OnBnClickedBtnopen() { if(!m_pCtrl) { AfxMessageBox("please create the control first"); return; } CString strInfo; CWnd *pWnd = GetDlgItem(IDC_EDTPATH); pWnd->GetWindowText(strInfo); _bstr_t bstrInfo(strInfo.GetBuffer()); static CLSID const clsid_App ={ 0x7b93e267, 0x6bbc, 0x11d4, { 0xa5, 0x4d, 0x0, 0x50, 0xba, 0xdb, 0x14, 0xa3 } }; m_pCtrl->Open(clsid_App,bstrInfo); //clsid_app : the ole server's clsid //bstrInfo: the file's path }
- 当容器窗口的大小改变时,调用
IFoxitPDFControl::OnSize()
(对于当前情况,容器不可调整大小)。 - 在销毁容器窗口之前,销毁(释放)它。
void CtesterDlg::OnCancel() { if(m_pCtrl) m_pCtrl->Release(); CDialog::OnCancel(); }
关注点
将文档/视图架构包装到 DLL 模块中并不容易,因为该架构中的主框架窗口作为重叠窗口工作,它不能作为子窗口工作;但在这里它必须作为子窗口工作(严格来说,它在这里作为弹出窗口工作)。 为了调整窗口的位置,导出了一个额外的函数(OnMove
)。 即使现在,还有一个问题让我困扰,这个 COM 对象不能与 MS-Word 正确工作。 希望有人能更正它,使其能够与任何 OLE 服务器无问题地工作。