我试图在 C++ 中编写一个图标处理程序,但我有一些问题要做到这一点。我跟着 codeproject 的turoriel
本教程的不同之处在于我想用 Visual Studio (2013) 向导中的 ATL 项目对我的 dll 进行编码。所以我创建了一个新的 ATL 项目,并且我有一个该项目的 COM +1 类(这是标题的代码)。
问题是它接缝我的 dll 已附加但之后立即分离。
我将在下面放一些代码和更多解释:
extern "C" BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID lpReserved)
{
if (dwReason == DLL_PROCESS_ATTACH)
{
_AtlModule.InitLibId();
//_AtlModule.RegisterAppId();
}
return _AtlModule.DllMain(dwReason, lpReserved);;
}
这是我的 dll 的入口点。我在这个入口点做了很多尝试和测试。我试图写一些 dwReason 的登录函数,这个函数只有在我编译时才会启动。一次使用属性 DLL_PROCESS_ATTACH,另一次使用属性 DLL_PROCESS_DETACH。之后,即使我将注册表设置为在文件的 IconHandler 中调用此 dll,也没有任何接缝可以工作。
我将把我的 dllmain.h、我的 handler.h、我的 idl 文件和我的 rgs 文件放入其中。如果您需要更多代码来帮助我,我稍后再放。
dllmain.h
class CQIIconDllModule : public ATL::CAtlDllModuleT< CQIIconDllModule >
{
public :
DECLARE_LIBID(LIBID_QIIconDllLib)
DECLARE_REGISTRY_APPID_RESOURCEID(IDR_QIHANDLER, "{7FFCD43D-9EB3-4F76-940C-98C333FB8A99}")
};
extern class CQIIconDllModule _AtlModule;
图标处理程序.h
// QIHandler.h : Declaration of the CQIHandler
#pragma once
#include "resource.h" // main symbols
#include <ShlObj.h>
#include "QIIconDll_i.h"
#if defined(_WIN32_WCE) && !defined(_CE_DCOM) && !defined(_CE_ALLOW_SINGLE_THREADED_OBJECTS_IN_MTA)
#error "Single-threaded COM objects are not properly supported on Windows CE platform, such as the Windows Mobile platforms that do not include full DCOM support. Define _CE_ALLOW_SINGLE_THREADED_OBJECTS_IN_MTA to force ATL to support creating single-thread COM object's and allow use of it's single-threaded COM object implementations. The threading model in your rgs file was set to 'Free' as that is the only threading model supported in non DCOM Windows CE platforms."
#endif
using namespace ATL;
// CQIHandler
class ATL_NO_VTABLE CQIHandler :
public CComObjectRootEx<CComSingleThreadModel>,
public CComCoClass<CQIHandler, &CLSID_QIHandler>,
public IQIHandler,
public IPersistFile,
public IExtractIcon
{
public:
CQIHandler()
{
}
DECLARE_REGISTRY_RESOURCEID(IDR_QIHANDLER)
DECLARE_NOT_AGGREGATABLE(CQIHandler)
BEGIN_COM_MAP(CQIHandler)
COM_INTERFACE_ENTRY(IQIHandler)
COM_INTERFACE_ENTRY(IPersistFile)
COM_INTERFACE_ENTRY(IExtractIcon)
END_COM_MAP()
DECLARE_PROTECT_FINAL_CONSTRUCT()
HRESULT FinalConstruct()
{
return S_OK;
}
void FinalRelease()
{
}
public:
// IPersistFile
STDMETHODIMP GetClassID( CLSID* ) { return E_NOTIMPL; }
STDMETHODIMP IsDirty() { return E_NOTIMPL; }
STDMETHODIMP Save( LPCOLESTR, BOOL ) { return E_NOTIMPL; }
STDMETHODIMP SaveCompleted( LPCOLESTR ) { return E_NOTIMPL; }
STDMETHODIMP GetCurFile( LPOLESTR* ) { return E_NOTIMPL; }
STDMETHODIMP Load( LPCOLESTR wszFile, DWORD )
{
USES_CONVERSION;
lstrcpyn ( m_szFilename, W2CT(wszFile), MAX_PATH );
return S_OK;
}
// IExtractIcon
STDMETHODIMP GetIconLocation( UINT uFlags, LPTSTR szIconFile, UINT cchMax,
int* piIndex, UINT* pwFlags );
STDMETHODIMP Extract( LPCTSTR pszFile, UINT nIconIndex, HICON* phiconLarge,
HICON* phiconSmall, UINT nIconSize );
protected:
TCHAR m_szFilename[MAX_PATH]; // Full path to the file in question.
};
OBJECT_ENTRY_AUTO(__uuidof(QIHandler), CQIHandler)
我的idl文件
// QIIconDll.idl : IDL source for QIIconDll
//
// This file will be processed by the MIDL tool to
// produce the type library (QIIconDll.tlb) and marshalling code.
import "oaidl.idl";
import "ocidl.idl";
[
object,
uuid(a817e7a2-43fa-11d0-9e44-00aa00b6770a),
dual,
pointer_default(unique)
]
interface IComponentRegistrar : IDispatch
{
[id(1)] HRESULT Attach([in] BSTR bstrPath);
[id(2)] HRESULT RegisterAll();
[id(3)] HRESULT UnregisterAll();
[id(4)] HRESULT GetComponents([out] SAFEARRAY(BSTR)* pbstrCLSIDs, [out] SAFEARRAY(BSTR)* pbstrDescriptions);
[id(5)] HRESULT RegisterComponent([in] BSTR bstrCLSID);
[id(6)] HRESULT UnregisterComponent([in] BSTR bstrCLSID);
};
[
object,
uuid(1A80BA8B-2932-4EB4-AA88-5216F92BBA33),
pointer_default(unique)
]
interface IQIHandler : IUnknown{
};
[
uuid(17AD604F-FDD1-453C-A2D2-EAD3FCC42AB5),
version(1.0),
custom(a817e7a1-43fa-11d0-9e44-00aa00b6770a,"{D32D9690-E6A4-44D8-A949-5F39D35269F8}")
]
library QIIconDllLib
{
importlib("stdole2.tlb");
[
uuid(D32D9690-E6A4-44D8-A949-5F39D35269F8)
]
coclass CompReg
{
[default] interface IComponentRegistrar;
};
[
uuid(7FFCD43D-9EB3-4F76-940C-98C333FB8A99)
]
coclass QIHandler
{
[default] interface IQIHandler;
};
};
rgs 文件:
HKCR
{
NoRemove CLSID
{
ForceRemove {D32D9690-E6A4-44D8-A949-5F39D35269F8} = s 'CompReg Class'
{
InprocServer32 = s '%MODULE%'
{
val ThreadingModel = s 'Apartment'
}
TypeLib = s '{17AD604F-FDD1-453C-A2D2-EAD3FCC42AB5}'
Version = s '1.0'
}
}
}
rgs 处理程序文件:
HKCR
{
NoRemove CLSID
{
ForceRemove {7FFCD43D-9EB3-4F76-940C-98C333FB8A99} = s 'QIHandler Class'
{
InprocServer32 = s '%MODULE%'
{
val ThreadingModel = s 'Apartment'
}
TypeLib = s '{17AD604F-FDD1-453C-A2D2-EAD3FCC42AB5}'
Version = s '1.0'
}
}
NoRemove qifile
{
NoRemove DefaultIcon = s '%%1'
NoRemove ShellEx
{
ForceRemove IconHandler = s '{7FFCD43D-9EB3-4F76-940C-98C333FB8A99}'
}
}
}
我希望我的解释很清楚。如果您需要更多信息来回答我的问题,请告诉我我会尽快回答。我会感谢你花时间帮助我。
弗洛里安
编辑 :
在我的 dllmain 上查看我的测试。cpp
BOOL ret = false;
FILE *file;
fopen_s(&file, "test.txt","a+"); /* apend file (add text to
a file or create a file if it does not exist.*/
if (dwReason == DLL_PROCESS_ATTACH)
{
fprintf(file,"%s","Initialize AtlModule\n"); /*writes*/
_AtlModule.InitLibId();
HRESULT hr = _AtlModule.RegisterAppId();
if (SUCCEEDED(hr))
{
fprintf(file,"%s","Registrer app succeeded \n"); /*writes*/
hr = _AtlModule.RegisterServer(TRUE, &CLSID_QIHandler);
if (SUCCEEDED(hr))
{
fprintf(file,"%s","RegisterServer succeeded \n"); /*writes*/
hr = _AtlModule.UpdateRegistryAppId(TRUE);
if (SUCCEEDED(hr))
{
fprintf(file,"%s","UpdateRegistryAppId succeeded \n"); /*writes*/
ret = true;
}
}
}
}
#ifdef _DEBUG
else if (dwReason == DLL_PROCESS_DETACH)
{
_AtlModule.UpdateRegistryAppId(FALSE);
_AtlModule.Term();
}//*/
#endif
if (dwReason == DLL_PROCESS_DETACH && lpReserved != NULL)
{
ret = true;
}
else if (dwReason == DLL_PROCESS_DETACH)
{
fprintf(file,"%s","Execption ! \n"); /*writes*/
}
fclose(file); /*done!*/
return ret;
我的 test.txt 中的结果:
Initialize AtlModule
Registrer app succeeded
RegisterServer succeeded
UpdateRegistryAppId succeeded
Execption !
这里有人有想法吗?