1 /******************************************************************************
2 *
3 * Copyright (C) 2004-2007, The Gentee Group. All rights reserved.
4 * This file is part of the Gentee open source project - http://www.gentee.com.
5 *
6 * THIS FILE IS PROVIDED UNDER THE TERMS OF THE GENTEE LICENSE ("AGREEMENT").
7 * ANY USE, REPRODUCTION OR DISTRIBUTION OF THIS FILE CONSTITUTES RECIPIENTS
8 * ACCEPTANCE OF THE AGREEMENT.
9 *
10 * ID: vis.dialogs 19.09.07 0.0.A.
11 *
12 * Author: Alexander Krivonogov ( gentee )
13 *
14 ******************************************************************************/
15
16
17 /* Компонента vOpenDialog, порождена от vComp
18 */
19
20 type vOpenSaveDialog <inherit = vComp> {
21 //Hidden Fields
22 ustr pDefExt
23 ustr pInitialDir
24 ustr pFileName
25 locustr pTitleOpen
26 locustr pTitleSave
27 uint pOptions
28 uint pFilterIndex
29 locustr pFiltersText
30
31 //Public Fields
32 arrustr Filters
33 arrustr Files
34 }
35
36 define
37 {
38 osfMultiSelect = 0x01
39 // osfENABLESIZING
40 }
41
42 define
43 {
44 OSD_BUFSIZE = 4096 //Размер буфера для получения имен файлов
45 }
46
47 /*------------------------------------------------------------------------------
48 Hidden Methods
49 */
50 method vOpenSaveDialog.iUpdateFilters()
51 {
52 /*uint filtertext = .pFiltersText.Text( this )
53 if */
54 .Filters.load( .pFiltersText.Text( this ), 0 )
55 }
56
57 /*Вывод диалогового окна для открытия сохранения и открытия файла*/
58 method uint vOpenSaveDialog.Show( uint flgsave )
59 {
60 OPENFILENAME pOFN
61 ustr files
62 buf bfilters
63 files.reserve( $OSD_BUFSIZE )
64 if flgsave
65 {
66 files = .pFileName
67 }
68 files.use = $OSD_BUFSIZE
69 with pOFN
70 {
71 .lStructSize = sizeof( OPENFILENAME )
72 .lpstrDefExt = this.pDefExt.ptr()
73 .lpstrInitialDir = this.pInitialDir.ptr()
74 //print( "initdir = \(this.pInitialDir.str())\n" )
75 .lpstrFile = files.ptr()
76
77 ustr title
78 if flgsave : title = .pTitleSave.Text( this )
79 else : title = .pTitleOpen.Text( this )
80 if *title : .lpstrTitle = title.ptr()
81
82 .nMaxFile = $OSD_BUFSIZE
83 if .Owner
84 {
85 .hwndOwner = .Owner->vCtrl.hwnd
86 }
87 .Flags = $OFN_EXPLORER | $OFN_PATHMUSTEXIST | $OFN_HIDEREADONLY | ?( flgsave, $OFN_OVERWRITEPROMPT, $OFN_FILEMUSTEXIST ) | ?( this.pOptions & $osfMultiSelect, $OFN_ALLOWMULTISELECT, 0 )
88 if *.Filters
89 {
90 arrustr arpair
91 foreach pair, .Filters
92 {
93 pair.split( arpair, '\', 0 )
94 if *arpair == 1
95 {
96 bfilters@arpair[0]
97 bfilters@'\h2 0'
98 }
99 elif *arpair > 1
100 {
101 bfilters@arpair[0]@arpair[1]
102 }
103 }
104 bfilters@'\h2 0'
105 .lpstrFilter = bfilters.ptr()
106 }
107 }
108 uint res = ?( flgsave, GetSaveFileName( pOFN ), GetOpenFileName( pOFN ) )
109 if res
110 {
111 .Files.clear()
112 if !flgsave &this.pOptions & $osfMultiSelect
113 {
114 files.getmultiustr( .Files )
115 if *.Files > 1
116 {
117 ustr dir = .Files[0] + "\\".ustr()
118 .Files.del( 0 )
119 foreach x, .Files
120 {
121 x = dir + x
122 }
123 }
124 }
125 else
126 {
127 files.setlenptr()
128 .Files.expand(1)
129 .Files[0] = files
130 }
131 /*foreach x, .Files
132 {
133 print( "res = \( .pOFN.nMaxFile) ["+x.str()+"]\n" )
134 }*/
135 .pInitialDir = files.str().fgetdir("").ustr()
136 .pFileName = .Files[0]
137 }
138 return res
139 }
140
141 /*------------------------------------------------------------------------------
142 Public Methods
143 */
144 /*Вывод диалогового окна для открытия файла*/
145 method uint vOpenSaveDialog.ShowOpenFile()
146 {
147 return this.Show( 0 )
148 }
149
150 /*Вывод диалогового окна для сохранения файла*/
151 method uint vOpenSaveDialog.ShowSaveFile()
152 {
153 return this.Show( 1 )
154 }
155
156 /*------------------------------------------------------------------------------
157 Properties
158 */
159
160 /* Свойство uint DefExt - Get Set
161 Усотанавливает или определяет расширение по умолчанию
162 */
163 property ustr vOpenSaveDialog.DefExt<result>()
164 {
165 result = .pDefExt
166 }
167
168 property vOpenSaveDialog.DefExt( ustr val )
169 {
170 if .pDefExt != val
171 {
172 .pDefExt = val
173 }
174 }
175
176 /* Свойство uint InitialDir - Get Set
177 Усотанавливает или определяет начальную директорию
178 */
179 property ustr vOpenSaveDialog.InitialDir<result>()
180 {
181 result = .pInitialDir
182 }
183
184 property vOpenSaveDialog.InitialDir( ustr val )
185 {
186 if .pInitialDir != val
187 {
188 .pInitialDir = val
189 }
190 }
191
192
193 /* Свойство uint InitialDir - Get Set
194 Усотанавливает или определяет имя выбранного файла
195 */
196 property ustr vOpenSaveDialog.FileName<result>()
197 {
198 result = .pFileName
199 }
200
201 property vOpenSaveDialog.FileName( ustr val )
202 {
203 if .pFileName != val
204 {
205 .pFileName = val
206 }
207 }
208
209 /* Свойство uint Options - Get Set
210 Усотанавливает или определяет настройки
211 */
212 property uint vOpenSaveDialog.Options()
213 {
214 return .pOptions
215 }
216
217 property vOpenSaveDialog.Options( uint val )
218 {
219 if .pOptions != val
220 {
221 .pOptions = val
222 }
223 }
224
225 /* Свойство uint FilterIndex - Get Set
226 Усотанавливает или определяет текущий индекс фильтра
227 */
228 property uint vOpenSaveDialog.FilterIndex()
229 {
230 return .pFilterIndex
231 }
232
233 property vOpenSaveDialog.FilterIndex( uint val )
234 {
235 if .pFilterIndex != val
236 {
237 .pFilterIndex = min( val, *.Filters - 1 )
238 }
239 }
240
241 /* Свойство uint TitleOpen - Get Set
242 Усотанавливает или определяет заголовок окна открытия файла
243 */
244 property ustr vOpenSaveDialog.TitleOpen <result>
245 {
246 result = this.pTitleOpen.Value
247 }
248
249 property vOpenSaveDialog.TitleOpen( ustr val )
250 {
251 this.pTitleOpen.Value = val
252 }
253
254 /* Свойство uint TitleSave - Get Set
255 Усотанавливает или определяет заголовок окна сохранения файла
256 */
257 property ustr vOpenSaveDialog.TitleSave <result>
258 {
259 result = this.pTitleSave.Value
260 }
261
262 property vOpenSaveDialog.TitleSave( ustr val )
263 {
264 this.pTitleSave.Value = val
265 }
266
267 /* Свойство uint FiltersText - Get Set
268 Усотанавливает или определяет заголовок окна сохранения файла
269 */
270 property ustr vOpenSaveDialog.FiltersText <result>
271 {
272 result = this.pFiltersText.Value
273 }
274
275 property vOpenSaveDialog.FiltersText( ustr val )
276 {
277 if this.pFiltersText.Value != val
278 {
279 this.pFiltersText.Value = val
280 .iUpdateFilters()
281 }
282 }
283
284
285 /*Виртуальный метод uint vOpenSaveDialog.mLangChanged - Изменение текущего языка
286 */
287 method vOpenSaveDialog.mLangChanged <alias=vOpenSaveDialog_mLangChanged>()
288 {
289 if *this.pFiltersText.Value : .iUpdateFilters()
290 this->vComp.mLangChanged()
291 }
292
293
294 /* Компонента vOpenDialog, порождена от vComp
295 */
296
297 type vSelectDir <inherit = vComp> {
298 //Hidden Fields
299 /* ustr pDefExt
300 ustr pInitialDir
301 ustr pFileName*/
302 ustr pDir
303 locustr pTitle
304 uint pCanCreate
305 uint pShowEdit
306 /*locustr pTitleSave
307 uint pOptions
308 uint pFilterIndex
309
310 //Public Fields
311 arrustr Filters
312 arrustr Files*/
313 }
314
315
316 //--------------------------------------------------------------------------
317
318
319
320 type BROWSEINFO {
321 uint hwndOwner
322 uint pidlRoot
323 uint pszDisplayName
324 uint lpszTitle
325 uint ulFlags
326 uint lpfn
327 uint lParam
328 int iImage
329 }
330
331 import "ole32.dll" {
332 uint CoTaskMemAlloc( uint )
333 CoTaskMemFree( uint )
334 uint CoInitializeEx( uint, uint )
335 uint CoInitialize(uint)
336 }
337
338 import "shell32.dll" {
339 uint SHGetSpecialFolderLocationW( uint, int, uint ) -> SHGetSpecialFolderLocationW
340 uint SHGetPathFromIDListW( uint, uint ) -> SHGetPathFromIDList
341 uint SHBrowseForFolderW( BROWSEINFO ) -> SHBrowseForFolder
342 }
343
344 define {
345 BIF_RETURNONLYFSDIRS = 0x0001
346 BIF_EDITBOX = 0x0010
347 BIF_NEWDIALOGSTYLE = 0x0040
348 BIF_NONEWFOLDERBUTTON = 0x0200
349
350 BFFM_INITIALIZED = 1
351
352 BFFM_SETSELECTION = $WM_USER + 103 //BFFM_SETSELECTIONW
353 }
354
355 global {
356 uint AddrBrowseCallbackProc
357 }
358
359 /*------------------------------------------------------------------------------
360 Properties
361 */
362
363 /* Свойство ustr Title - Get Set
364 Усотанавливает или определяет заголовок над списком директорий
365 */
366 property ustr vSelectDir.Title<result>()
367 {
368 result = .pTitle
369 }
370
371 property vSelectDir.Title( ustr val )
372 {
373 if .pTitle != val
374 {
375 .pTitle = val
376 }
377 }
378
379 /* Свойство ustr Dir - Get Set
380 Усотанавливает или определяет текущую выбранную директорию
381 */
382 property ustr vSelectDir.Dir<result>()
383 {
384 result = .pDir
385 }
386
387 property vSelectDir.Dir( ustr val )
388 {
389 if .pDir != val
390 {
391 .pDir = val
392 }
393 }
394
395 /* Свойство ustr C - Get Set
396 Усотанавливает или определяет возможность создания директорий
397 */
398 property uint vSelectDir.CanCreate()
399 {
400 return .pCanCreate
401 }
402
403 property vSelectDir.CanCreate( uint val )
404 {
405 if .pCanCreate != val
406 {
407 .pCanCreate = val
408 }
409 }
410
411 /* Свойство ustr C - Get Set
412 Усотанавливает или определяет показ Edit с текущей директорией
413 */
414 property uint vSelectDir.ShowEdit()
415 {
416 return .pShowEdit
417 }
418
419 property vSelectDir.ShowEdit( uint val )
420 {
421 if .pShowEdit != val
422 {
423 .pShowEdit = val
424 }
425 }
426
427
428 func int BrowseCallbackProc( uint hwnd, uMsg, lParam, lpData )
429 {
430 if uMsg == $BFFM_INITIALIZED && lpData
431 {
432 SendMessage( hwnd, $BFFM_SETSELECTION, 1, lpData->ustr.ptr() )
433 }
434 return 0
435 }
436
437 method uint vSelectDir.Show( )
438 {
439 // int nidl
440 uint result
441 BROWSEINFO bi
442 uint lpidl
443 uint pidlRoot = 0
444
445 /*if( nidl )
446 {
447 SHGetSpecialFolderLocation( owner, nidl, &pidlRoot);
448 }*/
449
450 if ( *.pDir )
451 {
452 bi.lpfn = AddrBrowseCallbackProc
453 bi.lParam = &.pDir
454 }
455 if .Owner
456 {
457 bi.hwndOwner = .Owner->vCtrl.hwnd
458 }
459 bi.pidlRoot = pidlRoot
460 bi.pszDisplayName = 0//"dir".ptr();
461 bi.lpszTitle = this.pTitle.Text( this ).ptr()
462 bi.ulFlags = $BIF_RETURNONLYFSDIRS | $BIF_NEWDIALOGSTYLE
463 if .pShowEdit : bi.ulFlags |= $BIF_EDITBOX
464 if !.pCanCreate : bi.ulFlags |= $BIF_NONEWFOLDERBUTTON
465 //CoInitialize(0)
466 lpidl = SHBrowseForFolder( bi )
467 if ( lpidl )
468 {
469 .pDir.reserve( 260 )
470 SHGetPathFromIDList( lpidl, .pDir.ptr() )
471 .pDir.setlenptr()
472 CoTaskMemFree( lpidl )
473 result = 1
474 }
475 else
476 {
477 .pDir.clear()
478 }
479 /*
480 if(pidlRoot)
481 {
482 CoTaskMemFree( pidlRoot )
483 }
484 */
485 return result
486 }
487
488
489 /*------------------------------------------------------------------------------
490 Registration
491 */
492 method vOpenSaveDialog vOpenSaveDialog.init( )
493 {
494 this.pTypeId = vOpenSaveDialog
495 return this
496 }
497
498 method vSelectDir vSelectDir.init( )
499 {
500 this.pTypeId = vSelectDir
501 this.pCanCreate = 1
502 return this
503 }
504
505 func init_vOpenSaveDialog <entry>()
506 {
507 regcomp( vOpenSaveDialog, "vOpenSaveDialog", vComp, $vComp_last,
508 %{ %{$mLangChanged, vOpenSaveDialog_mLangChanged } },
509 0->collection )
510
511 regcomp( vSelectDir, "vSelectDir", vComp, $vComp_last,
512 0->collection,
513 0->collection )
514
515 //CoInitializeEx(0,0)
516 AddrBrowseCallbackProc = callback( &BrowseCallbackProc, 4 )
517
518 ifdef $DESIGNING {
519
520 cm.AddComp( vOpenSaveDialog, 1, "Windows", "dialogs" )
521
522 cm.AddProps( vOpenSaveDialog, %{
523 "DefExt", ustr, 0,
524 "FileName", ustr, 0,
525 "InitialDir", ustr, 0,
526 "FilterIndex", uint, 0,
527 "FiltersText", ustr, 0,
528 "TitleOpen" , ustr, 0,
529 "TitleSave" , ustr, 0
530 })
531
532 cm.AddComp( vSelectDir, 1, "Windows", "dialogs" )
533
534 cm.AddProps( vSelectDir, %{
535 "Title", ustr, 0,
536 "Dir", ustr, 0,
537 "CanCreate", uint, 0,
538 "ShowEdit", uint, 0
539 })
540 }
541
542
543
544 }
545