COM-Server ohne ATL

Cromon

Erfahrenes Mitglied
Hallo zusammen!

Nachdem ich bereits oft und erfolgreich über ATL DLLs erstellt habe welche als Inprozess-Server für COM fungieren wollte ich mal lernen, wie das selber funktioniert. Bisher sieht das ganz gut aus. Ich habe die nötigen Funktionen nach aussen gelinkt:
Code:
#pragma comment (linker, "/EXPORT:DllRegisterServer=_DllRegisterServer@0,PRIVATE")
#pragma comment (linker, "/EXPORT:DllGetClassObject=_DllGetClassObject@12,PRIVATE")
#pragma comment (linker, "/EXPORT:DllUnregisterServer=_DllUnregisterServer@0,PRIVATE")
#pragma comment (linker, "/EXPORT:DllCanUnloadNow=_DllCanUnloadNow@0,PRIVATE")

static int gRefCount = 0;

STDAPI DllRegisterServer()
{
	// Registryeinträge sind bereits gemacht
	return S_OK;
}

STDAPI DllUnregisterServer()
{
	// Mach ich auch manuell
	return S_OK;
}

STDAPI DllCanUnloadNow()
{
	// Noch nicht implementiert, wird aber scheinbar auch nicht aufgerufen.
	MessageBoxA(0, "CanUnload", "", MB_OK);
	return gRefCount ? S_FALSE : S_OK;
}

STDAPI DllGetClassObject(const IID& rclsid, const IID& iid, LPVOID* ppv)
{
	CClassFactory<ShellExt>* pCf = new CClassFactory<ShellExt>();
	pCf->QueryInterface(iid, ppv);
	pCf->Release();
	return S_OK;
}

Das funktioniert soweit auch alles, meine CClassFactory funktioniert auch, es wird nämlich einwandfrei ShellExt::QueryInterface aufgerufen:
Code:
HRESULT __stdcall ShellExt::QueryInterface(const IID& rrid, void** ppvObject)
{
	*ppvObject = this;
	AddRef();
	return S_OK;
}

Nun kommt aber ein Problem. Die von mir implementierten Funktionen werden nicht aufgerufen! Man hovert die Datei und QueryInterface wird aufgerufen. Aber weder IQueryInfo::GetInfoFlags noch IQueryInfo:GetInfoTip werden aufgerufen. Es werden hingegen IPersistFile::GetClassID aufgerufen und IPersistFile::IsDirty. Allerdings habe ich bei diesen wie bei meinen anderen auf ATL basierenden Projekten E_NOTIMPL zurückgegeben und da funktioniert es dann auch.

Hat jemand von euch eine Ahnung, woran das liegen könnte?

Oder kennt jemand von euch ein Forum, das auf COM spezialisiert ist?

Gruss
Cromon
 
Zuletzt bearbeitet:
Problem erkannt, Problem gebannt.

Einerseits fehlte die überprüfung, ob das Interface wirklich unterstützt wird:
Code:
HRESULT __stdcall ShellExt::QueryInterface(const IID& riid, void** ppv)
{
	if(IsEqualIID(riid, IID_IUnknown))
	{
		*ppv = this;
		AddRef();
		return S_OK;
	}
	if(IsEqualIID(riid, IID_IPersistFile))
	{
		*ppv = static_cast<IPersistFile*>(this);
		AddRef();
		return S_OK;
	}
	if(IsEqualIID(riid, IID_IQueryInfo))
	{
		*ppv = static_cast<IQueryInfo*>(this);
		AddRef();
		return S_OK;
	}
	return E_NOINTERFACE;
}

Andererseits habe ich vergessen das ThreadingModel in der REgistry einzustellen.
 
Zurück