我正在使用一些使用Microsoft.WindowsAPICodePack的代码来提供Vista样式的通用对话框(IFileOpenDialog
,IFileSaveDialog
)的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
。
有人看到我在做什么错吗?我没有做错什么,但有时您无法获得窗口句柄?
答案 0 :(得分:0)
@Hans Passant的回覆令人垂涎。 COM接口中方法的顺序很重要,我的顺序很错,很简单。我从按字母顺序排序的文档中获得订单,而不是从实际的IDL中获得订单。 :-P
顺序错误,仅适用于人眼:
正确的订单,实际的IDL:
(我不知道GitHub上的@tpn是谁,此链接可能会中断,但如果确实如此,则只需从Windows SDK中的文件IOleWindow
中查找OleIdl.idl
。:-))