IOleWindow对于IFileDialog无法正常工作?

时间:2018-11-20 22:20:45

标签: c# com common-dialog

我正在使用一些使用Microsoft.WindowsAPICodePack的代码来提供Vista样式的通用对话框(IFileOpenDialogIFileSaveDialog)的C#包装。我想在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";

当我将传递给IFileDialog的{​​{1}}投射到OnFileOk时(最近我没有在COM interop上做过很多工作,但这包装了对IOleWindow的调用在底层的COM世界中,对吗?),不会发生错误,并且QueryInterface引用不是IOleWindow。但是,当我打电话给null时,它似乎总是返回GetWindow。我尝试用一​​个IntPtr.Zero参数而不是一个返回值声明该方法,并得到相同的结果:没有错误,但总是out

有人看到我在做什么错吗?我没有做错什么,但有时您无法获得窗口句柄?

1 个答案:

答案 0 :(得分:0)

@Hans Passant的回覆令人垂涎。 COM接口中方法的顺序很重要,我的顺序很错,很简单。我从按字母顺序排序的文档中获得订单,而不是从实际的IDL中获得订单。 :-P

顺序错误,仅适用于人眼:

正确的订单,实际的IDL:

(我不知道GitHub上的@tpn是谁,此链接可能会中断,但如果确实如此,则只需从Windows SDK中的文件IOleWindow中查找OleIdl.idl。:-))