egg*_*yal 5 c++ com excel activex atl
Microsoft Office支持文章" 添加或注册ActiveX控件 "说:
重要提示:并非所有ActiveX控件都可以直接在工作表中使用; 一些只能在Microsoft Visual Basic for Applications(VBA)UserForms上使用.使用这些控件时,如果您尝试将对象添加到工作表,Excel将显示消息"无法插入对象".
但是,我无法在任何地方找到有必要和足以使控件直接在工作表上使用的要求.
我创建了一个新的C++/ATL项目,我已经添加了一个ATL控件,接受了整个默认值.在编译,构建和注册控件之后,它出现在Excel的"更多控件"列表中(在"开发">"插入">"ActiveX控件">"更多控件"下访问...)但在尝试插入工作表时,会看到"无法插入对象" "错误.
我必须做些什么改变才能解决这个问题?
要么
Excel对ActiveX控件的要求记录在哪里?
为了它的价值,我已经验证了向导生成的控件确实可以正常工作(使用我从Visual C++ 2008示例包构建的ActiveX控件测试容器测试).
此外,我知道ATL控件向导的"外观"选项卡的文档描述了"可插入"复选框,如下所示:
选择此选项可使控件显示在Word和Excel等应用程序的"插入对象"对话框中.然后,任何支持嵌入对象的应用程序都可以通过此对话框插入您的控件.
但是,此复选框(只是将"可插入"子项添加到注册表中)只会使控件出现在"插入">"文本">"对象"对话框中 - 为避免疑问,我已尝试使用和不使用此选项并且无论如何都会产生同样的错误.
我正在尝试在尝试插入工作(Forms 2.0)控件时插入我的控件时,比较Excel的执行路径的痕迹.在加载类型库(OLE/COM对象查看器能够从我的DLL中正确加载)时,关键区别似乎在VBE7.dll中- 但在Excel执行了所有相同的读取之后,它在写出EXD之前中止)...我正在挖掘一些装配现在徒劳地希望我能弄明白 - 但是肯定有人为Excel建立了一个工作控制并知道我缺少什么可以免除我这种痛苦?!
Microsoft Windows 10 Pro v1511(10.0.10586.164)64位
Microsoft Excel 2016 MSO(16.0.4312.1000)64位
Microsoft Visual Studio社区2015(14.0.24720.00 Update 1)
要实现可插入 MS Excel 工作表的 ATL ActiveX 控件,请按照下列步骤操作:
确保 C:\Users\$(UserName)\AppData\Local\Temp\Excel8.0 中没有缓存 ActiveX 控件信息 *.exd 文件,这可能是一个不明显的障碍
使用所有默认值创建 ATL DLL 项目
2.1. 添加 x64 配置作为现有 Win32 的副本 - 对于 64 位 Excel,您将需要 64 位 ActiveX 控件
3.1. 确保填写 ProgID 字段
3.2. 在 Interfaces 页面添加 IPersistStreamInit
构建 DLL 并注册它 (regsvr32)
在 Excel 中,新控件在菜单“开发人员”、“...”、“更多控件”中可见
源代码:Subversion / Trac
更新:以下评论提出的问题:
...Excel是否支持无窗口激活?
要查看实际的控制操作,让我们在其中添加一些代码:
CSample()
{
CTrace::SetLevel(4);
Run Code Online (Sandbox Code Playgroud)
和
HRESULT OnDraw(ATL_DRAWINFO& di)
{
const CComQIPtr<IOleInPlaceSiteWindowless> pOleInPlaceSiteWindowless = m_spClientSite;
ATLTRACE(_T("m_spClientSite 0x%p, pOleInPlaceSiteWindowless 0x%p, m_hWnd 0x%08X\n"), m_spClientSite, pOleInPlaceSiteWindowless, m_hWnd);
Run Code Online (Sandbox Code Playgroud)
这将打印出有助于识别窗口/无窗口模式的控件成员。输出是(最终在激活对象后或从一开始):
CSample()
{
CTrace::SetLevel(4);
Run Code Online (Sandbox Code Playgroud)
该控件可以激活窗口模式和无窗口模式(除非m_bWindowOnly设置为 true,在这种情况下强制使用窗口模式)。跟踪显示控件处于窗口模式,并且该容器没有IOleInPlaceSiteWindowless,这对于无窗口是必需的。