SetThemeAppProperties 禁用 COM 通用对话框
使用带有标志 < 的参数调用 SetThemeAppProperties
code>STAP_ALLOW_CONTROLS 未设置会导致 CoCreateInstance
对于通用对话框(或列表文件打开对话框,CLSID_FileOpenDialog
)返回错误0x80040111
。
示例代码如下:
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 ) );
为了使其成为运行代码,我(在 Visual Studio 2010 Professional 中)创建了一个简单的 Win32 GUI 应用程序,并将该代码添加到菜单“帮助|关于处理程序”中。
为什么会这样以及如何解决这个问题?
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?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
禁用所有控件上的视觉样式是一个相当重的锤子。最新版本的对话框不支持它也就不足为奇了。尝试使用 GetOpenFileName() 回退到旧版 shell 对话框界面。接下来删除启用 6.0 版本公共控件的清单条目。也许对剥皮的想法有点厌恶。
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.
也许是一个愚蠢的问题:但是你打电话 InitCommonControlsEx() 和 CoInitializeEx()在尝试使用 CoCreateInstance 之前?
我的猜测是,如果设置了 STAP_ALLOW_CONTROLS 标志,则对 SetThemeAppProperties 的调用会自动初始化 COM。但如果未设置该标志,您必须自己执行此操作。
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.
使用模板自定义通用对话框在 Windows 7 上并不那么容易。首先,您必须强制 GetOpenFileName 从 DoModal 调用旧函数,这可以通过 m_bVistaStyle = false 轻松完成。但我必须处理一些断言
ASSERT(pThreadState->m_pAlternateWndInit == NULL);
pThreadState->m_pAlternateWndInit = NULL;
我仍然不确定它的用途,但它可以通过处理 WM_NCDESTROY 来“解决”并且简单地
指派
_AFX_THREAD_STATE* pThreadState = AfxGetThreadState();
if( ::IsWindow( pThreadState->m_pAlternateWndInit->m_hWnd ) )
TRACE( "scary..." );
else
pThreadState->m_pAlternateWndInit = NULL;
TRACE( "WM_NCDESTROY");
return false;
在窗口过程中。但是我没有成功的是从“打开文件”对话框中获取选定的文件名
在 CDN_SELCHANGE 上。发送 CDM_GETFILEPATH 仅返回 256 个字符,无论此消息使用的缓冲区有多大。也许有人知道在 Windows 7 上执行此操作的方法?
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?