2 // System.Windows.Forms.FileDialog.cs
5 // stubbed out by Daniel Carrera (dcarrera@math.toronto.edu)
6 // Dennis Hayes (dennish@raytek.com)
7 // Aleksey Ryabchuk (ryabchuk@yahoo.com)
8 // (C) 2002 Ximian, Inc
12 // Permission is hereby granted, free of charge, to any person obtaining
13 // a copy of this software and associated documentation files (the
14 // "Software"), to deal in the Software without restriction, including
15 // without limitation the rights to use, copy, modify, merge, publish,
16 // distribute, sublicense, and/or sell copies of the Software, and to
17 // permit persons to whom the Software is furnished to do so, subject to
18 // the following conditions:
20 // The above copyright notice and this permission notice shall be
21 // included in all copies or substantial portions of the Software.
23 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
24 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
25 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
26 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
27 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
28 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
29 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
31 using System
.ComponentModel
;
32 using System
.Runtime
.InteropServices
;
34 namespace System
.Windows
.Forms
{
37 // Displays a dialog window from which the user can select a file.
40 public abstract class FileDialog
: CommonDialog
{
41 internal const int MAX_PATH
= 1024*8;
50 bool dereferenceLinks
;
53 string initialDirectory
;
54 bool restoreDirectory
;
56 internal bool isSave
= false;
58 protected static readonly object EventFileOk
;
59 internal FileDialog ( )
64 public bool AddExtension
{
65 get { return addExtencsion; }
66 set { addExtencsion = value; }
69 public virtual bool CheckFileExists
{
70 get { return checkFileExists; }
71 set { checkFileExists = value; }
74 public bool CheckPathExists
{
75 get { return checkPathExists; }
76 set { checkPathExists = value; }
79 public string DefaultExt
{
80 get { return defaultExt; }
82 if ( value.StartsWith ( "." ) )
83 defaultExt
= value.Remove( 0, 1 );
89 public bool DereferenceLinks
{
90 get { return dereferenceLinks; }
91 set { dereferenceLinks = value; }
94 public string FileName
{
95 get { return fileName; }
96 set { fileName = value; }
100 public string[] FileNames
{
102 throw new NotImplementedException ();
106 public string Filter
{
107 get { return filter; }
109 if ( value.Length
> 0 ) {
110 int sepNum
= getSeparatorsCount ( value );
111 if ( ( sepNum
/ 2 ) * 2 == sepNum
) {
112 // number of separators should be odd
113 throw new ArgumentException ("Parameter format is invalid");
120 public int FilterIndex
{
121 get { return filterIndex; }
122 set { filterIndex = value; }
125 public string InitialDirectory
{
126 get { return initialDirectory; }
127 set { initialDirectory = value; }
130 public bool RestoreDirectory
{
131 get { return restoreDirectory; }
132 set { restoreDirectory = value; }
135 public bool ShowHelp
{
136 get { return showHelp; }
137 set { showHelp = value; }
140 public string Title
{
141 get { return title; }
142 set { title = value;}
145 public bool ValidateNames
{
146 get { return validateNames; }
147 set { validateNames = value; }
150 public override void Reset()
156 public override string ToString()
159 return base.ToString();
162 public event CancelEventHandler FileOk
;
165 protected override IntPtr
HookProc( IntPtr hWnd
, int msg
, IntPtr wparam
, IntPtr lparam
)
168 case ( int ) Msg
.WM_NOTIFY
:
169 OFNOTIFY ofnhdr
= ( OFNOTIFY
)Marshal
.PtrToStructure ( lparam
, typeof ( OFNOTIFY
) );
171 switch ( ofnhdr
.code
) {
172 case ( int ) CommDlgNotifications
.CDN_FILEOK
:
173 OPENFILENAME ofn
= ( OPENFILENAME
) Marshal
.PtrToStructure ( ofnhdr
.lpOFN
, typeof ( OPENFILENAME
) );
174 string oldFileName
= FileName
;
175 FileName
= Win32
.WineToUnixPath(ofn
.lpstrFile
);
176 CancelEventArgs e
= new CancelEventArgs ( false );
179 Win32
.SetWindowLong( hWnd
, GetWindowLongFlag
.DWL_MSGRESULT
, 1 );
180 return ( IntPtr
) 1 ;
183 case ( int ) CommDlgNotifications
.CDN_HELP
:
184 OnHelpRequest ( EventArgs
.Empty
);
189 return base.HookProc(hWnd
, msg
, wparam
, lparam
);
192 protected void OnFileOk( CancelEventArgs e
)
194 if ( FileOk
!= null )
199 protected override bool RunDialog( IntPtr hWndOwner
)
201 OPENFILENAME opf
= new OPENFILENAME();
202 opf
.hwndOwner
= hWndOwner
;
204 initOpenFileName ( ref opf
);
210 res
= Win32
.GetSaveFileName ( ref opf
);
212 res
= Win32
.GetOpenFileName ( ref opf
);
216 error
= Win32
.CommDlgExtendedError();
218 if (error
==(uint)CommonDlgErrorCode
.CDERR_STRUCTSIZE
) // This system does not support the place bar
220 initOpenFileName ( ref opf
);
221 opf
.lStructSize
= (uint)Marshal
.SizeOf(new OPENFILENAME_PREWIN50());
222 // Try with the struct for older Systems
224 res
= Win32
.GetSaveFileName ( ref opf
);
226 res
= Win32
.GetOpenFileName ( ref opf
);
231 FileName
= Win32
.WineToUnixPath(opf
.lpstrFile
);
234 string errorMes
= string.Empty
;
236 case (uint)CommDlgErrors
.FNERR_BUFFERTOOSMALL
:
237 errorMes
= "Too many files selected. Please select fewer files and try again.";
239 case (uint)CommDlgErrors
.FNERR_INVALIDFILENAME
:
240 errorMes
= "A file name is invalid.";
243 throw new InvalidOperationException( errorMes
);
249 //protected virtual IntPtr Instance{}
250 //protected virtual int Options{}
252 internal virtual void initOpenFileName ( ref OPENFILENAME opf
)
254 opf
.lStructSize
= (uint)Marshal
.SizeOf( opf
);
255 char[] FileNameBuffer
= new char[MAX_PATH
];
256 opf
.lpstrFile
= new string( FileNameBuffer
);
257 opf
.nMaxFile
= (uint) opf
.lpstrFile
.Length
;
258 opf
.lpfnHook
= new Win32
.FnHookProc ( this.HookProc
);
259 opf
.Flags
= (int) ( OpenFileDlgFlags
.OFN_ENABLEHOOK
| OpenFileDlgFlags
.OFN_EXPLORER
| OpenFileDlgFlags
.OFN_ENABLESIZING
);
261 // convert filter to the proper format accepted by GetOpenFileName
262 int FilterLength
= Filter
.Length
;
263 if ( FilterLength
> 0 ) {
264 char[] FilterString
= new char[ FilterLength
+ 1 ];
265 Filter
.CopyTo ( 0, FilterString
, 0, FilterLength
);
266 int index
= Array
.IndexOf ( FilterString
, '|' );
267 while ( index
!= -1 ) {
268 FilterString
[ index
] = '\0';
269 index
= Array
.IndexOf ( FilterString
, '|', index
);
271 FilterString
[ FilterLength
] = '\0';
272 opf
.lpstrFilter
= new string ( FilterString
);
275 if ( FilterIndex
>= 0 )
276 opf
.nFilterIndex
= (uint)FilterIndex
;
278 opf
.lpstrDefExt
= DefaultExt
;
279 opf
.lpstrTitle
= Title
;
280 opf
.lpstrInitialDir
= InitialDirectory
;
282 if ( CheckFileExists
)
283 opf
.Flags
|= (int) ( OpenFileDlgFlags
.OFN_FILEMUSTEXIST
);
284 if ( CheckPathExists
)
285 opf
.Flags
|= (int) ( OpenFileDlgFlags
.OFN_PATHMUSTEXIST
);
286 if ( !DereferenceLinks
)
287 opf
.Flags
|= (int) ( OpenFileDlgFlags
.OFN_NODEREFERENCELINKS
);
289 opf
.Flags
|= (int) ( OpenFileDlgFlags
.OFN_SHOWHELP
);
290 if ( RestoreDirectory
)
291 opf
.Flags
|= (int) ( OpenFileDlgFlags
.OFN_NOCHANGEDIR
);
292 if ( !ValidateNames
)
293 opf
.Flags
|= (int) ( OpenFileDlgFlags
.OFN_NOVALIDATE
);
296 private int getSeparatorsCount ( string filter
)
299 foreach ( char c
in filter
)
300 if ( c
== '|' ) sepNum
++;
304 private void setDefaults ( )
306 fileName
= string.Empty
;
307 checkFileExists
= false;
308 addExtencsion
= true;
309 defaultExt
= string.Empty
;
310 filter
= string.Empty
;
312 checkPathExists
= true;
313 dereferenceLinks
= true;
315 title
= string.Empty
;
316 initialDirectory
= string.Empty
;
317 restoreDirectory
= false;
318 validateNames
= true;