代码之家  ›  专栏  ›  技术社区  ›  Jonathan Gilbert

IOleWindow在iFileDialog中工作不正常?

  •  0
  • Jonathan Gilbert  · 技术社区  · 6 年前

    我正在使用一些代码,这些代码使用microsoft.windowsapicodepack来提供Vista样式公共对话框的C包装器。( IFileOpenDialog ,请 IFileSaveDialog )。我要将所选项目的验证添加到 OnFileOk 事件回调,这基本上是有效的,但它的一个方面是提取对话框的Hwnd以用作显示的消息框的父级。Microsoft提供了有关如何执行此操作的文档:

    调用进程可以使用对话框本身的窗口句柄作为UI的父级。这个句柄可以通过第一次调用获得 IOleWindow::查询接口 然后打电话 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 传入 OnFoeOK IOL窗口 (我最近没有对COM Interop做过那么多的工作,但这包含了对 QueryInterface 在底层的COM世界中,对吗?),未发生错误,并且 IOL窗口 引用不是 null . 但是,当我打电话的时候 GetWindow ,似乎总是会回来 IntPtr.Zero . 我尝试用 out 参数而不是返回值,得到相同的结果:没有错误,但始终 零度 .

    有人看到我做错了什么吗?我是不是没做错什么,只是有时候你拿不到窗把手??

    1 回复  |  直到 6 年前
        1
  •  0
  •   Jonathan Gilbert    6 年前

    @汉斯·帕桑特的回答很有说服力。COM接口中方法的顺序很重要,我的顺序是错误的,很简单。我从按字母顺序排序的文档中得到了订单,而不是从实际的IDL中得到的。-P

    错误顺序,仅限人眼:

    正确的顺序,实际IDL:

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