由于.net自带的OpenFileDialog,多选文件时有最大限制,通过查阅MSDN,找到了这个示例
C:\Program Files\Microsoft Visual Studio .NET 2003\SDK\v1.1\Samples\Technologies\Interop\PlatformInvoke\WinAPIs\CS\OpenFileDlg.cs但这个例子是单选的,不能多选,为了能让其多选,我做了些改动(代码附后)出现的问题:
    当指定ofn.flags = LibWrap.OFN_ALLOWMULTISELECT|LibWrap.OFN_EXPLORER;时,多选时获取不到文件名(ofn.file),只能获取到文件所在的目录名,如果只选一个文件就能获取到。
    当指定ofn.flags = LibWrap.OFN_ALLOWMULTISELECT;时,弹出的又是Old-Style对话框。请问有没有办法能够,使用Explorer-Style对话框进行多选,并且获取到全部的文件名?
 

解决方案 »

  1.   

    // Copyright
    // Microsoft Corporation
    // All rights reserved// OpenFileDlg.csusing System;
    using System.Text;
    using System.Runtime.InteropServices;/*
    typedef struct tagOFN { 
      DWORD         lStructSize; 
      HWND          hwndOwner; 
      HINSTANCE     hInstance; 
      LPCTSTR       lpstrFilter; 
      LPTSTR        lpstrCustomFilter; 
      DWORD         nMaxCustFilter; 
      DWORD         nFilterIndex; 
      LPTSTR        lpstrFile; 
      DWORD         nMaxFile; 
      LPTSTR        lpstrFileTitle; 
      DWORD         nMaxFileTitle; 
      LPCTSTR       lpstrInitialDir; 
      LPCTSTR       lpstrTitle; 
      DWORD         Flags; 
      WORD          nFileOffset; 
      WORD          nFileExtension; 
      LPCTSTR       lpstrDefExt; 
      LPARAM        lCustData; 
      LPOFNHOOKPROC lpfnHook; 
      LPCTSTR       lpTemplateName; 
    #if (_WIN32_WINNT >= 0x0500)
      void *        pvReserved;
      DWORD         dwReserved;
      DWORD         FlagsEx;
    #endif // (_WIN32_WINNT >= 0x0500)
    } OPENFILENAME, *LPOPENFILENAME; 
    */[ StructLayout( LayoutKind.Sequential, CharSet=CharSet.Auto )]  
    public class OpenFileName 
    {
    public int structSize = 0;
    public IntPtr dlgOwner = IntPtr.Zero; 
    public IntPtr instance = IntPtr.Zero;
        
    public String filter = null;
    public String customFilter = null;
    public int maxCustFilter = 0;
    public int filterIndex = 0;
        
    public String file = null;
    public int maxFile = 0;
        
    public String fileTitle = null;
    public int maxFileTitle = 0;

    public String initialDir = null;
        
    public String title = null;   
        
    public int flags = 0; 
    public short fileOffset = 0;
    public short fileExtension = 0;
        
    public String defExt = null; 
        
    public IntPtr custData = IntPtr.Zero;  
    public IntPtr hook = IntPtr.Zero;  
        
    public String templateName = null; 
        
    public IntPtr reservedPtr = IntPtr.Zero; 
    public int reservedInt = 0;
    public int flagsEx = 0;
    }public class LibWrap
    {
    //BOOL GetOpenFileName(LPOPENFILENAME lpofn);

    [ DllImport( "Comdlg32.dll", CharSet=CharSet.Auto )]
    public static extern bool GetOpenFileName([ In, Out ] OpenFileName ofn );
    //声明常量
    public const int OFN_ALLOWMULTISELECT =  0x200;
    public const int OFN_EXPLORER =  0x80000;  
    }public class App
    {
    public static void Main()
    {
    OpenFileName ofn = new OpenFileName();

    ofn.structSize = Marshal.SizeOf( ofn );

    ofn.filter = "Log files\0*.log\0Batch files\0*.bat\0"; //设置对话框风格,并表明可以进行多选
    ofn.flags = LibWrap.OFN_ALLOWMULTISELECT|LibWrap.OFN_EXPLORER;
    ofn.file = new String( new char[ 256 ]);
    ofn.maxFile = ofn.file.Length;

    ofn.fileTitle = new String( new char[ 64 ]);
    ofn.maxFileTitle = ofn.fileTitle.Length;

    ofn.initialDir = "C:\\";
    ofn.title = "Open file called using platform invoke...";
    ofn.defExt = "txt";

    if( LibWrap.GetOpenFileName( ofn ))
    {
    Console.WriteLine( "Selected file with full path: {0}", ofn.file );
    Console.WriteLine( "Selected file name: {0}", ofn.fileTitle );
    Console.WriteLine( "Offset from file name: {0}", ofn.fileOffset );
    Console.WriteLine( "Offset from file extension: {0}", ofn.fileExtension );
    }
    }
    }
      

  2.   

    the marshalling ate the other part of the string, use Marshal.AllocHGlobal() to allocate some memory, seehttp://groups-beta.google.com/group/microsoft.public.de.german.entwickler.dotnet.csharp/msg/11650bbbc9b8e689?hl=enif you cannot visit the link, let me know, the important part
    [DllImport("kernel32.dll", ExactSpelling=true)] 
    public static extern void RtlZeroMemory( IntPtr mem, int size ); 
    public class OpenFileName 
    {
    public int structSize = 0;
    public IntPtr dlgOwner = IntPtr.Zero; 
    public IntPtr instance = IntPtr.Zero;
        
    public IntPtr filter = null; ofn.flags = LibWrap.OFN_ALLOWMULTISELECT|LibWrap.OFN_EXPLORER;
    ofn.filter = "Log files\0*.log\0Batch files\0*.bat\0";

    int nlen = 256*50;
    ofn.file = Marshal.AllocHGlobal( nlen ); 
    RtlZeroMemory( ofn.file, nlen); 
    ofn.maxFile = nlen - 2; 
    ...if( LibWrap.GetOpenFileName( ofn ))
    {
     Console.WriteLine( "Selected file with full path: {0}", ofn.file ); string files = Marshal.PtrToStringAuto( ofn.file, nlen ); 
     Marshal.FreeHGlobal( ofn.file ); 
     ofn.file = IntPtr.Zero; 
      

  3.   

    sorrypublic String filter = null;
    ...
    public IntPtr file;