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.treeview 25.09.07 0.0.A.
11 *
12 * Author: Alexander Krivonogov ( gentee )
13 *
14 ******************************************************************************/
15 include {
16 // "app.g"
17 "..\\gt\\gt.g"
18 }
19
20 define <export>{
21 TVSORT_NONE = 0
22 TVSORT_SORT = 1
23 TVSORT_RECURSE = 2
24 TVSORT_NONERECURSE = $TVSORT_NONE | $TVSORT_RECURSE
25 TVSORT_SORTRECURSE = $TVSORT_SORT | $TVSORT_RECURSE
26 }
27
28
29
30 type TVItem <index=this inherit=gtitem>
31 {
32
33 }
34
35 type TVSelection <index=TVItem>
36 {
37 uint pTreeView
38 arr Items of uint
39 uint StartShift
40 }
41
42 type treedata
43 {
44 //uint TreeView
45 uint treeview //Объект содержащий данный элемент
46 uint handle //Идентификатор элемента в окне
47 //uint inselection
48
49 //uint tag
50 //uint gttree
51 }
52
53 type evparTVEdit <inherit=evparEvent>
54 {
55 uint Item
56 ustr NewLabel
57 uint flgCancel
58 }
59
60 type evTVEdit <inherit=evEvent> :
61
62 method evTVEdit evTVEdit.init
63 {
64 this.eventtypeid = evparTVEdit
65 return this
66 }
67
68 /*
69
70 type evparItemMoved <inherit=evparEvent>
71 {
72 uint SrcItem
73 uint DestItem
74 uint Flag
75 }
76
77 type evItemMoved <inherit=evEvent> :
78
79 method evItemMoved evItemMoved.init
80 {
81 this.eventtypeid = evparItemMoved
82 return this
83 }
84 */
85 /* Компонента vTreeView, порождена от vCtrl
86 События
87 onClick - вызывается при нажатии на кнопку
88 */
89 type vTreeView <inherit = vCtrl>
90 {
91 //Hidden Fields
92 uint fConnectGt
93 /*locustr pCaption
94 uint pChecked
95 uint ptreeviewStyle*/
96 uint pShowPlusMinus //Показывать +/-
97 uint pShowLines //Показывать линейки дерева
98 uint pShowRootLines //Показывать корневую линейку
99 uint pShowSelection //Всегда показывать выделение
100 uint pRowSelect //Выделение элемента в виде строки
101 uint pLabelEdit //Возможность редактирования элементов
102 uint pBorder //Показывать рамку
103 uint pSorted //Сортировать элементы
104 uint pSelected //Текущий выбранный элемент
105 uint pMultiSelect //Выделение нескольких элементов
106 uint pAutoDrag //Возможность перетаскивать элементы
107 // uint pDragDrop
108 uint fDrag //Флаг, находимся в режиме drag'n'drop
109 uint fFromMouse
110 uint fMoving
111 uint fReleasing //Находимся в режиме освобождения
112 ustr pImageList
113 uint ptrImageList
114 ustr pStateImageList
115 uint ptrStateImageList
116 uint iNumIml
117 uint iStateNumIml
118 //arr items[1] of TVItem
119 //arr pSelections of uint
120 TVSelection Selection
121 gt gttree //Представление в виде gt
122 uint gtroot
123 //Events
124 //onevent onStartEdit
125 evTVEdit OnAfterEdit
126 evTVEdit OnBeforeEdit
127 evQuery OnBeforeSelect
128 evValUint OnAfterSelect
129 //evTVBefore OnBeforeExpand
130 //evTVAfter OnAfterExpand
131 //evTVBefore OnBeforeCollapse
132 //evTVAfter OnAfterCollapse
133 //evItemMoved OnItemMoved
134 evBeforeMove OnBeforeMove
135 evAfterMove OnAfterMove
136 }
137
138 /*define {
139 //Стили кнопки treeviewStyle
140 bsClassic = 0
141 bsAsRadiotreeview = 3
142 bsAsCheckBox = 4
143 }*/
144
145 extern {
146 //property uint TVItem.InSelections
147 //property TVItem.InSelections( uint val )
148 property TVItem vTreeView.Selected()
149 property vTreeView.Selected( TVItem item )
150 property ustr TVItem.Label<result>()
151 property TVItem TVItem.Child()
152 property TVItem TVItem.Prev()
153 //method TVItem.WinSet( uint mask )
154 property TVItem vTreeView.Root
155 method TVItem.Del()
156 method vTreeView.Reload()
157 }
158
159 include {
160 "treeviewitem.g"
161 }
162
163 /*Метод vToolBar.iUpdateImageList()
164 Обновить ImageList
165 */
166 method vTreeView.iUpdateImgList()
167 {
168 .ptrImageList = &.GetImageList( .pImageList, &.iNumIml )
169 if .ptrImageList
170 {
171 .WinMsg( $TVM_SETIMAGELIST, $TVSIL_NORMAL, .ptrImageList->ImageList.arrIml[.iNumIml].hIml )
172 }
173 else
174 {
175 .WinMsg( $TVM_SETIMAGELIST, $TVSIL_NORMAL, 0 )
176 }
177 .ptrStateImageList = &.GetImageList( .pStateImageList, &.iStateNumIml )
178 if .ptrStateImageList
179 {
180 .WinMsg( $TVM_SETIMAGELIST, $TVSIL_STATE, .ptrStateImageList->ImageList.arrIml[.iNumIml].hIml )
181 }
182 else
183 {
184 .WinMsg( $TVM_SETIMAGELIST, $TVSIL_STATE, 0 )
185 }
186 .Invalidate()
187 }
188 /*------------------------------------------------------------------------------
189 Public Methods
190 */
191
192 method vTreeView.iWinClear( uint flgdelitem )
193 {
194 .Selection.Clear()
195 .Selected = 0->TVItem
196
197 //.pSelected = 0
198 .fReleasing = 1
199 .WinMsg( $TVM_DELETEITEM, 0, 0 )
200 // .Root.iWinClear( flgdelitem )
201 uint children as .Root.Children
202 if &children
203 {
204 uint prev as children.lastchild()->TVItem
205 while &prev
206 {
207 prev.iWinClear( flgdelitem )
208 uint cur as prev
209 prev as cur.Prev
210 if flgdelitem : cur.del()
211 }
212 }
213 .fReleasing = 0
214 }
215
216 method vTreeView.Clear()
217 {
218 .iWinClear( 1 )
219 /* .fReleasing = 1
220 .WinMsg( $TVM_DELETEITEM, 0, 0 )
221 .Root.iWinClear( 1 )
222 .fReleasing = 0*/
223 /*.Root.Release()
224 .gttree.clear()
225 .Reload()*/
226 //.Root.Del()
227 //.WinMsg( $TVM_DELETEITEM, 0, $TVI_ROOT )
228 //.gttree.clear()
229 /*if *.items > 1
230 {
231 .items.del( 1, *.items - 2 )
232 .WinMsg( $TVM_DELETEITEM, 0, $TVI_ROOT )
233 .gti.clear()
234 } */
235 }
236
237 method vTreeView.Edit()
238 {
239 if &(.Selected())
240 {
241 .SetFocus()
242 .WinMsg( $TVM_EDITLABELW, 0, .Selected().param->treedata.handle )
243 }
244 }
245
246
247 method vTreeView.ReloadGTItem( TVItem parent, TVItem item )
248 {
249 //if &parent
250 {
251
252 uint itemdata as new( treedata )->treedata
253 itemdata.treeview = &this
254 item.param = &itemdata
255 /*child.set( "name", name.toutf8( "" ) )
256 child.setuint( "tag", tag )*/
257 //TVINSERTSTRUCT ti
258 //ti.item.pszText = name.ptr()
259 /*uint sorttype = .getuint( "sorttype" )
260 if sorttype & $TVSORT_SORT
261 {
262 //ti.hInsertAfter = $TVI_SORT
263 if sorttype == $TVSORT_SORTRECURSE
264 {
265 child.setuint( "sorttype", sorttype )
266 }
267 }*/
268 if &parent : parent.iItemInsert( item )
269 }
270 uint children as item.Children
271 if &children
272 {
273 foreach child, children
274 {
275 .ReloadGTItem( item, child->TVItem )
276 }
277 }
278 item.iItemUpdate( $TVIF_STATE | $TVIF_TEXT | $TVIF_SELECTEDIMAGE | $TVIF_IMAGE)
279 }
280
281 method vTreeView.Reload()
282 {
283
284 uint index
285 if !.gtroot
286 {
287 .gtroot = &this.gttree.root()
288 }
289 else
290 {
291 //this.Root.Release()
292
293 .iWinClear( 0 )
294
295
296 }
297
298 .pSelected = 0
299 uint root as this.Root
300 //root.Release()
301 uint children as root.Children
302 if !&children
303 {
304 children as root.insertchild( "children", 0->gtitem )
305 //foreach child, root->gtitem
306 uint child as root->gtitem.child()
307 while &child
308 {
309 uint next as child.getnext()
310 if &child != &children
311 {
312 child.move( children, $TREE_LAST )
313 child.gettreeitem().changenode( children.gettreeitem() )
314 }
315 child as next
316 }
317 /*.gttree.write( "tmp.gt" )
318 .gttree.clear()
319 .gttree.read( "tmp.gt" )*/
320 }
321 this.ReloadGTItem( 0->TVItem, root )
322 uint child as root.Child
323
324 //.Selected = 0->TVItem
325 if &child
326 {
327 .Selected = child
328 }
329
330 this.Root().SortType = ?( .pSorted, $TVSORT_SORTRECURSE, $TVSORT_NONE )
331 }
332
333
334 method vTreeView.ConnectGt( gtitem gtroot )
335 {
336 /* int i
337 for i = *.Rows - 1, i >= 0, i--
338 {
339 .Rows[i].Release()
340 }
341 */
342
343 .iWinClear( 0 )
344 //.Root.Release()
345
346 if !.fConnectGt
347 {
348 //.gtroot->gtitem.del()
349 .gtroot = 0
350 }
351 /*else
352 {
353
354 }*/
355
356 /**/
357 if >root
358 {
359 .gtroot = >root
360 .fConnectGt = 1
361 }
362 else
363 {
364 .gtroot = 0
365 .fConnectGt = 0
366 }
367 .Reload()
368
369 }
370
371 method vTreeView.DisconnectGt( )
372 {
373
374 if .fConnectGt : .ConnectGt( 0->gtitem)
375 //.gtrows = 0
376 }
377
378 method TVItem vTreeView.HitTest( uint x y uint pflags )
379 {
380 uint item
381
382 TVHITTESTINFO tvht
383 tvht.pt.x = x
384 tvht.pt.y = y
385
386 uint dest = .WinMsg( $TVM_HITTEST, 0, &tvht )
387 if pflags : pflags->uint = tvht.flags
388 if dest
389 {
390 TVITEM tvi
391 tvi.mask = $TVIF_PARAM
392 tvi.hItem = dest
393 .WinMsg( $TVM_GETITEMW, 0, &tvi )
394 item = tvi.lParam
395 }
396 return item->TVItem
397 }
398
399
400 method vTreeView.DelSelected()
401 {
402 int i
403 .Selection.RemoveChildren()
404 for i = *.Selection-1, i >= 0, i--
405 {
406 .Selection[i].Del()
407 }
408 }
409
410 method vTreeView.ExpandAll( uint val )
411 {
412 .Root.ExpandRecurse( val )
413 }
414 /*------------------------------------------------------------------------------
415 Properties
416 */
417 /*Свойство ustr Border - Get Set
418 Установить, получить наличие рамки у поля ввода
419 1 - рамка есть
420 0 - рамки нет
421 */
422 property vTreeView.Border( uint val )
423 {
424 .pBorder = val
425 uint style = GetWindowLong( this.hwnd, $GWL_EXSTYLE )
426 if val : style |= $WS_EX_CLIENTEDGE
427 else : style &= ~$WS_EX_CLIENTEDGE
428 SetWindowLong( this.hwnd, $GWL_EXSTYLE, style )
429 SetWindowPos( this.hwnd, 0, 0, 0, 0, 0, $SWP_FRAMECHANGED |
430 $SWP_NOACTIVATE | $SWP_NOZORDER | $SWP_NOMOVE | $SWP_NOSIZE )
431 }
432
433 property uint vTreeView.Border
434 {
435 //.pBorder = ?(GetWindowLong( this.hwnd, $GWL_EXSTYLE ) & $WS_EX_CLIENTEDGE,1,0)
436 return .pBorder
437 }
438
439 /*Свойство ustr ShowPlusMinus - Get Set
440 Установить, получить отображение кнопочки с крестиком/минусом отображающим
441 открытие ветки
442 1 - кнопка есть
443 0 - кнопок нет
444 */
445 property vTreeView.ShowPlusMinus( uint val )
446 {
447 .pShowPlusMinus = val
448 .SetStyle( $TVS_HASBUTTONS, val )
449 }
450
451 property uint vTreeView.ShowPlusMinus
452 {
453 return .pShowPlusMinus//.GetStyle( $TVS_HASBUTTONS )
454 }
455
456 /*Свойство ustr ShowLines - Get Set
457 Установить, получить отображение линеек слева от веток
458 1 - есть
459 0 - нет
460 */
461 property vTreeView.ShowLines( uint val )
462 {
463 .pShowLines = val
464 .SetStyle( $TVS_HASLINES , val )
465 }
466
467 property uint vTreeView.ShowLines
468 {
469 return .pShowLines//.GetStyle( $TVS_HASLINES )
470 }
471
472 /*Свойство ustr ShowRootLines - Get Set
473 Установить, получить отображение линеек у корневого элемента
474 открытие ветки
475 1 - есть
476 0 - нет
477 */
478 property vTreeView.ShowRootLines( uint val )
479 {
480 .pShowRootLines = val
481 .SetStyle( $TVS_LINESATROOT, val )
482 }
483
484 property uint vTreeView.ShowRootLines
485 {
486 return .pShowRootLines//.GetStyle( $TVS_LINESATROOT )
487 }
488
489 /*Свойство ustr ShowSelection - Get Set
490 Установить, получить отображение линеек слева от веток
491 1 - есть
492 0 - нет
493 */
494 property vTreeView.ShowSelection( uint val )
495 {
496 .pShowSelection = val
497 .SetStyle( $TVS_SHOWSELALWAYS, val )
498 }
499
500 property uint vTreeView.ShowSelection
501 {
502 return .pShowSelection//.GetStyle( $TVS_HASLINES )
503 }
504
505 /*Свойство ustr RowSelect - Get Set
506 Установить, получить отображение линеек слева от веток
507 1 - есть
508 0 - нет
509 */
510 property vTreeView.RowSelect( uint val )
511 {
512 .pRowSelect = val
513 .SetStyle( $TVS_FULLROWSELECT , val )
514 }
515
516 property uint vTreeView.RowSelect
517 {
518 return .pRowSelect//.GetStyle( $TVS_HASLINES )
519 }
520
521 /*Свойство ustr LabelEdit - Get Set
522 Установить, получить отображение линеек слева от веток
523 1 - есть
524 0 - нет
525 */
526 property vTreeView.LabelEdit( uint val )
527 {
528 .pLabelEdit = val
529 .SetStyle( $TVS_EDITLABELS , val )
530 }
531
532 property uint vTreeView.LabelEdit
533 {
534 return .pLabelEdit//.GetStyle( $TVS_HASLINES )
535 }
536
537 /* Свойство str vTreeView.ImageList - Get Set
538 Устанавливает или получает имя списка картинок
539 */
540 property ustr vTreeView.ImageList <result>
541 {
542 result = this.pImageList
543 }
544
545 property vTreeView.ImageList( ustr val )
546 {
547 if val != this.pImageList
548 {
549 this.pImageList = val
550 .Virtual( $mLangChanged )
551 //.iUpdateImageList()
552 }
553 }
554
555 /* Свойство str vTreeView.StateImgListName - Get Set
556 Устанавливает или получает имя списка картинок состояний
557 */
558 property ustr vTreeView.StateImageList <result>
559 {
560 result = this.pStateImageList
561 }
562
563 property vTreeView.StateImageList( ustr val )
564 {
565 if val != this.pStateImageList
566 {
567 this.pStateImageList = val
568 .Virtual( $mLangChanged )
569 //.iUpdateImageList()
570 }
571 }
572
573 /* Свойство uint vTreeView.MultiSelect - Get Set
574 Выделение нескольких элементов
575 */
576 property uint vTreeView.MultiSelect()
577 {
578 return .pMultiSelect
579 }
580
581 property vTreeView.MultiSelect( uint val )
582 {
583 if val != this.pMultiSelect
584 {
585 this.pMultiSelect = val
586 }
587 }
588
589
590 /* Свойство uint vListView.AutoDrag - Get Set
591 Возможность перетаскивать элементы внутри объекта
592 */
593 property uint vTreeView.AutoDrag()
594 {
595 return .pAutoDrag
596 }
597
598 property vTreeView.AutoDrag( uint val )
599 {
600 this.pAutoDrag = val
601 }
602
603 /*property TVSelections vTreeView.Selections
604 {
605 return this->TVSelections
606 }
607
608
609
610 method TVItem TVSelections.index( uint idx )
611 {
612 uint tv as this->vTreeView
613 if idx < *tv.pSelections
614 {
615 return tv.pSelections[idx]->TVItem
616 }
617 return 0->TVItem
618 }
619
620 operator uint * ( TVSelections sel )
621 {
622 return *sel->vTreeView.pSelections
623 }
624
625 method TVSelections.Clear()
626 {
627 uint tv as this->vTreeView
628 while *tv.pSelections
629 {
630 tv.pSelections[0]->TVItem.InSelections = 0
631 }
632 }*/
633 /*method TVItem.Index( uint 0 )
634 {
635
636 }*/
637
638
639 property TVItem vTreeView.Root
640 {
641 if &this
642 {
643 return .gtroot->TVItem//.gttree.root()->TVItem//.items[0]
644 }
645 return 0->TVItem
646 }
647
648
649
650 /* Свойство uint Sorted - Get Set
651 Устанавливает или определяет должны ли сортироваться элементы в дереве
652 1 - элементы сортируются
653 0 - элементы не сортируются
654 */
655 property uint vTreeView.Sorted()
656 {
657 return this.pSorted
658 }
659
660 property vTreeView.Sorted( uint val)
661 {
662 if this.pSorted != val
663 {
664 this.pSorted = val
665 this.Root().SortType = ?( val, $TVSORT_SORTRECURSE, $TVSORT_NONE )
666
667 }
668 }
669
670 property TVItem vTreeView.Selected()
671 {
672 return this.pSelected->TVItem
673 }
674
675 property vTreeView.Selected( TVItem item )
676 {
677 if this.pSelected != &item
678 {
679 uint destitem = &item
680 if destitem == &this.Root : destitem = 0
681 //this.pSelected = destitem
682 .WinMsg( $TVM_SELECTITEM, $TVGN_CARET, ?( destitem, destitem->TVItem.param->treedata.handle, 0) )
683 }
684 }
685
686 /* Свойство uint InSelections - Get Set
687 Устанавливает или определяет находится ли элемент в числе выбранных
688 */
689 /*property uint TVItem.InSelections
690 {
691 return .param->treedata.inselections
692 }
693
694 property TVItem.InSelections( uint val )
695 {
696 if val != .param->treedata.inselections
697 {
698 .param->treedata.inselections = val
699 uint sels as .param->treedata.treeview->vTreeView.pSelections
700 if val
701 {
702 sels[sels.expand( 1 )] = &this
703 }
704 else
705 {
706 uint i
707 fornum i = 0, *sels
708 {
709 if sels[i] == &this
710 {
711 sels.del(i)
712 break;
713 }
714 }
715 }
716 .iItemUpdate( $TVIF_STATE )
717 }
718 }
719 */
720
721 /* Свойство uint treeviewStyle - Get Set
722 Усотанавливает или определяет стиль кнопки
723 Возможны следующие варианты:
724 bsClassic - обычный вид,
725 bsAsRadiotreeview - работает как Radiotreeview,
726 bsAsCheckBox - работает как CheckBox
727 */
728 /*property uint vTreeView.treeviewStyle()
729 {
730 return this.ptreeviewStyle
731 }
732
733 property vTreeView.treeviewStyle( uint val)
734 {
735 if this.ptreeviewStyle != val
736 {
737 uint checked = this.Checked
738 uint remstyle = $BS_AUTORADIOBUTTON | $BS_AUTOCHECKBOX | $BS_PUSHLIKE
739 uint addstyle
740 this.WinMsg( $BM_SETCHECK, 0 )
741 this.pChecked = 0
742 if val == $bsAsRadiotreeview
743 {
744 addstyle = $BS_AUTORADIOBUTTON | $BS_PUSHLIKE
745 }
746 elif val == $bsAsCheckBox
747 {
748 addstyle = $BS_AUTOCHECKBOX | $BS_PUSHLIKE
749 }
750 this.ChangeStyle( addstyle, remstyle )
751 this.ptreeviewStyle = val
752 this.Checked = checked
753 }
754 }
755 */
756 /* Свойство uint Caption - Get Set
757 Усотанавливает или определяет заголовок кнопки
758 */
759 /*property ustr vTreeView.Caption <result>
760 {
761 result = this.pCaption.Value
762 }
763
764 property vTreeView.Caption( ustr val )
765 {
766 this.pCaption.Value = val
767 SetWindowText( this.hwnd, this.pCaption.Text.ptr() )
768 }
769
770
771 */
772 /*------------------------------------------------------------------------------
773 Virtual Methods
774 */
775 /*Виртуальный метод vTreeView vTreeView.mCreateWin - Создание окна
776 */
777 method vTreeView vTreeView.mCreateWin <alias=vTreeView_mCreateWin>()
778 {
779 uint exstyle
780 uint style = $WS_CHILD | $WS_CLIPSIBLINGS
781 if .pShowPlusMinus : style |= $TVS_HASBUTTONS
782 if .pShowLines : style |= $TVS_HASLINES
783 if .pShowRootLines : style |= $TVS_LINESATROOT
784 if .pShowSelection : style |= $TVS_SHOWSELALWAYS
785 if .pRowSelect : style |= $TVS_FULLROWSELECT
786 if .pLabelEdit : style |= $TVS_EDITLABELS
787
788 if .pBorder : exstyle |= $WS_EX_CLIENTEDGE
789 this.CreateWin( "SysTreeView32".ustr(), exstyle, style )
790 this->vCtrl.mCreateWin()
791 this.WinMsg( $WM_SETFONT, GetStockObject( $DEFAULT_GUI_FONT ) )
792 .iUpdateImgList()
793 //uint himl = ImageList_Create(16, 16, 0xFE, 1, 0)
794 //uint hbitmap = LoadBitmap( 0, 32754 )//"OBM_CHECKBOXES".ustr().ptr() )
795 //ImageList_Add( himl,hbitmap,0)
796 //DeleteObject( hbitmap )
797 //hbitmap = LoadBitmap( 0, 32759 )//"OBM_CHECKBOXES".ustr().ptr() )
798 //ImageList_Add( himl,hbitmap,0)
799 //DeleteObject( hbitmap )
800 //.WinMsg( $TVM_SETINDENT, -20 )
801 // .WinMsg( $TVM_SETIMAGELIST, 0, himl );
802 .Reload()
803 return this
804 }
805
806 /*Виртуальный метод uint vTreeView.mWinNtf - обработка сообщений
807 */
808 method uint vTreeView.mWinNtf <alias=vTreeView_mWinNtf>( winmsg wmsg )//NMHDR ntf )
809 {
810 uint nmtv as wmsg.lpar->NMTREEVIEWW
811 switch nmtv.hdr.code
812 {
813 case $NM_RCLICK
814 {
815 //TVHITTESTINFO tvht
816 POINT pt
817 uint lpar
818 //uint curitem
819
820 GetCursorPos( pt )
821 lpar = ( pt.y << 16 ) | pt.x
822 ScreenToClient( .hwnd, pt )
823 /*tvht.pt = pt
824 if curitem = .WinMsg( $TVM_HITTEST, 0, &tvht )
825 {
826 .WinMsg( $TVM_SELECTITEM, $TVGN_CARET, curitem )
827 }*/
828
829 .WinMsg( $WM_CONTEXTMENU, this.hwnd, lpar )
830 }
831 case $TVN_GETDISPINFOW
832 {
833 nmtv as NMTVDISPINFO
834 //uint nd as ntf->NMTVDISPINFO
835 if nmtv.item.mask & $TVIF_IMAGE
836 {
837 nmtv.item.iImage = -1
838 }
839 if nmtv.item.mask & $TVIF_SELECTEDIMAGE
840 {
841 nmtv.item.iSelectedImage = -1
842 }
843 return 0
844 }
845 case $TVN_SELCHANGEDW
846 {
847 uint selected = ?( nmtv.itemNew.hItem, nmtv.itemNew.lParam, 0 )
848 if selected == this.pSelected : return 0
849 this.pSelected = selected
850
851 if .pMultiSelect
852 {
853 if !.fReleasing
854 {
855 nmtv as NMTREEVIEWW
856 if GetKeyState( $VK_SHIFT ) & 0x8000// nmtv.action == 2/*$TVC_BYMOUSE*/ &&
857 {
858 if nmtv.itemNew.lParam
859 {
860 if .fFromMouse
861 {
862 if nmtv.itemOld.lParam
863 {
864 if .Selection.Find( nmtv.itemOld.lParam->TVItem ) != -1
865 {
866 .Selection.iSelect( nmtv.itemOld.lParam->TVItem, 1 )
867 }
868 }
869 }
870 else
871 {
872 .Selection.Clear()
873 }
874 uint item
875 uint flgselect
876 item as .Root
877 if .Selection.StartShift
878 {
879 while ( item as item.NextInList )
880 {
881 if !flgselect
882 {
883 if &item == .Selection.StartShift : flgselect = 1
884 elif &item == nmtv.itemNew.lParam : flgselect = 2
885 else : continue
886 }
887 {
888 .Selection.Append( item )
889 if ( flgselect == 2 && &item == .Selection.StartShift ) ||
890 ( flgselect == 1 && &item == nmtv.itemNew.lParam )
891 {
892 break
893 }
894 }
895
896 }
897 }
898 else
899 {
900 .Selection.StartShift = nmtv.itemNew.lParam
901 .Selection.Append( nmtv.itemNew.lParam->TVItem )
902 }
903 }
904 }
905 elif GetKeyState( $VK_CONTROL ) & 0x8000 && .fFromMouse/*$TVC_BYMOUSE*/
906 {
907 if nmtv.itemNew.lParam
908 {
909 if .Selection.Find( nmtv.itemNew.lParam->TVItem ) != -1
910 {
911 .Selection.Remove( nmtv.itemNew.lParam->TVItem )
912 }
913 else
914 {
915 .Selection.Append( nmtv.itemNew.lParam->TVItem )
916 }
917 .Selection.StartShift = nmtv.itemNew.lParam
918 }
919 if nmtv.itemOld.lParam
920 {
921 if .Selection.Find( nmtv.itemOld.lParam->TVItem ) != -1
922 {
923 .Selection.iSelect( nmtv.itemOld.lParam->TVItem, 1 )
924 }
925 }
926 }
927 else
928 {
929 .Selection.Clear()
930 if nmtv.itemNew.lParam
931 {
932 /* if .Selection.Find( nmtv.itemNew.lParam->TVItem ) == -1
933 {
934 .Selection.Clear()
935 .Selection.Append( nmtv.itemNew.lParam->TVItem )
936 }
937 else
938 {
939 //InvalidateRect( this.hwnd, 0->RECT, 0 )
940 //.Selections.iWinUpdate( 1 )
941
942 if nmtv.itemOld.lParam
943 {
944 if .Selection.Find( nmtv.itemOld.lParam->TVItem ) != -1
945 {
946 .Selection.iSelect( nmtv.itemOld.lParam->TVItem, 1 )
947 }
948 }
949 } */
950 .Selection.Append( nmtv.itemNew.lParam->TVItem )
951 .Selection.StartShift = nmtv.itemNew.lParam
952 }
953 }
954 }
955 else
956 {
957 if nmtv.itemNew.lParam
958 {
959 .Selection.Append( nmtv.itemNew.lParam->TVItem )
960 .Selection.StartShift = nmtv.itemNew.lParam
961 }
962 }
963
964 //if nmtv.itemOld.lParam &&
965 // (( nmtv.action == 1/*$TVC_BYMOUSE*/ && GetKeyState( $VK_CONTROL ) & 0x8000 ) ||
966 // ( nmtv.action == 2/*$TVC_BYKEYBOARD*/ && GetKeyState( $VK_SHIFT ) & 0x8000 ))
967
968 // nmtv.itemOld.lParam->TVItem.InSelections = !nmtv.itemOld.lParam->TVItem.InSelections
969 //wmsg.flags = 1
970
971
972 }
973 else
974 {
975 .Selection.Clear()
976 if &this.Selected
977 {
978 .Selection.Append( this.Selected )
979 }
980 }
981 evparValUint etva
982 etva.val = this.pSelected
983 etva.sender = &this
984 .OnAfterSelect.Run( /*this,*/ etva )
985 }
986 case $TVN_SELCHANGINGW
987 {
988 if .fMoving
989 {
990 wmsg.flags = 1
991 return 1
992 }
993 /* nmtv as NMTREEVIEWW
994 if nmtv.action == 1 && GetKeyState( $VK_CONTROL ) & 0x8000
995 {
996 wmsg.flags= 1
997 return 1
998 }*/
999 evparQuery etvb
1000 etvb.val = ?( nmtv.itemNew, nmtv.itemNew.lParam, 0 )
1001 etvb.sender = &this
1002 .OnBeforeSelect.Run( /*this,*/ etvb )
1003 return etvb.flgCancel
1004 }
1005 case $TVN_ITEMEXPANDEDW
1006 {
1007 if nmtv.action & ( $TVE_COLLAPSE | $TVE_EXPAND )
1008 {
1009 nmtv.itemNew.lParam->TVItem.setuint( "expanded", nmtv.action & $TVE_EXPAND )
1010
1011 }
1012 /*foreach it, this.Root()
1013 {
1014 .Selected = it
1015 break;
1016 }*/
1017
1018 }
1019 case $TVN_ITEMEXPANDINGW
1020 {
1021 }
1022 case $TVN_BEGINLABELEDITW
1023 {
1024 evparTVEdit etve
1025 etve.Item = &.Selected
1026 etve.sender = &this
1027 .OnBeforeEdit.Run( /*this,*/ etve )
1028 return etve.flgCancel
1029 }
1030 case $TVN_ENDLABELEDITW
1031 {
1032 nmtv as NMTVDISPINFO
1033
1034 evparTVEdit etve
1035 uint item as ?( nmtv.item.hItem, nmtv.item.lParam, 0 )->TVItem
1036
1037 etve.Item = &item
1038 if nmtv.item.pszText
1039 {
1040 etve.NewLabel.copy( nmtv.item.pszText )
1041 }
1042 else
1043 {
1044 etve.flgCancel = 1
1045 }
1046 etve.sender = &this
1047 .OnAfterEdit.Run( /*this,*/ etve )
1048 if !etve.flgCancel
1049 {
1050 if &item
1051 {
1052 item.Label = etve.NewLabel
1053 }
1054 /*uint selected as .Selected
1055 if &selected
1056 {
1057 selected.Label = etve.NewLabel
1058 //selected.set( "label", etve.NewLabel.toutf8( "" ) )
1059 } */
1060 return 1
1061 }
1062 }
1063 case $TVN_BEGINDRAGW
1064 {
1065 if .pAutoDrag
1066 {
1067 .Selected = nmtv.itemNew.lParam->TVItem
1068 //RECT rect
1069 //(&rect)->uint = nmtv.itemNew.hItem
1070 //.WinMsg( $TVM_GETITEMRECT, 1, &rect )
1071 //uint hdc = GetDC( .hwnd )
1072
1073 SetCapture( .hwnd )
1074 .fDrag = 1
1075 }
1076 }
1077 case $TVN_DELETEITEMW
1078 {
1079 }
1080 case $NM_CUSTOMDRAW
1081 {
1082 uint cd as wmsg.lpar->NMTVCUSTOMDRAW
1083 uint resi = $CDRF_DODEFAULT;
1084 switch( cd.nmcd.dwDrawStage )
1085 {
1086 case $CDDS_PREPAINT: resi |= $CDRF_NOTIFYITEMDRAW;
1087 case $CDDS_ITEMPREPAINT
1088 {
1089 uint item as cd.nmcd.lItemlParam->TVItem
1090 if &item && item.getuint( "disabled" ) : cd.clrText = GetSysColor(16)
1091 }
1092 }
1093 wmsg.flags = 1
1094 return resi
1095 }
1096 }
1097 return 0
1098 }
1099
1100 method uint vTreeView.mMouse <alias=vTreeView_mMouse>( evparMouse em )
1101 {
1102 switch em.evmtype
1103 {
1104 case $evmMove
1105 {
1106 if .fDrag
1107 {
1108 POINT point
1109 uint destitem
1110 //TVHITTESTINFO tvht
1111
1112 /*tvht.pt.x = */point.x = em.x
1113 /*tvht.pt.y =*/ point.y = em.y
1114 //if dest = .WinMsg( $TVM_HITTEST, 0, &tvht)
1115
1116 if destitem = &.HitTest( em.x, em.y, 0 )
1117 {
1118 destitem as TVItem
1119 /*TVITEM tvi
1120 tvi.mask = $TVIF_PARAM
1121 tvi.hItem = dest
1122 .WinMsg( $TVM_GETITEMW, 0, &tvi )
1123 uint destitem as tvi.lParam->TVItem*/
1124
1125 if .Selection.Find( destitem ) == -1
1126 {
1127 .WinMsg( $TVM_SELECTITEM, $TVGN_DROPHILITE, destitem.param->treedata.handle )
1128 //.WinMsg( $TVM_EXPAND, $TVE_EXPAND, destitem )
1129 SetCursor( App.cursorDrag )
1130 }
1131 else
1132 {
1133 .WinMsg( $TVM_SELECTITEM, $TVGN_DROPHILITE, 0 )
1134 SetCursor( App.cursorNoDrag )
1135 }
1136 }
1137 else
1138 {
1139 if int( em.x ) > 0 && int( em.y ) > 0 && em.x < .clloc.width && em.y < .clloc.height
1140 {
1141 SetCursor( App.cursorDrag )
1142 }
1143 else
1144 {
1145 SetCursor( App.cursorNoDrag )
1146 }
1147 }
1148 ClientToScreen( .hwnd, point )
1149 //ImageList_DragMove( point.x, point.y )
1150 }
1151 }
1152 case $evmLUp
1153 {
1154 uint dest
1155 TVHITTESTINFO tvht
1156 if .fDrag
1157 {
1158 uint destitem //as TVItem
1159 uint selected as .pSelected->TVItem
1160 uint flg
1161
1162 //tvht.pt.x = em.x
1163 //tvht.pt.y = em.y
1164 //if dest = .WinMsg( $TVM_HITTEST, 0, &tvht)
1165 if destitem = &.HitTest( em.x, em.y, 0 )
1166 {
1167 /* TVITEM item
1168 item.mask = $TVIF_PARAM
1169 item.hItem = dest
1170 .WinMsg( $TVM_GETITEMW, 0, &item )
1171
1172 destitem as item.lParam->TVItem*/
1173 destitem as TVItem
1174 uint previtem as destitem.getprev()->TVItem
1175 if .Selection.Find( destitem ) == -1 &&
1176 ( !&previtem || .Selection.Find( previtem ) == -1 )
1177 {
1178 uint owneritem as destitem
1179 uint root as .Root
1180 do
1181 {
1182 if &owneritem == .pSelected
1183 {
1184 destitem as 0
1185 break
1186 }
1187 owneritem as owneritem.Parent
1188 }
1189 while &owneritem != &root
1190 flg = $TREE_BEFORE
1191 }
1192 else : goto end
1193 }
1194 elif int( em.x ) > 0 && int( em.y ) > 0 && em.x < .clloc.width && em.y < .clloc.height
1195 {
1196 destitem as .Root
1197 flg = $TREE_LAST
1198 //selected.MoveTo( .Root, $TREE_LAST )
1199 }
1200 .Selection.MoveTo( destitem->TVItem, flg )
1201 //ImageList_EndDrag( )
1202 label end
1203 ReleaseCapture()
1204 //.Selected = 0->TVItem
1205 //.Selected = selected
1206 //.fDrag = 0
1207 }
1208 }
1209 }
1210
1211 return this->vCtrl.mMouse( em )
1212 }
1213
1214 method uint vTreeView.wmcapturechange <alias=vTreeView_wmcapturechanged>( winmsg wmsg )
1215 {
1216 if wmsg.lpar != .hwnd && .fDrag
1217 {
1218 SetCursor( App.cursorArrow )
1219 .WinMsg( $TVM_SELECTITEM, $TVGN_DROPHILITE, 0 )
1220 .fDrag = 0
1221 }
1222 return 0
1223 }
1224
1225 method vTreeView.mPreDel <alias=vTreeView_mPreDel>()
1226 {
1227 .DisconnectGt()
1228 .WinMsg( $TVM_SELECTITEM, $TVGN_CARET, 0 )
1229 //this.Root.Del()
1230 this.Clear()
1231 //destroy( this.Root.param )
1232 this->vCtrl.mPreDel()
1233 }
1234 /*Виртуальный метод uint vTreeView.mLangChanged - Изменение текущего языка
1235 */
1236 method uint vTreeView.mLangChanged <alias=vTreeView_mLangChanged>()
1237 {
1238 .iUpdateImgList()
1239 .Root.Update()
1240 this->vCtrl.mLangChanged()
1241 // .Caption = .Caption
1242 return 0
1243 }
1244
1245 method vTreeView.mFocus <alias=vTreeView_mFocus>( evparValUint ev )
1246 {
1247 if *.Selection > 1
1248 {
1249 .Invalidate()
1250 }
1251 this->vCtrl.mFocus( ev )
1252 }
1253
1254
1255 method uint vTreeView.wmMouse <alias=vTreeView_wmMouse>( winmsg wmsg )
1256 {
1257 //if .pShowSelection
1258 {
1259
1260 TVHITTESTINFO tvht
1261 //POINT pt
1262 //uint lpar
1263 uint curitem
1264
1265 //GetCursorPos( pt )
1266 //lpar = ( pt.y << 16 ) | pt.x
1267 //ScreenToClient( .hwnd, pt )
1268 tvht.pt.x = int( ( &wmsg.lpar )->short )
1269 tvht.pt.y = int( ( &wmsg.lpar + 2 )->short )
1270 if curitem = .WinMsg( $TVM_HITTEST, 0, &tvht )
1271 {
1272 if !( tvht.flags & $TVHT_ONITEMBUTTON )
1273 {
1274 .fFromMouse = 1
1275 .WinMsg( $TVM_SELECTITEM, $TVGN_CARET, curitem )
1276 .fFromMouse = 0
1277 }
1278 }
1279 //SetFocus( this.hwnd )
1280 /* LVHITTESTINFO info
1281 info.pt.x = int( ( &wmsg.lpar )->short )
1282 info.pt.y = int( ( &wmsg.lpar + 2 )->short )
1283 if .WinMsg( $LVM_HITTEST, 0, &info ) == -1*/
1284 {
1285 //( &wmsg.lpar )->short = 5
1286 //( &wmsg.lpar + 2 )->short = 5
1287 // wmsg.flags = 1
1288 /*
1289 info.pt.x = 5
1290 if .WinMsg( $LVM_HITTEST, 0, &info ) != -1
1291 {
1292 LVITEM lvi
1293 lvi.mask = $LVIF_STATE
1294 //lvi.iItem = info.iItem
1295 lvi.stateMask = $LVIS_FOCUSED | $LVIS_SELECTED
1296 lvi.state = $LVIS_FOCUSED | $LVIS_SELECTED
1297 .WinMsg( $LVM_SETITEMSTATE, info.iItem, &lvi )
1298 }*/
1299 }
1300 }
1301 return this->vCtrl.wmMouse( wmsg )
1302 }
1303
1304 /*Виртуальный метод vTreeView.mSetName - Установка заголовка в режиме проектирования
1305 */
1306 /*method uint vTreeView.mSetName <alias=vTreeView_mSetName>( str newname )
1307 {
1308 ifdef $DESIGNING {
1309 if !*.Caption || .Caption == .Name
1310 {
1311 .Caption = newname.ustr()
1312 }
1313 }
1314 return 1
1315 }
1316
1317 */
1318 /*------------------------------------------------------------------------------
1319 Registration
1320 */
1321 /*Системный метод vTreeView vTreeView.init - Инициализация объекта
1322 */
1323 method vTreeView vTreeView.init( )
1324 {
1325 this.pTypeId = vTreeView
1326
1327 this.pCanFocus = 1
1328 this.pTabStop = 1
1329 this.loc.width = 100
1330 this.loc.height = 25
1331 this.pBorder = 1
1332 this.pShowPlusMinus = 1
1333 this.pShowLines = 1
1334 this.pShowRootLines = 1
1335 //uint itemdata as new( treedata )->treedata
1336 //itemdata.treeview = &this
1337 //this.gttree.root().param = &itemdata
1338
1339 .Selection.pTreeView = &this
1340 .Reload()
1341 //this.items[0].TreeView = &this
1342 //this.items[0].gti = &this.gti.root()
1343 return this
1344 }
1345
1346 /*ifdef $DESIGNING
1347 {
1348 method vTreeView.mRegProps <alias=vTreeView_mRegProps>( uint typeid, compMan cm )
1349 {
1350 // this->vCtrl.mRegProps( typeid, cm)
1351 }*/
1352 /*
1353 method vTreeView.getevents( uint typeid, compMan cm )
1354 {
1355 this->vCtrl.getevents( typeid, cm)
1356 cm.addevents( typeid, %{
1357 "onclick" , "eventn"
1358 })
1359 }*/
1360
1361 func init_vTreeView <entry>()
1362 {
1363 regcomp( vTreeView, "vTreeView", vCtrl, $vCtrl_last,
1364 %{ %{$mCreateWin, vTreeView_mCreateWin},
1365 %{$mWinNtf, vTreeView_mWinNtf },
1366 %{$mMouse, vTreeView_mMouse },
1367 %{$mPreDel, vTreeView_mPreDel },
1368 %{$mLangChanged, vTreeView_mLangChanged },
1369 %{$mFocus, vTreeView_mFocus }/*,
1370 %{$mSetName, vTreeView_mSetName}*/
1371 },
1372 %{ %{ $WM_CAPTURECHANGED, vTreeView_wmcapturechanged },
1373 %{ $WM_LBUTTONDOWN, vTreeView_wmMouse },
1374 %{ $WM_RBUTTONDOWN, vTreeView_wmMouse }
1375 }
1376 )
1377
1378 ifdef $DESIGNING {
1379 cm.AddComp( vTreeView, 1, "Windows", "treeview" )
1380 cm.AddProps( vTreeView, %{
1381 //"TabOrder", uint, 0,
1382 "Border", uint, 0,
1383 "ShowPlusMinus", uint, 0,
1384 "ShowLines", uint, 0,
1385 "ShowRootLines", uint, 0,
1386 "ShowSelection", uint, 0,
1387 "RowSelect", uint, 0,
1388 "LabelEdit", uint, 0,
1389 "ImageList", ustr, 0,
1390 "StateImageList", ustr, 0,
1391 "AutoDrag", uint, 0,
1392 "MultiSelect", uint, 0
1393 /*"Caption", ustr, 0,
1394 "treeviewStyle", uint, 0,
1395 "Checked", uint, 0*/
1396 })
1397 /*
1398 cm.AddPropVals( vTreeView, "treeviewStyle", %{
1399 "bsClassic", $bsClassic,
1400 "bsAsRadiotreeview", $bsAsRadiotreeview,
1401 "bsAsCheckBox", $bsAsCheckBox
1402 })
1403 */
1404 cm.AddEvents( vTreeView, %{
1405 //"OnBeforeEdit", "eventTVEdit",
1406 "OnAfterEdit", "evparTVEdit",
1407 //"OnBeforeSelect", "",
1408 "OnAfterSelect", "evValUint",
1409 /*,
1410 "OnBeforeExpand", "",
1411 "OnAfterExpand", "",
1412 "OnBeforeCollapse", "",
1413 "OnAfterCollapse", ""*/
1414 "OnBeforeMove", "evparBeforeMove",
1415 "OnAfterMove", "evparAfterMove"
1416
1417 })
1418 }
1419
1420 }
1421