Click to See Complete Forum and Search --> : IClassFactory::CreateInstance is not being called


Markus_Karg
April 24th, 1999, 05:11 AM
I am just a beginner in COM programming and wanted to start with a simple example: Adding a context menu handler to the WinNT4 explorer.

All just went good until now, and I don't know where I am wrong because hardly all of my code is copied from the SDK samples delivered with VC5.

The problem is: My DLL gets loaded and DllGetClassObject is called. My implementation of QueryInterface is called (the explorer asks for IID_ClassFactory which I expected). Now see the following code (from SDK examples):



extern "C" HRESULT __stdcall DllGetClassObject ( REFCLSID rclsid , REFIID riid , LPVOID * ppvObj )
{
HRESULT hRes = E_OUTOFMEMORY ;

* ppvObj = NULL ;

CMyClassFactory * pClassFactory = new CMyClassFactory ( /* rclsid */ ) ;

if ( pClassFactory != NULL )
{
hRes = E_UNEXPECTED ;

if ( riid == IID_IClassFactory )
{
hRes = pClassFactory -> QueryInterface ( riid , ppvObj ) ;
pClassFactory -> Release ( ) ;
}

}

return hRes ;
}





After finishing the call to DllGetClassObject, my debug log says that QueryInterface (and AddRef, which is called from inner QueryInterface) is done, even Release is done, which frees the newly created instance - all right I think, it's just what the SDK examples do.

But then, there is NEVER Initialize (IShellExtInit) NOR CreateInstance (IClassFactory) called!

When I do NOT call Release in the upper code, Initialize (IShellExtInit) is called, but CreateInstance (IClassFactory) is NEVER called but the is a GPF.

Where am I wrong?

From former times I know there is a bug in the SDK examples somewhere, but I can't remeber where!

Markus Karg

April 26th, 1999, 04:06 AM
After calling "new" the reference count of the class factory is 0. The QueryInterface increments the counter to 1 and the Release decrements the counter to 0. When the counter changes from 1 to 0, the object is deleted. I recommend you to call pClassFactory->AddRef() after calling new.

Markus_Karg
April 26th, 1999, 11:41 AM
I understand what you explain, but why is the pClassFactory->Release() in the example? If I do QueryInterface, AddRef, Release I also just can do QueryInterface and nothing else, I think, and this is what makes my server crash. :-(

Markus Karg

MoMoPi
April 26th, 1999, 12:00 PM
The following codes are working in my prj:
// Can we create this component?
if (clsid != CLSID_Component1)
{
return CLASS_E_CLASSNOTAVAILABLE ;
}

// Create class factory.
CFactory* pFactory = new CFactory ; // Reference count set to 1
if (pFactory == NULL)
{
return E_OUTOFMEMORY ;
}

// Get requested interface.
HRESULT hr = pFactory->QueryInterface(iid, ppv);
pFactory->Release() ;

return hr ;

Markus_Karg
May 3rd, 1999, 03:59 PM
Hi,
unfortunately I was not able to solve my problems. I have now about 100 lines of code in my skeleton Shell Extension. Maybe there is someone such kind to help me a bit by watching my very easy to read code? I think for one that understands Shell Extensions and COM it would be a one minute job to find my mistake. Please, help me, COM code gurus! :-)

Markus Karg

ravish
April 11th, 2000, 11:31 AM
The Release() after the QueryInterface is not REALLY necessary. But it is a good programming practice to have release. But on the same hand if you want to use the Release then you have write the constructor in such a way that it initializes the reference to 1. This is becoz when the object is created it is set to one, and the if QueryInterface fails, the release will set it to 0 and then the object will be deleted. And at the same time, if it is passed the release will nuillify the effect of setting 1 in constructor. I guess you initiated to 0 in the constructor and used like this in the class factory, that made your server crash.
Ravi

SublimeAscetic
April 11th, 2000, 06:15 PM
I agree with Ravish's reasoning. For a good explanation and some sample code check out Chapter Seven from "Inside COM" by Dale Rogerson.

Mike Wild
April 12th, 2000, 02:28 AM
If you really want some good samples go to the codeproject.com-site and look for the shellext-Tutorial which has five parts and adds some good code.

Mike