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 {
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 /*uint pImageIndex
33 uint pSelectedImageIndex
34 uint pStateImageIndex*/
35 //ustr pListImgName
36 }
37
38 /*type TVSelections <index=TVItem>
39 {
40 }*/
41
42 type treedata
43 {
44 //uint TreeView
45 uint treeview //Объект содержащий данный элемент
46 uint handle //Идентификатор элемента в окне
47 // uint inselections
48 //uint tag
49 //uint gttree
50 }
51
52 type evparTVEdit <inherit=evparEvent>
53 {
54 ustr NewLabel
55 uint flgCancel
56 }
57
58 type evTVEdit <inherit=evEvent> :
59
60 method evTVEdit evTVEdit.init
61 {
62 this.eventtypeid = evparTVEdit
63 return this
64 }
65
66 type evparTVBefore <inherit=evparEvent>
67 {
68 uint CurItem
69 uint flgCancel
70 }
71
72 type evTVBefore <inherit=evEvent> :
73
74 method evTVBefore evTVBefore.init
75 {
76 this.eventtypeid = evparTVBefore
77 return this
78 }
79
80 type evparTVAfter <inherit=evparEvent>
81 {
82 uint CurItem
83 }
84
85 type evTVAfter <inherit=evEvent> :
86
87 method evTVAfter evTVAfter.init
88 {
89 this.eventtypeid = evparTVAfter
90 return this
91 }
92
93 type evparItemMoved <inherit=evparEvent>
94 {
95 uint SrcItem
96 uint DestItem
97 uint Flag
98 }
99
100 type evItemMoved <inherit=evEvent> :
101 /*{
102 uint CurItem
103 }
104 */
105 method evItemMoved evItemMoved.init
106 {
107 this.eventtypeid = evparItemMoved
108 return this
109 }
110
111 /* Компонента vTreeView, порождена от vCtrl
112 События
113 onClick - вызывается при нажатии на кнопку
114 */
115 type vTreeView <inherit = vCtrl>
116 {
117 //Hidden Fields
118 /*locustr pCaption
119 uint pChecked
120 uint ptreeviewStyle*/
121 uint pShowPlusMinus //Показывать +/-
122 uint pShowLines //Показывать линейки дерева
123 uint pShowRootLines //Показывать корневую линейку
124 uint pShowSelection //Всегда показывать выделение
125 uint pRowSelect //Выделение элемента в виде строки
126 uint pLabelEdit //Возможность редактирования элементов
127 uint pBorder //Показывать рамку
128 uint pSorted //Сортировать элементы
129 uint pSelected //Текущий выбранный элемент
130 uint fDrag //Флаг, находимся в режиме drag'n'drop
131 ustr pImageList
132 uint ptrImageList
133 ustr pStateImageList
134 uint ptrStateImageList
135 uint iNumIml
136 uint iStateNumIml
137 //arr items[1] of TVItem
138 // arr pSelections of uint
139 gt gttree //Представление в виде gt
140 //Events
141 //onevent onStartEdit
142 evTVEdit OnAfterEdit
143 evTVEdit OnBeforeEdit
144 evTVBefore OnBeforeSelect
145 evTVAfter OnAfterSelect
146 evTVBefore OnBeforeExpand
147 evTVAfter OnAfterExpand
148 evTVBefore OnBeforeCollapse
149 evTVAfter OnAfterCollapse
150 evItemMoved OnItemMoved
151 }
152
153 define {
154 //Стили кнопки treeviewStyle
155 bsClassic = 0
156 bsAsRadiotreeview = 3
157 bsAsCheckBox = 4
158 }
159
160 extern {
161 //property uint TVItem.InSelections
162 //property TVItem.InSelections( uint val )
163 property TVItem vTreeView.Selected()
164 property vTreeView.Selected( TVItem item )
165 property ustr TVItem.Label<result>()
166 property TVItem TVItem.Child()
167 property TVItem TVItem.Prev()
168 method TVItem.WinSet( uint mask )
169 property TVItem vTreeView.Root
170 method TVItem.Del()
171
172 }
173
174 include {
175 "treeviewitem.g"
176 }
177
178 /*Метод vToolBar.iUpdateImageList()
179 Обновить ImageList
180 */
181 method vTreeView.iUpdateImgList()
182 {
183 .ptrImageList = &.GetImageList( .pImageList, &.iNumIml )
184 if .ptrImageList
185 {
186 .WinMsg( $TVM_SETIMAGELIST, $TVSIL_NORMAL, .ptrImageList->ImageList.arrIml[.iNumIml].hIml )
187 }
188 else
189 {
190 .WinMsg( $TVM_SETIMAGELIST, $TVSIL_NORMAL, 0 )
191 }
192 .ptrStateImageList = &.GetImageList( .pStateImageList, &.iStateNumIml )
193 if .ptrStateImageList
194 {
195 .WinMsg( $TVM_SETIMAGELIST, $TVSIL_STATE, .ptrStateImageList->ImageList.arrIml[.iNumIml].hIml )
196 }
197 else
198 {
199 .WinMsg( $TVM_SETIMAGELIST, $TVSIL_STATE, 0 )
200 }
201 InvalidateRect( this.hwnd, 0->RECT, 1 )
202 }
203 /*------------------------------------------------------------------------------
204 Public Methods
205 */
206 method vTreeView.Clear()
207 {
208 .Selected = 0->TVItem
209 .Root.Release()
210 .gttree.clear()
211 //.Root.Del()
212 //.WinMsg( $TVM_DELETEITEM, 0, $TVI_ROOT )
213 //.gttree.clear()
214 /*if *.items > 1
215 {
216 .items.del( 1, *.items - 2 )
217 .WinMsg( $TVM_DELETEITEM, 0, $TVI_ROOT )
218 .gti.clear()
219 } */
220 }
221
222 method vTreeView.Edit()
223 {
224 if &(.Selected())
225 {
226 .SetFocus()
227 .WinMsg( $TVM_EDITLABELW, 0, .Selected().param->treedata.handle )
228 }
229 }
230
231
232 method vTreeView.ReloadGTItem( TVItem parent, TVItem item )
233 {
234 if &parent
235 {
236
237 uint itemdata as new( treedata )->treedata
238 itemdata.treeview = &this
239 item.param = &itemdata
240 /*child.set( "name", name.toutf8( "" ) )
241 child.setuint( "tag", tag )*/
242 //print( "add \(&this) \(&child)\n" )
243 //TVINSERTSTRUCT ti
244 //ti.item.pszText = name.ptr()
245 /*uint sorttype = .getuint( "sorttype" )
246 if sorttype & $TVSORT_SORT
247 {
248 //ti.hInsertAfter = $TVI_SORT
249 if sorttype == $TVSORT_SORTRECURSE
250 {
251 child.setuint( "sorttype", sorttype )
252 }
253 }*/
254 parent.iItemInsert( item )
255 }
256 uint children as item.Children
257 if &children
258 {
259 foreach child, children
260 {
261 .ReloadGTItem( item, child->TVItem )
262 }
263 }
264 item.iItemUpdate( $TVIF_STATE | $TVIF_TEXT | $TVIF_SELECTEDIMAGE | $TVIF_IMAGE)
265 }
266
267 method vTreeView.ReloadGT()
268 {
269 .pSelected = 0
270
271 uint root as this.Root
272 root.Release()
273 uint children as root.Children
274 if !&children
275 {
276 children as root.insertchild( "children", 0->gtitem )
277 foreach child, root
278 {
279 if &child != &children
280 {
281 child.move( children, $TREE_LAST )
282 child.gettreeitem().changenode( children.gettreeitem() )
283 }
284 }
285 /*.gttree.write( "tmp.gt" )
286 .gttree.clear()
287 .gttree.read( "tmp.gt" )*/
288 }
289 this.ReloadGTItem( 0->TVItem, root )
290 uint child as root.Child
291 if &child
292 {
293 .Selected = child
294 }
295 }
296
297 /*------------------------------------------------------------------------------
298 Properties
299 */
300 /*Свойство ustr Border - Get Set
301 Установить, получить наличие рамки у поля ввода
302 1 - рамка есть
303 0 - рамки нет
304 */
305 property vTreeView.Border( uint val )
306 {
307 .pBorder = val
308 uint style = GetWindowLong( this.hwnd, $GWL_EXSTYLE )
309 if val : style |= $WS_EX_CLIENTEDGE
310 else : style &= ~$WS_EX_CLIENTEDGE
311 SetWindowLong( this.hwnd, $GWL_EXSTYLE, style )
312 SetWindowPos( this.hwnd, 0, 0, 0, 0, 0, $SWP_FRAMECHANGED |
313 $SWP_NOACTIVATE | $SWP_NOZORDER | $SWP_NOMOVE | $SWP_NOSIZE )
314 }
315
316 property uint vTreeView.Border
317 {
318 //.pBorder = ?(GetWindowLong( this.hwnd, $GWL_EXSTYLE ) & $WS_EX_CLIENTEDGE,1,0)
319 return .pBorder
320 }
321
322 /*Свойство ustr ShowPlusMinus - Get Set
323 Установить, получить отображение кнопочки с крестиком/минусом отображающим
324 открытие ветки
325 1 - кнопка есть
326 0 - кнопок нет
327 */
328 property vTreeView.ShowPlusMinus( uint val )
329 {
330 .pShowPlusMinus = val
331 .SetStyle( $TVS_HASBUTTONS, val )
332 }
333
334 property uint vTreeView.ShowPlusMinus
335 {
336 return .pShowPlusMinus//.GetStyle( $TVS_HASBUTTONS )
337 }
338
339 /*Свойство ustr ShowLines - Get Set
340 Установить, получить отображение линеек слева от веток
341 1 - есть
342 0 - нет
343 */
344 property vTreeView.ShowLines( uint val )
345 {
346 .pShowLines = val
347 .SetStyle( $TVS_HASLINES , val )
348 }
349
350 property uint vTreeView.ShowLines
351 {
352 return .pShowLines//.GetStyle( $TVS_HASLINES )
353 }
354
355 /*Свойство ustr ShowRootLines - Get Set
356 Установить, получить отображение линеек у корневого элемента
357 открытие ветки
358 1 - есть
359 0 - нет
360 */
361 property vTreeView.ShowRootLines( uint val )
362 {
363 .pShowRootLines = val
364 .SetStyle( $TVS_LINESATROOT, val )
365 }
366
367 property uint vTreeView.ShowRootLines
368 {
369 return .pShowRootLines//.GetStyle( $TVS_LINESATROOT )
370 }
371
372 /*Свойство ustr ShowSelection - Get Set
373 Установить, получить отображение линеек слева от веток
374 1 - есть
375 0 - нет
376 */
377 property vTreeView.ShowSelection( uint val )
378 {
379 .pShowSelection = val
380 .SetStyle( $TVS_SHOWSELALWAYS, val )
381 }
382
383 property uint vTreeView.ShowSelection
384 {
385 return .pShowSelection//.GetStyle( $TVS_HASLINES )
386 }
387
388 /*Свойство ustr RowSelect - Get Set
389 Установить, получить отображение линеек слева от веток
390 1 - есть
391 0 - нет
392 */
393 property vTreeView.RowSelect( uint val )
394 {
395 .pRowSelect = val
396 .SetStyle( $TVS_FULLROWSELECT , val )
397 }
398
399 property uint vTreeView.RowSelect
400 {
401 return .pRowSelect//.GetStyle( $TVS_HASLINES )
402 }
403
404 /*Свойство ustr LabelEdit - Get Set
405 Установить, получить отображение линеек слева от веток
406 1 - есть
407 0 - нет
408 */
409 property vTreeView.LabelEdit( uint val )
410 {
411 .pLabelEdit = val
412 .SetStyle( $TVS_EDITLABELS , val )
413 }
414
415 property uint vTreeView.LabelEdit
416 {
417 return .pLabelEdit//.GetStyle( $TVS_HASLINES )
418 }
419
420 /* Свойство str vTreeView.ImageList - Get Set
421 Устанавливает или получает имя списка картинок
422 */
423 property ustr vTreeView.ImageList <result>
424 {
425 result = this.pImageList
426 }
427
428 property vTreeView.ImageList( ustr val )
429 {
430 if val != this.pImageList
431 {
432 this.pImageList = val
433 .Virtual( $mLangChanged )
434 //.iUpdateImageList()
435 }
436 }
437
438 /* Свойство str vTreeView.StateImgListName - Get Set
439 Устанавливает или получает имя списка картинок состояний
440 */
441 property ustr vTreeView.StateImageList <result>
442 {
443 result = this.pStateImageList
444 }
445
446 property vTreeView.StateImageList( ustr val )
447 {
448 if val != this.pStateImageList
449 {
450 this.pStateImageList = val
451 .Virtual( $mLangChanged )
452 //.iUpdateImageList()
453 }
454 }
455
456 /*property TVSelections vTreeView.Selections
457 {
458 return this->TVSelections
459 }
460
461
462
463 method TVItem TVSelections.index( uint idx )
464 {
465 uint tv as this->vTreeView
466 if idx < *tv.pSelections
467 {
468 return tv.pSelections[idx]->TVItem
469 }
470 return 0->TVItem
471 }
472
473 operator uint * ( TVSelections sel )
474 {
475 return *sel->vTreeView.pSelections
476 }
477
478 method TVSelections.Clear()
479 {
480 uint tv as this->vTreeView
481 while *tv.pSelections
482 {
483 tv.pSelections[0]->TVItem.InSelections = 0
484 }
485 }*/
486 /*method TVItem.Index( uint 0 )
487 {
488
489 }*/
490
491
492 property TVItem vTreeView.Root
493 {
494 if &this
495 {
496 return .gttree.root()->TVItem//.items[0]
497 }
498 return 0->TVItem
499 }
500
501
502
503 /* Свойство uint Sorted - Get Set
504 Устанавливает или определяет должны ли сортироваться элементы в дереве
505 1 - элементы сортируются
506 0 - элементы не сортируются
507 */
508 property uint vTreeView.Sorted()
509 {
510 return this.pSorted
511 }
512
513 property vTreeView.Sorted( uint val)
514 {
515 if this.pSorted != val
516 {
517 this.pSorted = val
518 this.Root().SortType = ?( val, $TVSORT_SORTRECURSE, $TVSORT_NONE )
519
520 }
521 }
522
523 property TVItem vTreeView.Selected()
524 {
525 //print( "Get Selected \(this.pSelected)\n" )
526 return this.pSelected->TVItem
527 }
528
529 property vTreeView.Selected( TVItem item )
530 {
531 //print( "Selected x \(&item)\n" )
532 if this.pSelected != &item
533 {
534 uint destitem = &item
535 if destitem == &this.Root : destitem = 0
536 this.pSelected = destitem
537 //print( "Selected x \(destitem)\n" )
538 .WinMsg( $TVM_SELECTITEM, $TVGN_CARET, ?( destitem, destitem->TVItem.param->treedata.handle, 0) )
539 }
540 }
541
542 /* Свойство uint InSelections - Get Set
543 Устанавливает или определяет находится ли элемент в числе выбранных
544 */
545 /*property uint TVItem.InSelections
546 {
547 return .param->treedata.inselections
548 }
549
550 property TVItem.InSelections( uint val )
551 {
552 print( "inselections \(val)\n" )
553 if val != .param->treedata.inselections
554 {
555 .param->treedata.inselections = val
556 uint sels as .param->treedata.treeview->vTreeView.pSelections
557 print( "10\n" )
558 if val
559 {
560 print( "20\n" )
561 sels[sels.expand( 1 )] = &this
562 print( "30\n" )
563 }
564 else
565 {
566 uint i
567 fornum i = 0, *sels
568 {
569 if sels[i] == &this
570 {
571 sels.del(i)
572 break;
573 }
574 }
575 }
576 print( "40\n" )
577 .WinSet( $TVIF_STATE )
578 print( "50\n" )
579 }
580 }
581 */
582
583 /* Свойство uint treeviewStyle - Get Set
584 Усотанавливает или определяет стиль кнопки
585 Возможны следующие варианты:
586 bsClassic - обычный вид,
587 bsAsRadiotreeview - работает как Radiotreeview,
588 bsAsCheckBox - работает как CheckBox
589 */
590 /*property uint vTreeView.treeviewStyle()
591 {
592 return this.ptreeviewStyle
593 }
594
595 property vTreeView.treeviewStyle( uint val)
596 {
597 if this.ptreeviewStyle != val
598 {
599 uint checked = this.Checked
600 uint remstyle = $BS_AUTORADIOBUTTON | $BS_AUTOCHECKBOX | $BS_PUSHLIKE
601 uint addstyle
602 this.WinMsg( $BM_SETCHECK, 0 )
603 this.pChecked = 0
604 if val == $bsAsRadiotreeview
605 {
606 addstyle = $BS_AUTORADIOBUTTON | $BS_PUSHLIKE
607 }
608 elif val == $bsAsCheckBox
609 {
610 addstyle = $BS_AUTOCHECKBOX | $BS_PUSHLIKE
611 }
612 this.ChangeStyle( addstyle, remstyle )
613 this.ptreeviewStyle = val
614 this.Checked = checked
615 }
616 }
617 */
618 /* Свойство uint Caption - Get Set
619 Усотанавливает или определяет заголовок кнопки
620 */
621 /*property ustr vTreeView.Caption <result>
622 {
623 result = this.pCaption.Value
624 }
625
626 property vTreeView.Caption( ustr val )
627 {
628 this.pCaption.Value = val
629 SetWindowText( this.hwnd, this.pCaption.Text.ptr() )
630 }
631
632
633 */
634 /*------------------------------------------------------------------------------
635 Virtual Methods
636 */
637 /*Виртуальный метод vTreeView vTreeView.mCreateWin - Создание окна
638 */
639 method vTreeView vTreeView.mCreateWin <alias=vTreeView_mCreateWin>()
640 {
641 uint exstyle
642 uint style = $WS_CHILD | $WS_VISIBLE | $WS_CLIPSIBLINGS
643 if .pShowPlusMinus : style |= $TVS_HASBUTTONS
644 if .pShowLines : style |= $TVS_HASLINES
645 if .pShowRootLines : style |= $TVS_LINESATROOT
646 if .pShowSelection : style |= $TVS_SHOWSELALWAYS
647 if .pRowSelect : style |= $TVS_FULLROWSELECT
648 if .pLabelEdit : style |= $TVS_EDITLABELS
649
650 if .pBorder : exstyle |= $WS_EX_CLIENTEDGE
651 this.CreateWin( "SysTreeView32".ustr(), exstyle, style )
652 this->vCtrl.mCreateWin()
653 this.WinMsg( $WM_SETFONT, GetStockObject( $DEFAULT_GUI_FONT ) )
654
655 //uint himl = ImageList_Create(16, 16, 0xFE, 1, 0)
656 //uint hbitmap = LoadBitmap( 0, 32754 )//"OBM_CHECKBOXES".ustr().ptr() )
657 //print( "hbitmap = \(hbitmap )\n" )
658 //ImageList_Add( himl,hbitmap,0)
659 //DeleteObject( hbitmap )
660 //hbitmap = LoadBitmap( 0, 32759 )//"OBM_CHECKBOXES".ustr().ptr() )
661 //print( "hbitmap = \(hbitmap )\n" )
662 //ImageList_Add( himl,hbitmap,0)
663 //DeleteObject( hbitmap )
664 //.WinMsg( $TVM_SETINDENT, -20 )
665 // .WinMsg( $TVM_SETIMAGELIST, 0, himl );
666
667 return this
668 }
669
670 /*Виртуальный метод uint vTreeView.mWinNtf - обработка сообщений
671 */
672 method uint vTreeView.mWinNtf <alias=vTreeView_mWinNtf>( NMHDR ntf )
673 {
674 uint nmtv as ntf->NMTREEVIEWW
675 switch ntf.code
676 {
677 case $NM_RCLICK
678 {
679 TVHITTESTINFO tvht
680 POINT pt
681 uint lpar
682 uint curitem
683
684 GetCursorPos( pt )
685 lpar = ( pt.y << 16 ) | pt.x
686 ScreenToClient( .hwnd, pt )
687 tvht.pt = pt
688 if curitem = .WinMsg( $TVM_HITTEST, 0, &tvht )
689 {
690 .WinMsg( $TVM_SELECTITEM, $TVGN_CARET, curitem )
691 }
692 .WinMsg( $WM_CONTEXTMENU, this.hwnd, lpar )
693 }
694 case $TVN_GETDISPINFOW
695 {
696 uint nd as ntf->NMTVDISPINFO
697 if nd.item.mask & $TVIF_IMAGE
698 {
699 nd.item.iImage = -1
700 }
701 if nd.item.mask & $TVIF_SELECTEDIMAGE
702 {
703 nd.item.iSelectedImage = -1
704 }
705 return 0
706 }
707 case $TVN_SELCHANGEDW
708 {
709 //print( "Selchanged\n" )
710 this.pSelected = ?( nmtv.itemNew.hItem, nmtv.itemNew.lParam, 0 )
711
712 evparTVAfter etva
713 etva.CurItem = this.pSelected
714 //print( "selchange \( this.pSelected ) \(etva.CurItem)\n" )
715 etva.sender = &this
716 .OnAfterSelect.Run( /*this,*/ etva )
717 /*uint nmtv as ntf->NMTREEVIEWW
718 if nmtv.itemOld.lParam
719 {
720 nmtv.itemOld.lParam->TVItem.InSelections = !nmtv.itemOld.lParam->TVItem.InSelections
721 }*/
722 }
723 case $TVN_SELCHANGINGW
724 {
725 evparTVBefore etvb
726 etvb.CurItem = ?( nmtv.itemNew, nmtv.itemNew.lParam, 0 )
727 etvb.sender = &this
728 .OnBeforeSelect.Run( /*this,*/ etvb )
729 return etvb.flgCancel
730 }
731 case $TVN_ITEMEXPANDEDW
732 {
733 //print( "Expanded \(&this) \(&ntf)\n" )
734 if nmtv.action & ( $TVE_COLLAPSE | $TVE_EXPAND )
735 {
736 nmtv.itemNew.lParam->TVItem.setuint( "expanded", nmtv.action & $TVE_EXPAND )
737
738 }
739 /*foreach it, this.Root()
740 {
741 .Selected = it
742 break;
743 }*/
744
745 }
746 case $TVN_ITEMEXPANDINGW
747 {
748 //print( "Expanding\n" )
749 }
750 case $TVN_BEGINLABELEDITW
751 {
752 evparTVEdit etve
753 etve.sender = &this
754 .OnBeforeEdit.Run( /*this,*/ etve )
755 return etve.flgCancel
756 }
757 case $TVN_ENDLABELEDITW
758 {
759 nmtv as NMTVDISPINFO
760
761 evparTVEdit etve
762 //print( "len = \(nmtv.item.cchTextMax )\n" )
763 if nmtv.item.pszText
764 {
765 etve.NewLabel.copy( nmtv.item.pszText )
766 }
767 else
768 {
769 etve.flgCancel = 1
770 }
771 //print( "["+etve.NewLabel.str()+ "] \(nmtv.item.pszText) \(etve.flgCancel )\n" )
772 etve.sender = &this
773 .OnAfterEdit.Run( /*this,*/ etve )
774 if !etve.flgCancel
775 {
776 uint selected as .Selected
777 if &selected
778 {
779
780 selected.set( "name", etve.NewLabel.toutf8( "" ) )
781 }
782 return 1
783 }
784 }
785 case $TVN_BEGINDRAGW
786 {
787 .Selected = nmtv.itemNew.lParam->TVItem
788 //RECT rect
789 //(&rect)->uint = nmtv.itemNew.hItem
790 //.WinMsg( $TVM_GETITEMRECT, 1, &rect )
791 //uint hdc = GetDC( .hwnd )
792
793 SetCapture( .hwnd )
794 .fDrag = 1
795 }
796 case $TVN_DELETEITEMW
797 {
798 //print( "DEL\n" )
799 }
800 }
801 return 0
802 }
803
804 method uint vTreeView.mMouse <alias=vTreeView_mMouse>( evparMouse em )
805 {
806 switch em.evmtype
807 {
808 case $evmMove
809 {
810 if .fDrag
811 {
812 POINT point
813 uint destitem
814 TVHITTESTINFO tvht
815
816 tvht.pt.x = point.x = em.x
817 tvht.pt.y = point.y = em.y
818 if destitem = .WinMsg( $TVM_HITTEST, 0, &tvht)
819 {
820 .WinMsg( $TVM_SELECTITEM, $TVGN_DROPHILITE, destitem )
821 //.WinMsg( $TVM_EXPAND, $TVE_EXPAND, destitem )
822 SetCursor( App.cursorDrag )
823 }
824 else
825 {
826 if int( em.x ) > 0 && int( em.y ) > 0 && em.x < .clloc.width && em.y < .clloc.height
827 {
828 SetCursor( App.cursorDrag )
829 }
830 else
831 {
832 SetCursor( App.cursorNoDrag )
833 }
834 }
835 ClientToScreen( .hwnd, point )
836 //ImageList_DragMove( point.x, point.y )
837 }
838 }
839 case $evmLUp
840 {
841 uint dest
842 TVHITTESTINFO tvht
843 if .fDrag
844 {
845 uint destitem as TVItem
846 uint selected as .pSelected->TVItem
847
848 tvht.pt.x = em.x
849 tvht.pt.y = em.y
850 if dest = .WinMsg( $TVM_HITTEST, 0, &tvht)
851 {
852 TVITEM item
853 item.mask = $TVIF_PARAM
854 item.hItem = dest
855 .WinMsg( $TVM_GETITEMW, 0, &item )
856
857 destitem as item.lParam->TVItem
858 uint owneritem as destitem
859 uint root as .Root
860 do
861 {
862 if &owneritem == .pSelected
863 {
864 destitem as 0
865 break
866 }
867 owneritem as owneritem.Parent
868 }
869 while &owneritem != &root
870 if &destitem
871 {
872 selected.MoveTo( destitem, $TREE_BEFORE )
873 }
874
875 //.WinMsg( $TVM_SELECTITEM, $TVGN_DROPHILITE, destitem )
876 }
877 elif int( em.x ) > 0 && int( em.y ) > 0 && em.x < .clloc.width && em.y < .clloc.height
878 {
879 selected.MoveTo( .Root, $TREE_LAST )
880 }
881 //ImageList_EndDrag( )
882 ReleaseCapture()
883 .Selected = selected
884 //.fDrag = 0
885 }
886 }
887 }
888 return this->vCtrl.mMouse( em )
889 }
890
891 method uint vTreeView.wmcapturechange <alias=vTreeView_wmcapturechanged>( winmsg wmsg )
892 {
893 if wmsg.lpar != .hwnd && .fDrag
894 {
895 SetCursor( App.cursorArrow )
896 .WinMsg( $TVM_SELECTITEM, $TVGN_DROPHILITE, 0 )
897 .fDrag = 0
898 }
899 return 0
900 }
901
902 method vTreeView.mPreDel <alias=vTreeView_mPreDel>()
903 {
904 .WinMsg( $TVM_SELECTITEM, $TVGN_CARET, 0 )
905 //this.Root.Del()
906 this.Clear()
907 destroy( this.Root.param )
908 this->vCtrl.mPreDel()
909 }
910 /*Виртуальный метод uint vTreeView.mLangChanged - Изменение текущего языка
911 */
912 method uint vTreeView.mLangChanged <alias=vTreeView_mLangChanged>()
913 {
914 .iUpdateImgList()
915 .Root.Update()
916 this->vCtrl.mLangChanged()
917 // .Caption = .Caption
918 return 0
919 }
920
921 /*Виртуальный метод vTreeView.mSetName - Установка заголовка в режиме проектирования
922 */
923 /*method uint vTreeView.mSetName <alias=vTreeView_mSetName>( str newname )
924 {
925 ifdef $DESIGNING {
926 if !*.Caption || .Caption == .Name
927 {
928 .Caption = newname.ustr()
929 }
930 }
931 return 1
932 }
933
934 */
935 /*------------------------------------------------------------------------------
936 Registration
937 */
938 /*Системный метод vTreeView vTreeView.init - Инициализация объекта
939 */
940 method vTreeView vTreeView.init( )
941 {
942 this.pTypeId = vTreeView
943
944 this.pCanFocus = 1
945 this.pTabStop = 1
946 this.loc.width = 100
947 this.loc.height = 25
948 this.pBorder = 1
949 this.pShowPlusMinus = 1
950 this.pShowLines = 1
951 this.pShowRootLines = 1
952 uint itemdata as new( treedata )->treedata
953 itemdata.treeview = &this
954 this.gttree.root().param = &itemdata
955
956
957 //this.items[0].TreeView = &this
958 //this.items[0].gti = &this.gti.root()
959 return this
960 }
961
962 /*ifdef $DESIGNING
963 {
964 method vTreeView.mRegProps <alias=vTreeView_mRegProps>( uint typeid, compMan cm )
965 {
966 // this->vCtrl.mRegProps( typeid, cm)
967 }*/
968 /*
969 method vTreeView.getevents( uint typeid, compMan cm )
970 {
971 this->vCtrl.getevents( typeid, cm)
972 cm.addevents( typeid, %{
973 "onclick" , "eventn"
974 })
975 }*/
976
977 func init_vTreeView <entry>()
978 {
979 regcomp( vTreeView, "vTreeView", vCtrl, $vCtrl_last,
980 %{ %{$mCreateWin, vTreeView_mCreateWin},
981 %{$mWinNtf, vTreeView_mWinNtf },
982 %{$mMouse, vTreeView_mMouse },
983 %{$mPreDel, vTreeView_mPreDel },
984 %{$mLangChanged, vTreeView_mLangChanged }/*,
985 %{$mSetName, vTreeView_mSetName}*/
986 },
987 %{ %{ $WM_CAPTURECHANGED, vTreeView_wmcapturechanged }
988 }
989 )
990
991 ifdef $DESIGNING {
992 cm.AddComp( vTreeView, 1, "Windows", "treeview" )
993
994 cm.AddProps( vTreeView, %{
995 "TabOrder", uint, 0,
996 "Border", uint, 0,
997 "ShowPlusMinus", uint, 0,
998 "ShowLines", uint, 0,
999 "ShowRootLines", uint, 0,
1000 "ShowSelection", uint, 0,
1001 "RowSelect", uint, 0,
1002 "LabelEdit", uint, 0,
1003 "ImageList", ustr, 0,
1004 "StateImageList", ustr, 0
1005 /*"Caption", ustr, 0,
1006 "treeviewStyle", uint, 0,
1007 "Checked", uint, 0*/
1008 })
1009 /*
1010 cm.AddPropVals( vTreeView, "treeviewStyle", %{
1011 "bsClassic", $bsClassic,
1012 "bsAsRadiotreeview", $bsAsRadiotreeview,
1013 "bsAsCheckBox", $bsAsCheckBox
1014 })
1015 */
1016 cm.AddEvents( vTreeView, %{
1017 //"OnBeforeEdit", "eventTVEdit",
1018 "OnAfterEdit", "eventTVEdit",
1019 //"OnBeforeSelect", "",
1020 "OnAfterSelect", "evparTVAfter"/*,
1021 "OnBeforeExpand", "",
1022 "OnAfterExpand", "",
1023 "OnBeforeCollapse", "",
1024 "OnAfterCollapse", ""*/
1025
1026 })
1027 }
1028
1029 }