using ATL7.0 instead of ATL3, I'm missing something but what?
-
Hello! I've implemented
IShellExtInit
andIContextMenu
and followed the Complete Idiots guide by Michael Dunn. But I'm using ATL7.0 and some stuff is different. Like theCComModule
has been replaced. From MSDN: "As of ATL 7.0, CComModule is obsolete: see ATL Module Classes for more details." The wizard in VS.NET 2003 implementedCAtlDllModuleT
. Everything compiles, but my class (T2TContextMenu) isn't called (I have set up breakpoints in all functions). I've checked the registry and my key is there: HKEY_CLASSES_ROOT\.omfg\ShellEx\ContextMenuHandlers\This2That default value = "{3E670573-EA3F-498A-8EB1-F72DA6B5D221}" as a string The only difference I can see between my code and the tutorial is in theDllMain()
. The tutorial calls_Module.Init(ObjectMap, hInstance, &LIBID_SIMPLEEXTLib);
and has a Object map that includes the COM class the DLL is going to use. Mine doesn't. So my guess is that I have to pass the CLSID and maybe my classname somewhere toCAtlDllModuleT
. MSDN gave me this: "Init and Term methods have moved into the constructors and destructors for the module classes; there is no longer a need to call Init and Term." VS.NET created CThis2That like this:class CThis2ThatModule : public CAtlDllModuleT< CThis2ThatModule >
{
public :
DECLARE_LIBID(LIBID_This2ThatLib)
DECLARE_REGISTRY_APPID_RESOURCEID(IDR_THIS2THAT, "{3E670573-EA3F-498A-8EB1-F72DA6B5D221}")
};And CT2TContextMenu like this (I added the IShellExtInit/IContextMenu stuff):
class ATL_NO_VTABLE CT2TContextMenu :
public CComObjectRootEx<CComSingleThreadModel>,
public CComCoClass<CT2TContextMenu, &CLSID_T2TContextMenu>,
public IDispatchImpl<IT2TContextMenu, &IID_IT2TContextMenu, &LIBID_This2ThatLib, /*wMajor =*/ 1, /*wMinor =*/ 0>,
public IShellExtInit,
public IContextMenu
{
public:
CT2TContextMenu(){}DECLARE_REGISTRY_RESOURCEID(IDR_T2TCONTEXTMENU)
DECLARE_PROTECT_FINAL_CONSTRUCT()
BEGIN_COM_MAP(CT2TContextMenu)
COM_INTERFACE_ENTRY(IT2TContextMenu)
COM_INTERFACE_ENTRY(IDispatch)
COM_INTERFACE_ENTRY(IShellExtInit)
COM_INTERFACE_ENTRY(IContextMenu)
END_COM_MAP()HRESULT FinalConstruct(){ return S\_OK; } void FinalRelease() {}
public:
// IShellExtInit
STDMETHOD(Initialize)(LPCITEMIDLIST, LPDATAOBJECT, HKEY);// IContextMenu STDMETHOD(GetCommandString)(UINT, UINT, UINT\*, LPSTR, UINT); STDMETHOD(InvokeCommand)(LPCMINVOKECOMMANDINFO); STDMETHOD
-
Hello! I've implemented
IShellExtInit
andIContextMenu
and followed the Complete Idiots guide by Michael Dunn. But I'm using ATL7.0 and some stuff is different. Like theCComModule
has been replaced. From MSDN: "As of ATL 7.0, CComModule is obsolete: see ATL Module Classes for more details." The wizard in VS.NET 2003 implementedCAtlDllModuleT
. Everything compiles, but my class (T2TContextMenu) isn't called (I have set up breakpoints in all functions). I've checked the registry and my key is there: HKEY_CLASSES_ROOT\.omfg\ShellEx\ContextMenuHandlers\This2That default value = "{3E670573-EA3F-498A-8EB1-F72DA6B5D221}" as a string The only difference I can see between my code and the tutorial is in theDllMain()
. The tutorial calls_Module.Init(ObjectMap, hInstance, &LIBID_SIMPLEEXTLib);
and has a Object map that includes the COM class the DLL is going to use. Mine doesn't. So my guess is that I have to pass the CLSID and maybe my classname somewhere toCAtlDllModuleT
. MSDN gave me this: "Init and Term methods have moved into the constructors and destructors for the module classes; there is no longer a need to call Init and Term." VS.NET created CThis2That like this:class CThis2ThatModule : public CAtlDllModuleT< CThis2ThatModule >
{
public :
DECLARE_LIBID(LIBID_This2ThatLib)
DECLARE_REGISTRY_APPID_RESOURCEID(IDR_THIS2THAT, "{3E670573-EA3F-498A-8EB1-F72DA6B5D221}")
};And CT2TContextMenu like this (I added the IShellExtInit/IContextMenu stuff):
class ATL_NO_VTABLE CT2TContextMenu :
public CComObjectRootEx<CComSingleThreadModel>,
public CComCoClass<CT2TContextMenu, &CLSID_T2TContextMenu>,
public IDispatchImpl<IT2TContextMenu, &IID_IT2TContextMenu, &LIBID_This2ThatLib, /*wMajor =*/ 1, /*wMinor =*/ 0>,
public IShellExtInit,
public IContextMenu
{
public:
CT2TContextMenu(){}DECLARE_REGISTRY_RESOURCEID(IDR_T2TCONTEXTMENU)
DECLARE_PROTECT_FINAL_CONSTRUCT()
BEGIN_COM_MAP(CT2TContextMenu)
COM_INTERFACE_ENTRY(IT2TContextMenu)
COM_INTERFACE_ENTRY(IDispatch)
COM_INTERFACE_ENTRY(IShellExtInit)
COM_INTERFACE_ENTRY(IContextMenu)
END_COM_MAP()HRESULT FinalConstruct(){ return S\_OK; } void FinalRelease() {}
public:
// IShellExtInit
STDMETHOD(Initialize)(LPCITEMIDLIST, LPDATAOBJECT, HKEY);// IContextMenu STDMETHOD(GetCommandString)(UINT, UINT, UINT\*, LPSTR, UINT); STDMETHOD(InvokeCommand)(LPCMINVOKECOMMANDINFO); STDMETHOD
Hmmm... do you have an instance in your module of CThis2That ? I.e. like: CThis2That myModuleThingyStuff; I think you need it because then the constructor/destructor of it will be called when the DLL is loaded (and _Module.Init()/ .Term() will also be called). Hope that helps, /Rob
-
Hmmm... do you have an instance in your module of CThis2That ? I.e. like: CThis2That myModuleThingyStuff; I think you need it because then the constructor/destructor of it will be called when the DLL is loaded (and _Module.Init()/ .Term() will also be called). Hope that helps, /Rob
Yes, VS.NET created that for me. There's a global
CThis2ThatModule _AtlModule;
Init() is completely gone according to MSDN and is "replaced" by the constructor. While Term() is still there it's called by the destructor. What I don't know how to do is how I should pass myCT2TContextMenu
soCThis2ThatModule
will register it or whatever it's called. When the Init() function was available in ATL3.0 there was a object map and that was passed to _TheGlobalModule.Init(), this is where myCT2TContextMenu
would've been passed. But I don't know how to do it in ATL7.0... -
Hello! I've implemented
IShellExtInit
andIContextMenu
and followed the Complete Idiots guide by Michael Dunn. But I'm using ATL7.0 and some stuff is different. Like theCComModule
has been replaced. From MSDN: "As of ATL 7.0, CComModule is obsolete: see ATL Module Classes for more details." The wizard in VS.NET 2003 implementedCAtlDllModuleT
. Everything compiles, but my class (T2TContextMenu) isn't called (I have set up breakpoints in all functions). I've checked the registry and my key is there: HKEY_CLASSES_ROOT\.omfg\ShellEx\ContextMenuHandlers\This2That default value = "{3E670573-EA3F-498A-8EB1-F72DA6B5D221}" as a string The only difference I can see between my code and the tutorial is in theDllMain()
. The tutorial calls_Module.Init(ObjectMap, hInstance, &LIBID_SIMPLEEXTLib);
and has a Object map that includes the COM class the DLL is going to use. Mine doesn't. So my guess is that I have to pass the CLSID and maybe my classname somewhere toCAtlDllModuleT
. MSDN gave me this: "Init and Term methods have moved into the constructors and destructors for the module classes; there is no longer a need to call Init and Term." VS.NET created CThis2That like this:class CThis2ThatModule : public CAtlDllModuleT< CThis2ThatModule >
{
public :
DECLARE_LIBID(LIBID_This2ThatLib)
DECLARE_REGISTRY_APPID_RESOURCEID(IDR_THIS2THAT, "{3E670573-EA3F-498A-8EB1-F72DA6B5D221}")
};And CT2TContextMenu like this (I added the IShellExtInit/IContextMenu stuff):
class ATL_NO_VTABLE CT2TContextMenu :
public CComObjectRootEx<CComSingleThreadModel>,
public CComCoClass<CT2TContextMenu, &CLSID_T2TContextMenu>,
public IDispatchImpl<IT2TContextMenu, &IID_IT2TContextMenu, &LIBID_This2ThatLib, /*wMajor =*/ 1, /*wMinor =*/ 0>,
public IShellExtInit,
public IContextMenu
{
public:
CT2TContextMenu(){}DECLARE_REGISTRY_RESOURCEID(IDR_T2TCONTEXTMENU)
DECLARE_PROTECT_FINAL_CONSTRUCT()
BEGIN_COM_MAP(CT2TContextMenu)
COM_INTERFACE_ENTRY(IT2TContextMenu)
COM_INTERFACE_ENTRY(IDispatch)
COM_INTERFACE_ENTRY(IShellExtInit)
COM_INTERFACE_ENTRY(IContextMenu)
END_COM_MAP()HRESULT FinalConstruct(){ return S\_OK; } void FinalRelease() {}
public:
// IShellExtInit
STDMETHOD(Initialize)(LPCITEMIDLIST, LPDATAOBJECT, HKEY);// IContextMenu STDMETHOD(GetCommandString)(UINT, UINT, UINT\*, LPSTR, UINT); STDMETHOD(InvokeCommand)(LPCMINVOKECOMMANDINFO); STDMETHOD
The tutorial had this:
BEGIN_OBJECT_MAP(ObjectMap)
OBJECT_ENTRY(CLSID_SimpleShlExt, CSimpleShlExt)
END_OBJECT_MAP()// DllMain(), a bunch of stuff and:
_Module.Init(ObjectMap, hInstance, &LIBID_SIMPLEEXTLib); // Where _Module is a CComModuleWhat I found out from MSDN is that that type of object map has been replaced by
OBJECT_ENTRY_AUTO
and inspecting my code VS.NET had already generated this for me:OBJECT_ENTRY_AUTO(__uuidof(T2TContextMenu), CT2TContextMenu)
What I've understood that means that the main module object does has some kind of reference to my context menu. But why isn't it called?