【发布时间】:2010-11-11 13:06:23
【问题描述】:
例如,这是IFileOpenDialog 接口的完整定义,一个Windows Shell 接口,取自Pinvoke 站点:
[ComImport, Guid ( "d57c7288-d4ad-4768-be02-9d969532d960" ), InterfaceType ( ComInterfaceType.InterfaceIsIUnknown )]
interface IFileOpenDialog : IFileDialog
{
// Defined on IModalWindow - repeated here due to requirements of COM interop layer
// --------------------------------------------------------------------------------
[MethodImpl ( MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime ), PreserveSig]
int Show ( [In] IntPtr parent );
// Defined on IFileDialog - repeated here due to requirements of COM interop layer
[MethodImpl ( MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime )]
void SetFileTypes ( [In] uint cFileTypes, [In] COMDLG_FILTERSPEC[] rgFilterSpec );
[MethodImpl ( MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime )]
void SetFileTypeIndex ( [In] uint iFileType );
[MethodImpl ( MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime )]
void GetFileTypeIndex ( out uint piFileType );
[MethodImpl ( MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime )]
void Advise ( [In, MarshalAs ( UnmanagedType.Interface )] IFileDialogEvents pfde, out uint pdwCookie );
[MethodImpl ( MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime )]
void Unadvise ( [In] uint dwCookie );
[MethodImpl ( MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime )]
void SetOptions ( [In] FOS fos );
[MethodImpl ( MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime )]
void GetOptions ( out FOS pfos );
[MethodImpl ( MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime )]
void SetDefaultFolder ( [In, MarshalAs ( UnmanagedType.Interface )] IShellItem psi );
[MethodImpl ( MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime )]
void SetFolder ( [In, MarshalAs ( UnmanagedType.Interface )] IShellItem psi );
[MethodImpl ( MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime )]
void GetFolder ( [MarshalAs ( UnmanagedType.Interface )] out IShellItem ppsi );
[MethodImpl ( MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime )]
void GetCurrentSelection ( [MarshalAs ( UnmanagedType.Interface )] out IShellItem ppsi );
[MethodImpl ( MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime )]
void SetFileName ( [In, MarshalAs ( UnmanagedType.LPWStr )] string pszName );
[MethodImpl ( MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime )]
void GetFileName ( [MarshalAs ( UnmanagedType.LPWStr )] out string pszName );
[MethodImpl ( MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime )]
void SetTitle ( [In, MarshalAs ( UnmanagedType.LPWStr )] string pszTitle );
[MethodImpl ( MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime )]
void SetOkButtonLabel ( [In, MarshalAs ( UnmanagedType.LPWStr )] string pszText );
[MethodImpl ( MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime )]
void SetFileNameLabel ( [In, MarshalAs ( UnmanagedType.LPWStr )] string pszLabel );
[MethodImpl ( MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime )]
void GetResult ( [MarshalAs ( UnmanagedType.Interface )] out IShellItem ppsi );
[MethodImpl ( MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime )]
void AddPlace ( [In, MarshalAs ( UnmanagedType.Interface )] IShellItem psi, NativeMethods.FDAP fdap );
[MethodImpl ( MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime )]
void SetDefaultExtension ( [In, MarshalAs ( UnmanagedType.LPWStr )] string pszDefaultExtension );
[MethodImpl ( MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime )]
void Close ( [MarshalAs ( UnmanagedType.Error )] int hr );
[MethodImpl ( MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime )]
void SetClientGuid ( [In] ref Guid guid );
[MethodImpl ( MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime )]
void ClearClientData ( );
// Not supported: IShellItemFilter is not defined, converting to IntPtr
[MethodImpl ( MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime )]
void SetFilter ( [MarshalAs ( UnmanagedType.Interface )] IntPtr pFilter );
// Defined by IFileOpenDialog
// ---------------------------------------------------------------------------------
[MethodImpl ( MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime )]
void GetResults ( [MarshalAs ( UnmanagedType.Interface )] out IShellItemArray ppenum );
[MethodImpl ( MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime )]
void GetSelectedItems ( [MarshalAs ( UnmanagedType.Interface )] out IShellItemArray ppsai );
}
如果我只打算使用这个接口中的两个方法,我可以这样定义吗:
[ComImport, Guid ( "d57c7288-d4ad-4768-be02-9d969532d960" ), InterfaceType ( ComInterfaceType.InterfaceIsIUnknown )]
interface IFileOpenDialog : IFileDialog
{
// Defined on IModalWindow - repeated here due to requirements of COM interop layer
// --------------------------------------------------------------------------------
[MethodImpl ( MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime ), PreserveSig]
int Show ( [In] IntPtr parent );
[MethodImpl ( MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime )]
void SetOptions ( [In] FOS fos );
}
它会工作吗?还是我必须用所有方法定义完整的接口?
【问题讨论】:
-
是的,如果我只调用 Show 方法,它可以工作,如果我尝试调用 SetOptions,我得到一个异常:“尝试读取或写入受保护的内存。这通常表明其他内存已损坏。”