2012-01-31 111 views
2

我不能在我的应用程序中使用OpenFileDialog。使用GetOpenFileName而不是OpenFileDialog

正如我使用GetOpenFileName替代()方法:

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.Runtime.InteropServices; 

namespace Reader 
{ 
    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)] 
    public class OpenFileName 
    { 
     public int lstructSize; 
     public IntPtr hwndOwner; 
     public IntPtr hInstance; 
     public string lpstrFilter = null; 
     public string lpstrCustomFilter = null; 
     public int lMaxCustomFilter; 
     public int lFilterIndex; 
     public string lpstrFile = null; 
     public int lMaxFile = 0; 
     public string lpstrFileTitle = null; 
     public int lMaxFileTitle = 0; 
     public string lpstrInitialDir = null; 
     public string lpstrTitle = null; 
     public int lFlags; 
     public ushort nFileOffset; 
     public ushort nFileExtension; 
     public string lpstrDefExt = null; 
     public int lCustData; 
     public int lpfHook; 
     public int lpTemplateName; 
    } 

    public class OpenDialog 
    { 
     [DllImport("Comdlg32.dll",CharSet = CharSet.Auto)] 
     public static extern bool GetOpenFileName([In, Out] OpenFileName ofn); 
    } 
} 

然后在这样的按钮的OnClick事件使用它:

OpenFileName qofn = new OpenFileName(); 

qofn.lstructSize = Marshal.SizeOf(qofn); 
qofn.lpstrFile = ""; 
qofn.lMaxFile = 256; 
qofn.lpstrFileTitle = ""; 
qofn.lMaxFileTitle = 64; 
qofn.hInstance = this.Handle; 
source.Text = "Wait..."; 
if (OpenDialog.GetOpenFileName(qofn)) 
{ 
    MessageBox.Show("ofn.file: " + qofn. lpstrFile); 
} 

当应用程序运行时和按钮被点击,我尝试打开文件这是发生了什么事情:

第1次尝试:

它的路径返回到我的文件,但不是 C:\迪拉\ DIRB \ DIRC \ FILENAME.EXT 我有 C:\迪拉\ DIRB \ dircfilename.ext 没有 '\' 的名字前文件

第二个尝试

一切都OK

下一个: 有随机崩溃,如随机访问冲突或GUI冻结,应用程序的进程无法在任务管理器或其他错误中抛出。

在应用程序崩溃之前,通常对话框会工作2-3次。

我的代码有什么问题?

编辑:

我不能用打开文件对话框。我正在使用WinPE 4.0(Windows评估和部署套件ADK)。当我尝试OpenFileDIalog时,它会抛出运行时错误80040111。这可能是因为核心不受支持(就像Server Core不支持OpenFileDialog一样,错误也是一样)。可能在WinPE 4.0上,它们在诸如记事本等应用程序中使用GetOpenFileName。它适用于他们。

+3

你有什么情况'OpenFileDialog'不起作用? – 2012-01-31 23:52:10

+0

为什么你不能使用'OpenFileDialog'? 'OpenFileDialog'可能在幕后使用'GetOpenFileName',所以它不会真的改变任何东西...... – 2012-02-01 00:17:55

+2

顺便说一句,'这。处理'不是一个HINSTANCE,这是一个HWND – 2012-02-01 00:19:05

回答

3

OK,我发现这个微软的样品,它的工作原理:

// Copyright 
// Microsoft Corporation 
// All rights reserved 

// OpenFileDlg.cs 

using 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 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.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); 
     } 
    } 
} 
+0

您是否有完整样本的URL?我能找到的最接近的是[本MSDN文章](http://technet.microsoft.com/en-us/query/w5tyztk9)。 – 2012-03-23 06:26:18

2

的OpenFileDlg例子(如在阿里的回答中所使用的)可用Here

该页面有C#,C++和VB示例。我已经在WinPE 5.1中测试了VB示例,并且除了文件类型过滤器外,它工作得很好;它始终显示所有文件类型。

我很惊讶地发现即使WinPE-NetFX软件包安装在我的WinPE映像中,OpenFileDialog在WinPE中也不可用,并且试图使用它会抛出问题中引用的错误。这些使用非托管GetOpenFileName函数的OpenFileDlg示例是我能够在WinPE中使用的唯一选择。