Michael Jung wrote:
Hi all,
Some shell namespace extensions only work if COM is initialized (For instance the brand-new shell instance objects ;) Go download the free (as in beer) Shell Object Editor from www.tropictech.de if you want to try them.). On WinXP those work without the application calling CoInitialize in SHBrowseForFolder and in the file dialogs. I assume this means there is a CoInitialize/CoUninitialize pair guarding SHBrowseForFolder.
For the attached browse.c test program (meant to be compiled with borland's free compiler - sorry) on can browse into shell instance objects on winxp, but the call to GetDisplayNameOf fails with CO_E_NOTINITIALIZED. This means COM is initialized inside SHBrowseForFolder, but un-initialized after the call returns. If you remove the '//' in front of the CoInitialize call and compile again, GetDisplayNameOf succeeds.
On wine, you can't currently browse into shell instance objects, if COM is not initialized. If you add CoInitialize/CoUninitialize to SHBrowseForFolder (see attached patch), it exhibits the same behaviour as winxp.
How expensive is COM un-/initialization?
It depends on the threading model you specify. Apartment threading is more expensive than multi-threaded because it involves the creation of a window, but both are fairly cheap (although I haven't got any numbers to back this up). It is even cheaper if the thread has already initialized COM.
Any objections against adding CoInitialize/CoUnitialize to SHBrowseForFolder and the file dialogs?
The only objection is that in general it is bad to force a threading model and that the caller should be the one specifying it. However, if this is what native shell32 does then we should also do it.