SetThemeAppProperties disables COM Common Dialogs

0

Calling SetThemeAppProperties with argument which has flag STAP_ALLOW_CONTROLS unset causes CoCreateInstance for Common Dialogs (or at list File Open Dialog, CLSID_FileOpenDialog) to return error 0x80040111.

Sample code is following:

HRESULT hResult;
CComPtr< IFileOpenDialog > pFileOpenInterface1;
CComPtr< IFileOpenDialog > pFileOpenInterface2;

hResult = ::CoCreateInstance( CLSID_FileOpenDialog, NULL, CLSCTX_INPROC_SERVER, IID_PPV_ARGS( &pFileOpenInterface1 ) );
::SetThemeAppProperties( 0 );
hResult = ::CoCreateInstance( CLSID_FileOpenDialog, NULL, CLSCTX_INPROC_SERVER, IID_PPV_ARGS( &pFileOpenInterface2 ) );

To make it into running code I have created (in Visual Studio 2010 Professional) a simple Win32 GUI application and added that code to menu Help|About handler.

Why is it so and how to work around that issue?

winapi
com
fileopendialog
common-dialog
windows-themes
asked on Stack Overflow Mar 11, 2011 by Adam Badura

3 Answers

1

Disabling visual styles on all controls is a pretty heavy hammer. Not that surprising that the latest version of the dialogs don't support it. Try to fall back to the legacy shell dialog interface with GetOpenFileName(). Next remove the manifest entry that enables the 6.0 version of the common controls. A bit anathema to the idea of skinning perhaps.

answered on Stack Overflow Mar 11, 2011 by Hans Passant
0

Maybe a stupid question: but do you call InitCommonControlsEx() and CoInitializeEx() before you try to use CoCreateInstance?

My guess is that your call to SetThemeAppProperties initializes COM automatically if the STAP_ALLOW_CONTROLS flag is set. But you have to do it yourself if that flag isn't set.

answered on Stack Overflow Mar 11, 2011 by Stefan
0

Using Templates to customize common dialog it's not that easy on Windows 7. First you have to force GetOpenFileName to call legacy function from DoModal which can be easily done with m_bVistaStyle = false. But than i had to deal with some assertion

ASSERT(pThreadState->m_pAlternateWndInit == NULL);
pThreadState->m_pAlternateWndInit = NULL;

I am still not sure what is it for but it can be 'work arounded' with handling WM_NCDESTROY and simply assigning

_AFX_THREAD_STATE* pThreadState = AfxGetThreadState();
if( ::IsWindow( pThreadState->m_pAlternateWndInit->m_hWnd ) )
TRACE( "scary..." );
else
pThreadState->m_pAlternateWndInit = NULL;
TRACE( "WM_NCDESTROY");
return false;

in window procedure. However what i didn't managed is to obtain selected file names from OpenFile Dialog on CDN_SELCHANGE. Sending CDM_GETFILEPATH returns only 256 chars, no matter how big is the buffer using with this msg. Maybe someone know a way to do this on windows 7?

answered on Stack Overflow Mar 11, 2011 by Lukasz Foniok

User contributions licensed under CC BY-SA 3.0