2012-01-31 58 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中使用的唯一選擇。