【问题标题】:IOleWindow not working properly for IFileDialog?IOleWindow 不能为 IFileDialog 正常工作?
【发布时间】:2018-11-20 22:20:44
【问题描述】:

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

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

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

【问题讨论】:

  • 一个可用的 IOleWindow 声明是available here。获取方法是错误的顺序是相当致命的。
  • 非常感谢!现在就试试吧。
  • 我相信您已经知道,这正是问题所在。如果您想提交一个答案,即使是“COM 接口中的方法顺序很重要,而您的 IOleWindow 声明中的顺序是错误的”,我也很乐意将其标记为答案。 :-)

标签: c# com common-dialog


【解决方案1】:

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

顺序错误,仅限人眼:

正确的顺序,实际的 IDL:

(我不知道 GitHub 上的 @tpn 是谁,这个链接可能会断开,但如果它断开了,那么只需在 Windows SDK 的文件 OleIdl.idl 中查找 IOleWindow。:-))

【讨论】:

    猜你喜欢
    • 2016-07-16
    • 2019-01-04
    • 2020-09-03
    • 2016-10-10
    • 2016-10-24
    • 2017-02-27
    • 2017-07-08
    • 2014-11-23
    • 2021-03-07
    相关资源
    最近更新 更多