★★★ATL COM工程中创建多个ATL Object对象,为什么只有第一个创建的对象可用?

步履人生 2012-12-31 04:47:31
我创建了一个ATL COM工程,然后创建了一个ATL Object的对象,Object选择的是Simple Object,在Attributes页面中的设置如下:
Threading Model:Apartment
Interface:Custom
Aggregation:No

如下是接口定义:
class ATL_NO_VTABLE CFTProp : 
public CComObjectRootEx<CComSingleThreadModel>,
public CComCoClass<CFTProp, &CLSID_FTProp>,
// public IFTProp
public IShellExtInit,
public IShellPropSheetExt
{
public:
CFTProp()
{
}

DECLARE_REGISTRY_RESOURCEID(IDR_FTPROP)
DECLARE_NOT_AGGREGATABLE(CFTProp)

DECLARE_PROTECT_FINAL_CONSTRUCT()

BEGIN_COM_MAP(CFTProp)
// COM_INTERFACE_ENTRY(IFTProp)
COM_INTERFACE_ENTRY(IShellExtInit)
COM_INTERFACE_ENTRY(IShellPropSheetExt)
END_COM_MAP()

// IFTProp
public:
// IShellExtInit
STDMETHODIMP Initialize(LPCITEMIDLIST, LPDATAOBJECT, HKEY);

// IShellPropSheetExt
STDMETHODIMP AddPages(LPFNADDPROPSHEETPAGE, LPARAM);
STDMETHODIMP ReplacePage(UINT, LPFNADDPROPSHEETPAGE, LPARAM) { return E_NOTIMPL; }
};


上面的ATL 对象能正常运行。
我想在这个一个ATL COM工程中再创建一个ATL Object,所以按照上面的创建步骤再创建了一个,如下是接口:
class ATL_NO_VTABLE CFTComment : 
public CComObjectRootEx<CComSingleThreadModel>,
public CComCoClass<CFTComment, &CLSID_FTComment>,
// public IFTComment
public IShellExtInit, // 使用Shell接口的初始化;
public IContextMenu // 使用Shell中菜单接口;
{
public:
CFTComment()
{
}

DECLARE_REGISTRY_RESOURCEID(IDR_FTCOMMENT)

DECLARE_PROTECT_FINAL_CONSTRUCT()

BEGIN_COM_MAP(CFTComment)
// COM_INTERFACE_ENTRY(IFTComment)
COM_INTERFACE_ENTRY(IShellExtInit) // IShellExtInit接口映射;
COM_INTERFACE_ENTRY(IContextMenu) // IContextMenu接口映射;
END_COM_MAP()

// IFTComment
public:
STDMETHOD(Initialize)(LPCITEMIDLIST pidlFolder, LPDATAOBJECT pDataObj, HKEY hkeyProgID); // 接口初始化方法;

STDMETHOD(QueryContextMenu)(HMENU hmenu, UINT indexMenu, UINT idCmdFirst, UINT idCmdLast, UINT uFlags);
STDMETHOD(GetCommandString)(UINT idCmd, UINT uFlags, UINT *pwReserved, LPSTR pszName, UINT cchMax);
STDMETHOD(InvokeCommand)(LPCMINVOKECOMMANDINFO pici);
};



但是只有第一个创建的FTProp对象可以能正常运行,而第二个创建的则无法运行,是什么原因呢?

如果我把第二创建的ATL对象FTComment放在另一个工程(ATL COM工程)中,就能正常运行,搞不懂是什么原因,是对象创建的时候“Attributes”的设置原因吗?如果是,我该怎么设置才能在一个工程中使用两个ATL Object对象呢?
...全文
288 25 打赏 收藏 转发到动态 举报
写回复
用AI写文章
25 条回复
切换为时间正序
请发表友善的回复…
发表回复
步履人生 2013-01-17
  • 打赏
  • 举报
回复
最后一次顶了
步履人生 2013-01-12
  • 打赏
  • 举报
回复
自己顶一下。
步履人生 2013-01-08
  • 打赏
  • 举报
回复
引用 21 楼 RobertBaker 的回复:
我说错了,default 是设置 组件的默认接口,我以为是 设默认组件呢,(没有 设默认组件 这一说,怕误导,特别注明)
还有别的建议不?
LiuYinChina 2013-01-08
  • 打赏
  • 举报
回复
我说错了,default 是设置 组件的默认接口,我以为是 设默认组件呢,(没有 设默认组件 这一说,怕误导,特别注明)
步履人生 2013-01-08
  • 打赏
  • 举报
回复
引用 17 楼 RobertBaker 的回复:
只删除一个,你两个都删了?
如果在explorer中可以执行的话,第一步执行的是ATL的 Initialize 过程。 但是现在无法执行。
步履人生 2013-01-07
  • 打赏
  • 举报
回复
在把两个注册文件加上: HKCR { FTManager.FTComment.1 = s 'FTComment Class' { CLSID = s '{FFA53628-0D3B-43D5-AF64-1E1656B7EE24}' } FTManager.FTComment = s 'FTComment Class' { CLSID = s '{FFA53628-0D3B-43D5-AF64-1E1656B7EE24}' CurVer = s 'FTManager.FTComment.1' } NoRemove CLSID { ForceRemove {FFA53628-0D3B-43D5-AF64-1E1656B7EE24} = s 'FTComment Class' { ProgID = s 'FTManager.FTComment.1' VersionIndependentProgID = s 'FTManager.FTComment' InprocServer32 = s '%MODULE%' { val ThreadingModel = s 'Apartment' } 'TypeLib' = s '{F6EAED7B-24B7-4BB6-9F26-5A9C918F4E2E}' } } NoRemove * { NoRemove shellex { NoRemove ContextMenuHandlers { ForceRemove FTComment = s '{FFA53628-0D3B-43D5-AF64-1E1656B7EE24}' } } } } ------------------------------------------------------------------------- HKCR { FTManager.FTProp.1 = s 'FTProp Class' { CLSID = s '{BA056691-6D35-4666-A255-3C79CC110C61}' } FTManager.FTProp = s 'FTProp Class' { CLSID = s '{BA056691-6D35-4666-A255-3C79CC110C61}' CurVer = s 'FTManager.FTProp.1' } NoRemove CLSID { ForceRemove {BA056691-6D35-4666-A255-3C79CC110C61} = s 'FTProp Class' { ProgID = s 'FTManager.FTProp.1' VersionIndependentProgID = s 'FTManager.FTProp' InprocServer32 = s '%MODULE%' { val ThreadingModel = s 'Apartment' } 'TypeLib' = s '{F6EAED7B-24B7-4BB6-9F26-5A9C918F4E2E}' } } NoRemove * { NoRemove shellex { NoRemove PropertySheetHandlers { ForceRemove FTProp = s '{BA056691-6D35-4666-A255-3C79CC110C61}' } } } NoRemove Directory { NoRemove shellex { NoRemove PropertySheetHandlers { ForceRemove FTProp = s '{BA056691-6D35-4666-A255-3C79CC110C61}' } } } }
步履人生 2013-01-07
  • 打赏
  • 举报
回复
如果在explorer中可以执行的话,第一步执行的是ATL的 Initialize 过程。 但是现在无法执行。
步履人生 2013-01-07
  • 打赏
  • 举报
回复
只删除一个也是不行。
LiuYinChina 2013-01-07
  • 打赏
  • 举报
回复
只删除一个,你两个都删了?
步履人生 2013-01-07
  • 打赏
  • 举报
回复
把[default]删除了现在一个都出不来了,呵呵。 这个COM是由explorer调用的,不是自己程序调用哦。
LiuYinChina 2013-01-07
  • 打赏
  • 举报
回复
自己写个 测试程序 X ,CoCreateInstance(你那个 CLSID), 打开 COM 工程,调试对象设置为 X,在 DllGetClsidObject 处设断点, 如果没到断点,说明,对象没注册成功, 如果到了断点,就跟下去看,为啥功能没反应。 也可以在代码里找,第一个有,第二个没有,的地方, 问题在这里?你有两个 default coclass FTComment { [default] interface IFTComment; }; [ uuid(BA056691-6D35-4666-A255-3C79CC110C61), helpstring("FTProp Class") ] coclass FTProp { [default] interface IFTProp; };
步履人生 2013-01-07
  • 打赏
  • 举报
回复
没调试出来,这个是shell,第二个ATL对象只有在exploer中点击鼠标右键才能执行,断点设置在所有函数或过程的开始都没有断点提示,怎么去跟踪到你说的DllGetObject? 之前没做过此类的shell程序,也只是在codeproject上看到Michel的系列文章才开始学着写的。
LiuYinChina 2013-01-07
  • 打赏
  • 举报
回复
调试"创建出来没有",跟到 DllGetObject... 里,一看不就知道了,
步履人生 2013-01-07
  • 打赏
  • 举报
回复
调试,第二个ATL对象是不执行的。
LiuYinChina 2013-01-07
  • 打赏
  • 举报
回复
对啊,如果不是这个问题就是其他问题了,你可以写个测试调,至于怎么调,就不用我说了吧
步履人生 2013-01-07
  • 打赏
  • 举报
回复
引用 8 楼 RobertBaker 的回复:
应该是 在你的一个 cpp 里,只注册了一个对象的工厂,可能表达不是很清楚,你去找找吧, 你实现了两个 COM 对象,但是默认创建工程只登记了第一个,你要找到这里,加上第二个,
你说的是创建项目的cpp文件吗? 是不是这个? #include "stdafx.h" #include "resource.h" #include <initguid.h> #include "FTManager.h" #include "FTManager_i.c" #include "FTProp.h" #include "FTComment.h" CComModule _Module; CADODatabase _adoConn; BEGIN_OBJECT_MAP(ObjectMap) OBJECT_ENTRY(CLSID_FTComment, CFTComment) OBJECT_ENTRY(CLSID_FTProp, CFTProp) END_OBJECT_MAP()
步履人生 2013-01-07
  • 打赏
  • 举报
回复
你说的是创建项目的cpp文件吗? 是不是这个? #include "stdafx.h" #include "resource.h" #include <initguid.h> #include "FTManager.h" #include "FTManager_i.c" #include "FTProp.h" #include "FTComment.h" CComModule _Module; CADODatabase _adoConn; BEGIN_OBJECT_MAP(ObjectMap) OBJECT_ENTRY(CLSID_FTComment, CFTComment) OBJECT_ENTRY(CLSID_FTProp, CFTProp) END_OBJECT_MAP()
LiuYinChina 2013-01-07
  • 打赏
  • 举报
回复
应该是 在你的一个 cpp 里,只注册了一个对象的工厂,可能表达不是很清楚,你去找找吧, 你实现了两个 COM 对象,但是默认创建工程只登记了第一个,你要找到这里,加上第二个,
步履人生 2013-01-05
  • 打赏
  • 举报
回复
CLSID没有问题,都是创建的自动生成的,另外这个两个ATL对象是用于shell的,调用是通过右键菜单和文件属性来调用的。 如果将两个ATL对象分开到两个不同的ATL COM工程中运行是没有问题的,但是合在一起就有问题,就是第二个不能运行。 下面的是我的idl文件内容
import "oaidl.idl";
import "ocidl.idl";
	[
		object,
		uuid(DB456395-46F3-47AE-8887-E76B1D4648C0),
	
		helpstring("IFTComment Interface"),
		pointer_default(unique)
	]
	interface IFTComment : IUnknown
	{
	};

	[
		object,
		uuid(D22F5D40-1DDD-48BA-A760-EE8F85F3AEF1),
	
		helpstring("IFTProp Interface"),
		pointer_default(unique)
	]
	interface IFTProp : IUnknown
	{
	};
[
	uuid(F6EAED7B-24B7-4BB6-9F26-5A9C918F4E2E),
	version(1.0),
	helpstring("FTManager 1.0 Type Library")
]
library FTMANAGERLib
{
	importlib("stdole32.tlb");
	importlib("stdole2.tlb");

	[
		uuid(FFA53628-0D3B-43D5-AF64-1E1656B7EE24),
		helpstring("FTComment Class")
	]
	coclass FTComment
	{
		[default] interface IFTComment;
	};

	[
		uuid(BA056691-6D35-4666-A255-3C79CC110C61),
		helpstring("FTProp Class")
	]
	coclass FTProp
	{
		[default] interface IFTProp;
	};
};
jimette 2013-01-04
  • 打赏
  • 举报
回复
两个冲突了 不清楚啊大牛 顶
加载更多回复(4)

16,472

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC相关问题讨论
社区管理员
  • 基础类社区
  • Web++
  • encoderlee
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

        VC/MFC社区版块或许是CSDN最“古老”的版块了,记忆之中,与CSDN的年龄几乎差不多。随着时间的推移,MFC技术渐渐的偏离了开发主流,若干年之后的今天,当我们面对着微软的这个经典之笔,内心充满着敬意,那些曾经的记忆,可以说代表着二十年前曾经的辉煌……
        向经典致敬,或许是老一代程序员内心里面难以释怀的感受。互联网大行其道的今天,我们期待着MFC技术能够恢复其曾经的辉煌,或许这个期待会永远成为一种“梦想”,或许一切皆有可能……
        我们希望这个版块可以很好的适配Web时代,期待更好的互联网技术能够使得MFC技术框架得以重现活力,……

试试用AI创作助手写篇文章吧