【发布时间】:2018-11-20 22:20:44
【问题描述】:
我正在处理一些代码,这些代码使用 Microsoft.WindowsAPICodePack 来提供 Vista 风格的通用对话框的 C# 包装器(IFileOpenDialog、IFileSaveDialog)。我想在OnFileOk 事件回调中添加对所选项目的验证,这主要是可行的,但其中一个方面是提取对话框的 HWND 以用作显示的消息框的父级. Microsoft 提供了有关如何执行此操作的文档:
调用进程可以使用对话框本身的窗口句柄作为 UI 的父级。该句柄可以通过首先调用 IOleWindow::QueryInterface 然后使用该句柄调用 IOleWindow::GetWindow 来获得,如本例所示。
(https://msdn.microsoft.com/en-us/library/windows/desktop/bb776913(v=vs.85).aspx)
我在代码中添加了IOleWindow接口的定义:
[ComImport,
Guid(ShellIIDGuid.IOleWindow),
InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
internal interface IOleWindow
{
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
void ContextSensitiveHelp(
[In] bool fEnterMode);
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
IntPtr GetWindow();
}
...
internal const string IOleWindow = "00000114-0000-0000-C000-000000000046";
当我将传递给OnFileOk 的IFileDialog 转换为IOleWindow 时(我最近在COM 互操作方面没有做太多工作,但这包含了对底层COM 世界中QueryInterface 的调用,对吧? ),不会发生错误并且IOleWindow 引用不是null。但是,当我调用GetWindow 时,它似乎总是返回IntPtr.Zero。我尝试使用out 参数而不是返回值来声明该方法,并得到相同的结果:没有错误,但总是IntPtr.Zero。
有人看到我做错了吗?我没有做错什么,但有时您无法获得窗口句柄??
【问题讨论】:
-
一个可用的 IOleWindow 声明是available here。获取方法是错误的顺序是相当致命的。
-
非常感谢!现在就试试吧。
-
我相信您已经知道,这正是问题所在。如果您想提交一个答案,即使是“COM 接口中的方法顺序很重要,而您的 IOleWindow 声明中的顺序是错误的”,我也很乐意将其标记为答案。 :-)
标签: c# com common-dialog