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 pFilterIndex
28 locustr pFiltersText
29 uint pMultiSelect
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 .lpstrFile = files.ptr()
75
76 ustr title
77 if flgsave : title = .pTitleSave.Text( this )
78 else : title = .pTitleOpen.Text( this )
79 if *title : .lpstrTitle = title.ptr()
80
81 .nMaxFile = $OSD_BUFSIZE
82 if &.Owner
83 {
84 .hwndOwner = .Owner->vCtrl.GetMainForm()->vCtrl.hwnd
85 }
86 if !.hwndOwner : .hwndOwner = GetActiveWindow()
87 .Flags = $OFN_EXPLORER | $OFN_HIDEREADONLY | ?( flgsave, $OFN_OVERWRITEPROMPT, $OFN_FILEMUSTEXIST | $OFN_PATHMUSTEXIST ) | ?( this.pMultiSelect, $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 .nFilterIndex = .pFilterIndex
107 }
108 }
109 uint res = ?( flgsave, GetSaveFileName( pOFN ), GetOpenFileName( pOFN ) )
110 if res
111 {
112 .Files.clear()
113 if !flgsave & this.pMultiSelect
114 {
115 uint start = 0
116 while ( files.ptr() + ( start << 1) )->ushort
117 {
118 start = files.findsh( start, 0 ) + 1
119 }
120 files.use = start << 1
121 files.getmultiustr( .Files )
122 if *.Files > 1
123 {
124 ustr dir = .Files[0]
125
126 if dir[*dir-1] != '\'
127 {
128 dir = dir + "\\".ustr()
129 }
130 .Files.del( 0 )
131 foreach x, .Files
132 {
133 x = dir + x
134 }
135 }
136 }
137 else
138 {
139 files.setlenptr()
140 .Files.expand(1)
141 .Files[0] = files
142 }
143
144 .pInitialDir = files.str().fgetdir("").ustr()
145 .pFileName = .Files[0]
146 }
147 return res
148 }
149
150 /*------------------------------------------------------------------------------
151 Public Methods
152 */
153 /*Вывод диалогового окна для открытия файла*/
154 method uint vOpenSaveDialog.ShowOpenFile()
155 {
156 return this.Show( 0 )
157 }
158
159 /*Вывод диалогового окна для сохранения файла*/
160 method uint vOpenSaveDialog.ShowSaveFile()
161 {
162 return this.Show( 1 )
163 }
164
165 /*------------------------------------------------------------------------------
166 Properties
167 */
168
169 /* Свойство uint DefExt - Get Set
170 Усотанавливает или определяет расширение по умолчанию
171 */
172 property ustr vOpenSaveDialog.DefExt<result>()
173 {
174 result = .pDefExt
175 }
176
177 property vOpenSaveDialog.DefExt( ustr val )
178 {
179 if .pDefExt != val
180 {
181 .pDefExt = val
182 }
183 }
184
185 /* Свойство uint InitialDir - Get Set
186 Усотанавливает или определяет начальную директорию
187 */
188 property ustr vOpenSaveDialog.InitialDir<result>()
189 {
190 result = .pInitialDir
191 }
192
193 property vOpenSaveDialog.InitialDir( ustr val )
194 {
195 if .pInitialDir != val
196 {
197 .pInitialDir = val
198 }
199 }
200
201
202 /* Свойство uint InitialDir - Get Set
203 Усотанавливает или определяет имя выбранного файла
204 */
205 property ustr vOpenSaveDialog.FileName<result>()
206 {
207 result = .pFileName
208 }
209
210 property vOpenSaveDialog.FileName( ustr val )
211 {
212 if .pFileName != val
213 {
214 .pFileName = val
215 }
216 }
217
218 /* Свойство uint Options - Get Set
219 Усотанавливает или определяет настройки
220 */
221 property uint vOpenSaveDialog.MultiSelect()
222 {
223 return .pMultiSelect
224 }
225
226 property vOpenSaveDialog.MultiSelect( uint val )
227 {
228 if .pMultiSelect != val
229 {
230 .pMultiSelect = val
231 }
232 }
233
234 /* Свойство uint FilterIndex - Get Set
235 Усотанавливает или определяет текущий индекс фильтра
236 */
237 property uint vOpenSaveDialog.FilterIndex()
238 {
239 return .pFilterIndex
240 }
241
242 property vOpenSaveDialog.FilterIndex( uint val )
243 {
244 if .pFilterIndex != val
245 {
246 .pFilterIndex = min( val, *.Filters )
247 }
248 }
249
250 /* Свойство uint TitleOpen - Get Set
251 Усотанавливает или определяет заголовок окна открытия файла
252 */
253 property ustr vOpenSaveDialog.TitleOpen <result>
254 {
255 result = this.pTitleOpen.Value
256 }
257
258 property vOpenSaveDialog.TitleOpen( ustr val )
259 {
260 this.pTitleOpen.Value = val
261 }
262
263 /* Свойство uint TitleSave - Get Set
264 Усотанавливает или определяет заголовок окна сохранения файла
265 */
266 property ustr vOpenSaveDialog.TitleSave <result>
267 {
268 result = this.pTitleSave.Value
269 }
270
271 property vOpenSaveDialog.TitleSave( ustr val )
272 {
273 this.pTitleSave.Value = val
274 }
275
276 /* Свойство uint FiltersText - Get Set
277 Усотанавливает или определяет заголовок окна сохранения файла
278 */
279 property ustr vOpenSaveDialog.FiltersText <result>
280 {
281 result = this.pFiltersText.Value
282 }
283
284 property vOpenSaveDialog.FiltersText( ustr val )
285 {
286 if this.pFiltersText.Value != val
287 {
288 this.pFiltersText.Value = val
289 .iUpdateFilters()
290 }
291 }
292
293
294 /*Виртуальный метод uint vOpenSaveDialog.mLangChanged - Изменение текущего языка
295 */
296 method vOpenSaveDialog.mLangChanged <alias=vOpenSaveDialog_mLangChanged>()
297 {
298 if *this.pFiltersText.Value : .iUpdateFilters()
299 this->vComp.mLangChanged()
300 }
301
302
303 /* Компонента vOpenDialog, порождена от vComp
304 */
305
306 type vSelectDir <inherit = vComp> {
307 //Hidden Fields
308 /* ustr pDefExt
309 ustr pInitialDir
310 ustr pFileName*/
311 ustr pDir
312 locustr pTitle
313 uint pCanCreate
314 uint pShowEdit
315 }
316
317
318 //--------------------------------------------------------------------------
319
320
321
322 type BROWSEINFO {
323 uint hwndOwner
324 uint pidlRoot
325 uint pszDisplayName
326 uint lpszTitle
327 uint ulFlags
328 uint lpfn
329 uint lParam
330 int iImage
331 }
332
333 import "ole32.dll" {
334 uint CoTaskMemAlloc( uint )
335 CoTaskMemFree( uint )
336 uint CoInitializeEx( uint, uint )
337 uint CoInitialize(uint)
338 }
339
340 import "shell32.dll" {
341 uint SHGetSpecialFolderLocationW( uint, int, uint ) -> SHGetSpecialFolderLocationW
342 uint SHGetPathFromIDListW( uint, uint ) -> SHGetPathFromIDList
343 uint SHBrowseForFolderW( BROWSEINFO ) -> SHBrowseForFolder
344 }
345
346 define {
347 BIF_RETURNONLYFSDIRS = 0x0001
348 BIF_EDITBOX = 0x0010
349 BIF_NEWDIALOGSTYLE = 0x0040
350 BIF_NONEWFOLDERBUTTON = 0x0200
351
352 BFFM_INITIALIZED = 1
353
354 BFFM_SETSELECTION = $WM_USER + 103 //BFFM_SETSELECTIONW
355 }
356
357 global {
358 uint AddrBrowseCallbackProc
359 }
360
361 /*------------------------------------------------------------------------------
362 Properties
363 */
364
365 /* Свойство ustr Title - Get Set
366 Усотанавливает или определяет заголовок над списком директорий
367 */
368 property ustr vSelectDir.Title<result>()
369 {
370 result = .pTitle
371 }
372
373 property vSelectDir.Title( ustr val )
374 {
375 if .pTitle != val
376 {
377 .pTitle = val
378 }
379 }
380
381 /* Свойство ustr Dir - Get Set
382 Усотанавливает или определяет текущую выбранную директорию
383 */
384 property ustr vSelectDir.Dir<result>()
385 {
386 result = .pDir
387 }
388
389 property vSelectDir.Dir( ustr val )
390 {
391 if .pDir != val
392 {
393 .pDir = val
394 }
395 }
396
397 /* Свойство ustr C - Get Set
398 Усотанавливает или определяет возможность создания директорий
399 */
400 property uint vSelectDir.CanCreate()
401 {
402 return .pCanCreate
403 }
404
405 property vSelectDir.CanCreate( uint val )
406 {
407 if .pCanCreate != val
408 {
409 .pCanCreate = val
410 }
411 }
412
413 /* Свойство ustr C - Get Set
414 Усотанавливает или определяет показ Edit с текущей директорией
415 */
416 property uint vSelectDir.ShowEdit()
417 {
418 return .pShowEdit
419 }
420
421 property vSelectDir.ShowEdit( uint val )
422 {
423 if .pShowEdit != val
424 {
425 .pShowEdit = val
426 }
427 }
428
429
430 func int BrowseCallbackProc( uint hwnd uMsg lParam lpData )
431 {
432 if uMsg == $BFFM_INITIALIZED && lpData
433 {
434 SendMessage( hwnd, $BFFM_SETSELECTION, 1, lpData->ustr.ptr() )
435 }
436 return 0
437 }
438
439 method uint vSelectDir.Show( )
440 {
441 // int nidl
442 uint result
443 BROWSEINFO bi
444 uint lpidl
445 uint pidlRoot = 0
446
447 /*if( nidl )
448 {
449 SHGetSpecialFolderLocation( owner, nidl, &pidlRoot)
450 }*/
451
452 if ( *.pDir )
453 {
454 bi.lpfn = AddrBrowseCallbackProc
455 bi.lParam = &.pDir
456 }
457 if &.Owner
458 {
459 bi.hwndOwner = .Owner->vCtrl.GetMainForm()->vForm.hwnd
460 }
461 if !bi.hwndOwner : bi.hwndOwner = GetActiveWindow()
462 bi.pidlRoot = pidlRoot
463 bi.pszDisplayName = 0//"dir".ptr()
464 bi.lpszTitle = this.pTitle.Text( this ).ptr()
465 bi.ulFlags = $BIF_RETURNONLYFSDIRS | $BIF_NEWDIALOGSTYLE
466 if .pShowEdit : bi.ulFlags |= $BIF_EDITBOX
467 if !.pCanCreate : bi.ulFlags |= $BIF_NONEWFOLDERBUTTON
468 //CoInitialize(0)
469 lpidl = SHBrowseForFolder( bi )
470 if ( lpidl )
471 {
472 .pDir.reserve( 260 )
473 SHGetPathFromIDList( lpidl, .pDir.ptr() )
474 .pDir.setlenptr()
475 CoTaskMemFree( lpidl )
476 result = 1
477 }
478 else
479 {
480 .pDir.clear()
481 }
482 /*
483 if(pidlRoot)
484 {
485 CoTaskMemFree( pidlRoot )
486 }
487 */
488 return result
489 }
490
491
492
493 /* Компонента vColorDialog, порождена от vComp
494 */
495
496 type vColorDialog <inherit = vComp> {
497 //Hidden Fields
498 uint pColor
499 arr CustColors[16] of uint
500 uint pFullOpen
501 uint pPreventFullOpen
502 uint pSolidColor
503 uint pAnyColor
504 }
505
506 /*------------------------------------------------------------------------------
507 Properties
508 */
509
510 /* Свойство uint Color - Get Set
511 Устанавливает или определяет выбранный цвет
512 */
513 property uint vColorDialog.Color()
514 {
515 return .pColor
516 }
517
518 property vColorDialog.Color( uint val )
519 {
520 if .pColor != val
521 {
522 .pColor = val
523 }
524 }
525
526 /* Свойство uint AnyColor - Get Set
527 Устанавливает или определяет выбор любого цвета
528 */
529 property uint vColorDialog.AnyColor()
530 {
531 return .pAnyColor
532 }
533
534 property vColorDialog.AnyColor( uint val )
535 {
536 if .pAnyColor != val
537 {
538 .pAnyColor = val
539 }
540 }
541
542 /* Свойство uint SolidColor - Get Set
543 Устанавливает или определяет выбор заполненого цвета
544 */
545 property uint vColorDialog.SolidColor()
546 {
547 return .pSolidColor
548 }
549
550 property vColorDialog.SolidColor( uint val )
551 {
552 if .pSolidColor != val
553 {
554 .pSolidColor = val
555 }
556 }
557
558 /* Свойство ustr FullOpen - Get Set
559 Устанавливает или определяет режим полного просмотра
560 */
561 property uint vColorDialog.FullOpen()
562 {
563 return .pFullOpen
564 }
565
566 property vColorDialog.FullOpen( uint val )
567 {
568 if .pFullOpen != val
569 {
570 .pFullOpen = val
571 }
572 }
573
574 /* Свойство ustr PreventFullOpen - Get Set
575 Устанавливает или определяет режим полного просмотра
576 */
577 property uint vColorDialog.PreventFullOpen()
578 {
579 return .pPreventFullOpen
580 }
581
582 property vColorDialog.PreventFullOpen( uint val )
583 {
584 if .pPreventFullOpen != val
585 {
586 .pPreventFullOpen = val
587 }
588 }
589
590 func uint rgb_bgr( uint src )
591 {
592 return ( (src & 0xFF ) << 16 ) | ( src & 0xFF00 ) | ( ( src & 0xFF0000 ) >> 16 )
593 }
594 /*Вывод диалогового окна для выбора цвета*/
595 method uint vColorDialog.Show( )
596 {
597 CHOOSECOLOR chc
598 arr tmpcolors[16] of uint
599 tmpcolors = .CustColors
600
601 chc.lStructSize = sizeof( CHOOSECOLOR )
602 if &.Owner
603 {
604 chc.hwndOwner = .Owner->vCtrl.GetMainForm()->vCtrl.hwnd
605 }
606 if !chc.hwndOwner : chc.hwndOwner = GetActiveWindow()
607 chc.rgbResult = rgb_bgr( .pColor )
608 chc.lpCustColors = tmpcolors.ptr()
609 chc.Flags = $CC_RGBINIT
610 if .pAnyColor : chc.Flags |= $CC_ANYCOLOR
611 if .pSolidColor : chc.Flags |= $CC_SOLIDCOLOR
612 if .pFullOpen : chc.Flags |= $CC_FULLOPEN
613 if .pPreventFullOpen : chc.Flags |= $CC_PREVENTFULLOPEN
614 if ChooseColor( chc )
615 {
616 .CustColors = tmpcolors
617 .pColor = rgb_bgr( chc.rgbResult )
618 return 1
619 }
620 return 0
621 }
622
623
624 /* Компонента vFontDialog, порождена от vComp
625 */
626
627 type vFontDialog <inherit = vComp> {
628 //Hidden Fields
629 LOGFONT LogFont
630 uint pDevice
631 uint pSizeMin
632 uint pSizeMax
633 uint pEffects
634 uint pColor
635
636 }
637
638 define {
639 fddScreen = $CF_SCREENFONTS
640 fddPrinter = $CF_PRINTERFONTS
641 fddBoth = $CF_BOTH
642 }
643
644 operator LOGFONT =( LOGFONT left right )
645 {
646 mcopy( &left, &right, sizeof( LOGFONT ))
647 return left
648 }
649 /*------------------------------------------------------------------------------
650 Properties
651 */
652
653 /* Свойство uint SizeMin - Get Set
654 Устанавливает или определяет минимальный возможный размер
655 */
656 property uint vFontDialog.SizeMin()
657 {
658 return .pSizeMin
659 }
660
661 property vFontDialog.SizeMin( uint val )
662 {
663 if .pSizeMin != val
664 {
665 .pSizeMin = val
666 }
667 }
668
669 /* Свойство uint SizeMax - Get Set
670 Устанавливает или определяет максимальный возможный размер
671 */
672 property uint vFontDialog.SizeMax()
673 {
674 return .pSizeMax
675 }
676
677 property vFontDialog.SizeMax( uint val )
678 {
679 if .pSizeMax != val
680 {
681 .pSizeMax = val
682 }
683 }
684
685 /* Свойство uint Device - Get Set
686 Устанавливает или определяет максимальный возможный размер
687 */
688 property uint vFontDialog.Device()
689 {
690 return .pDevice
691 }
692
693 property vFontDialog.Device( uint val )
694 {
695 if .pDevice != val
696 {
697 .pDevice = val
698 }
699 }
700
701 /* Свойство uint Effects - Get Set
702 Устанавливает или определяет возможность эффектов
703 */
704 property uint vFontDialog.Effects()
705 {
706 return .pEffects
707 }
708
709 property vFontDialog.Effects( uint val )
710 {
711 if .pEffects != val
712 {
713 .pEffects = val
714 }
715 }
716
717
718 /* Свойство uint Color - Get Set
719 Устанавливает или определяет цвет шрифта
720 */
721 property uint vFontDialog.Color()
722 {
723 return .pColor
724 }
725
726 property vFontDialog.Color( uint val )
727 {
728 if .pColor != val
729 {
730 .pColor = val
731 }
732 }
733
734 /*Вывод диалогового окна для выбора цвета*/
735 method uint vFontDialog.Show( )
736 {
737 CHOOSEFONT chf
738 LOGFONT tmplogfont
739
740 tmplogfont = .LogFont
741
742 chf.lStructSize = sizeof( CHOOSEFONT )
743 chf.Flags = .pDevice | $CF_INITTOLOGFONTSTRUCT
744 if .pEffects : chf.Flags |= $CF_EFFECTS
745 chf.nSizeMin = .pSizeMin
746 chf.nSizeMax = .pSizeMax
747 chf.lpLogFont = &tmplogfont
748 if &.Owner
749 {
750 chf.hwndOwner = .Owner->vCtrl.GetMainForm()->vCtrl.hwnd
751 }
752 if !chf.hwndOwner : chf.hwndOwner = GetActiveWindow()
753 chf.rgbColors = .pColor
754 if ChooseFont( chf )
755 {
756 .LogFont = tmplogfont
757 .pColor = chf.rgbColors
758 return 1
759 }
760 return 0
761 }
762
763 /*------------------------------------------------------------------------------
764 Registration
765 */
766 method vOpenSaveDialog vOpenSaveDialog.init( )
767 {
768 this.pTypeId = vOpenSaveDialog
769 return this
770 }
771
772 method vSelectDir vSelectDir.init( )
773 {
774 this.pTypeId = vSelectDir
775 this.pCanCreate = 1
776 return this
777 }
778
779 method vColorDialog vColorDialog.init( )
780 {
781 this.pTypeId = vColorDialog
782 return this
783 }
784
785 method vFontDialog vFontDialog.init( )
786 {
787 this.pTypeId = vFontDialog
788 .pDevice = $fddScreen
789 .pEffects = 1
790 return this
791 }
792
793 func init_vOpenSaveDialog <entry>()
794 {
795 regcomp( vOpenSaveDialog, "vOpenSaveDialog", vComp, $vComp_last,
796 %{ %{$mLangChanged, vOpenSaveDialog_mLangChanged } },
797 0->collection )
798
799 regcomp( vSelectDir, "vSelectDir", vComp, $vComp_last,
800 0->collection,
801 0->collection )
802
803 regcomp( vColorDialog, "vColorDialog", vComp, $vComp_last,
804 0->collection,
805 0->collection )
806
807 regcomp( vFontDialog, "vFontDialog", vComp, $vComp_last,
808 0->collection,
809 0->collection )
810
811 //CoInitializeEx(0,0)
812 AddrBrowseCallbackProc = callback( &BrowseCallbackProc, 4 )
813
814 ifdef $DESIGNING {
815
816 cm.AddComp( vOpenSaveDialog, 1, "Windows", "dialogs" )
817
818 cm.AddProps( vOpenSaveDialog, %{
819 "DefExt", ustr, 0,
820 "FileName", ustr, 0,
821 "InitialDir", ustr, 0,
822 "FilterIndex", uint, 0,
823 "FiltersText", ustr, 0,
824 "TitleOpen" , ustr, 0,
825 "TitleSave" , ustr, 0,
826 "MultiSelect", uint, 0
827 })
828
829 cm.AddComp( vSelectDir, 1, "Windows", "dialogs" )
830
831 cm.AddProps( vSelectDir, %{
832 "Title", ustr, 0,
833 "Dir", ustr, 0,
834 "CanCreate", uint, 0,
835 "ShowEdit", uint, 0
836 })
837
838 cm.AddComp( vColorDialog, 1, "Windows", "dialogs" )
839 cm.AddProps( vColorDialog, %{
840 "Color", uint, 0,
841 "AnyColor", uint, 0,
842 "SolidColor",uint, 0,
843 "FullOpen", uint, 0,
844 "PreventFullOpen", uint, 0
845 })
846
847 cm.AddComp( vFontDialog, 1, "Windows", "dialogs" )
848 cm.AddProps( vFontDialog, %{
849 "SizeMin", uint, 0,
850 "SizeMax", uint, 0,
851 "Effects",uint, 0,
852 "Color", uint, 0
853 })
854 }
855
856
857
858 }