IOleWindow 对于 IFileDialog 不能正常工作?

IOleWindow not working properly for IFileDialog?

我正在处理一些代码,这些代码使用 Microsoft.WindowsAPICodePack 来提供 Vista 风格的通用对话框(IFileOpenDialogIFileSaveDialog)的 C# 包装器。我想在 OnFileOk 事件回调中添加所选项目的验证,这主要是工作,但它的一个方面是提取对话框的 HWND 以用作消息框的父级显示。 Microsoft 提供了有关如何执行此操作的文档:

The calling process can use the window handle of the dialog itself as the parent of the UI. That handle can be obtained by first calling IOleWindow::QueryInterface and then calling IOleWindow::GetWindow with the handle as shown in this example.

(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";

当我将传递到 OnFileOkIFileDialog 转换为 IOleWindow 时(我最近没有对 COM 互操作做那么多工作,但这包含对 [=18 的调用=] 在底层 COM 世界中,对吗?),没有错误发生并且 IOleWindow 引用不是 null。但是,当我调用 GetWindow 时,它似乎总是 return IntPtr.Zero。我尝试使用 out 参数而不是 return 值声明该方法,并得到相同的结果:没有错误,但总是 IntPtr.Zero.

有人看到我做错了什么了吗?我没有做错什么,只是有时你无法获得 window 句柄??

@Hans Passant 的回复令人难以置信。 COM 接口中方法的顺序很重要,我弄错了顺序,就这么简单。我从按字母顺序排序的文档中得到了顺序,而不是从实际的 IDL 中得到的。 :-P

顺序错误,仅供人眼查看:

正确顺序,实际IDL:

(我不知道 GitHub 上的 @tpn 是谁,这个 link 可能会崩溃,但如果确实如此,那么只需在文件 [=11= 中查找 IOleWindow ] 来自 Windows SDK。:-) )