Back to unsigned int count in wxTreeCtrl.
[wxWidgets.git] / src / os2 / treectrl.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: src/msw/treectrl.cpp
3 // Purpose: wxTreeCtrl
4 // Author: Julian Smart
5 // Modified by: Vadim Zeitlin to be less MSW-specific on 10.10.98
6 // Created: 1997
7 // RCS-ID: $Id$
8 // Copyright: (c) Julian Smart
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
11
12 // ============================================================================
13 // declarations
14 // ============================================================================
15
16 // ----------------------------------------------------------------------------
17 // headers
18 // ----------------------------------------------------------------------------
19
20 // For compilers that support precompilation, includes "wx.h".
21 #include "wx/wxprec.h"
22
23 #ifdef __BORLANDC__
24 #pragma hdrstop
25 #endif
26
27 #if wxUSE_TREECTRL
28
29 #include "wx/os2/private.h"
30
31 #include "wx/app.h"
32 #include "wx/log.h"
33 #include "wx/dynarray.h"
34 #include "wx/imaglist.h"
35 #include "wx/settings.h"
36 #include "wx/os2/treectrl.h"
37
38 // a macro to hide the ugliness of nested casts
39 #define HITEM(item) (HTREEITEM)(WXHTREEITEM)(item)
40
41 // the native control doesn't support multiple selections under MSW and we
42 // have 2 ways to emulate them: either using TVS_CHECKBOXES style and let
43 // checkboxes be the selection status (checked == selected) or by really
44 // emulating everything, i.e. intercepting mouse and key events &c. The first
45 // approach is much easier but doesn't work with comctl32.dll < 4.71 and also
46 // looks quite ugly.
47 #define wxUSE_CHECKBOXES_IN_MULTI_SEL_TREE 0
48
49 // ----------------------------------------------------------------------------
50 // private functions
51 // ----------------------------------------------------------------------------
52
53 // ----------------------------------------------------------------------------
54 // private classes
55 // ----------------------------------------------------------------------------
56
57 typedef struct _MYRECORD
58 {
59 RECORDCORE m_vRecord;
60 ULONG m_ulItemId;
61 ULONG m_ulUserData;
62 } MYRECORD, *PMYRECORD;
63
64 struct wxTreeViewItem : public MYRECORD
65 {
66 wxTreeViewItem(const wxTreeItemId& rItem)
67 {
68 m_ulItemId = (ULONG)rItem.m_pItem;
69 }
70 }; // end of STRUCT wxTreeViewItem
71
72 class wxTreeItemInternalData
73 {
74 public:
75
76 wxTreeItemInternalData() {}
77 ~wxTreeItemInternalData()
78 {
79 if(m_pAttr)
80 {
81 delete m_pAttr;
82 m_pAttr = NULL;
83 }
84 }
85
86 wxTreeItemAttr* m_pAttr;
87 WXLPARAM m_lParam; // user data
88 #if defined(C_CM_COS232)
89 PMYRECORD m_pMyRecord; // so we can set the m_ulUserData to 0 when this is deleted
90 #endif
91 }; // end of CLASS wxTreeItemInternalData
92
93 void BumpTreeRecordIds (
94 HWND hWnd
95 , PMYRECORD pRecord
96 )
97 {
98 while(pRecord)
99 {
100 pRecord = (PMYRECORD)PVOIDFROMMR(::WinSendMsg( hWnd
101 ,CM_QUERYRECORD
102 ,MPFROMP(pRecord)
103 ,MPFROM2SHORT(CMA_NEXT, CMA_ITEMORDER)
104 ));
105 if (pRecord)
106 pRecord->m_ulItemId++;
107 }
108 } // end of BumpTreeRecordIds
109
110 PMYRECORD FindOS2TreeRecordByID (
111 HWND hWnd
112 , long lItemId
113 )
114 {
115 PMYRECORD pRecord = NULL;
116 CNRINFO vCnrInfo;
117 unsigned long i;
118
119 if (!::WinSendMsg( hWnd
120 ,CM_QUERYCNRINFO
121 ,MPFROMP(&vCnrInfo)
122 ,(MPARAM)(USHORT)sizeof(CNRINFO)
123 ))
124 return NULL;
125 for (i = 0; i < vCnrInfo.cRecords; i++)
126 {
127 if (i == 0)
128 pRecord = (PMYRECORD)PVOIDFROMMR(::WinSendMsg( hWnd
129 ,CM_QUERYRECORD
130 ,MPFROMP(pRecord)
131 ,MPFROM2SHORT(CMA_FIRST, CMA_ITEMORDER)
132 ));
133 else
134 pRecord = (PMYRECORD)PVOIDFROMMR(::WinSendMsg( hWnd
135 ,CM_QUERYRECORD
136 ,MPFROMP(pRecord)
137 ,MPFROM2SHORT(CMA_NEXT, CMA_ITEMORDER)
138 ));
139 if (!pRecord)
140 return NULL;
141 if (pRecord->m_ulItemId == (ULONG)lItemId)
142 break;
143 }
144 return pRecord;
145 } // end of FindOS2ListRecordByID
146
147
148
149 class wxTreeTraversal
150 {
151 public:
152 wxTreeTraversal(const wxTreeCtrl* pTree)
153 {
154 m_pTree = pTree;
155 }
156
157 //
158 // Do traverse the tree: visit all items (recursively by default) under the
159 // given one; return true if all items were traversed or false if the
160 // traversal was aborted because OnVisit returned false
161 //
162 bool DoTraverse( const wxTreeItemId& rRoot
163 ,bool bRecursively = true
164 );
165
166 //
167 // Override this function to do whatever is needed for each item, return
168 // false to stop traversing
169 //
170 virtual bool OnVisit(const wxTreeItemId& rItem) = 0;
171
172 protected:
173 const wxTreeCtrl* GetTree(void) const { return m_pTree; }
174
175 private:
176 bool Traverse( const wxTreeItemId& rRoot
177 ,bool bRecursively
178 );
179
180 const wxTreeCtrl* m_pTree;
181 DECLARE_NO_COPY_CLASS(wxTreeTraversal)
182 }; // end of CLASS wxTreeTraversal
183
184 //
185 // Internal class for getting the selected items
186 //
187 class TraverseSelections : public wxTreeTraversal
188 {
189 public:
190 TraverseSelections( const wxTreeCtrl* pTree
191 ,wxArrayTreeItemIds& raSelections
192 )
193 : wxTreeTraversal(pTree)
194 , m_aSelections(raSelections)
195 {
196 m_aSelections.Empty();
197 DoTraverse(pTree->GetRootItem());
198 }
199
200 virtual bool OnVisit(const wxTreeItemId& rItem)
201 {
202 //
203 // Can't visit a virtual node.
204 //
205 if ((GetTree()->GetRootItem() == rItem) && (GetTree()->GetWindowStyle() & wxTR_HIDE_ROOT))
206 {
207 return true;
208 }
209 PMYRECORD pRecord = FindOS2TreeRecordByID( (HWND)GetTree()->GetHWND()
210 ,rItem.m_pItem
211 );
212 if (pRecord->m_vRecord.flRecordAttr & CRA_SELECTED)
213 {
214 m_aSelections.Add(rItem);
215 }
216 return true;
217 }
218
219 size_t GetCount(void) const { return m_aSelections.GetCount(); }
220
221 private:
222 wxArrayTreeItemIds& m_aSelections;
223 }; // end of CLASS TraverseSelections
224
225 //
226 // Internal class for counting tree items
227 //
228 class TraverseCounter : public wxTreeTraversal
229 {
230 public:
231 TraverseCounter( const wxTreeCtrl* pTree
232 ,const wxTreeItemId& rRoot
233 ,bool bRecursively
234 )
235 : wxTreeTraversal(pTree)
236 {
237 m_nCount = 0;
238 DoTraverse(rRoot, bRecursively);
239 }
240
241 virtual bool OnVisit(const wxTreeItemId& WXUNUSED(rItem))
242 {
243 m_nCount++;
244 return true;
245 }
246
247 size_t GetCount(void) const { return m_nCount; }
248
249 private:
250 size_t m_nCount;
251 }; // end of CLASS TraverseCounter
252
253 // ----------------------------------------------------------------------------
254 // wxWin macros
255 // ----------------------------------------------------------------------------
256
257 IMPLEMENT_DYNAMIC_CLASS(wxTreeCtrl, wxControl)
258
259 // ----------------------------------------------------------------------------
260 // constants
261 // ----------------------------------------------------------------------------
262
263 // indices in gs_expandEvents table below
264 enum
265 {
266 IDX_COLLAPSE,
267 IDX_EXPAND,
268 IDX_WHAT_MAX
269 };
270
271 enum
272 {
273 IDX_DONE,
274 IDX_DOING,
275 IDX_HOW_MAX
276 };
277
278 // handy table for sending events - it has to be initialized during run-time
279 // now so can't be const any more
280 static /* const */ wxEventType gs_expandEvents[IDX_WHAT_MAX][IDX_HOW_MAX];
281
282 /*
283 but logically it's a const table with the following entries:
284 =
285 {
286 { wxEVT_COMMAND_TREE_ITEM_COLLAPSED, wxEVT_COMMAND_TREE_ITEM_COLLAPSING },
287 { wxEVT_COMMAND_TREE_ITEM_EXPANDED, wxEVT_COMMAND_TREE_ITEM_EXPANDING }
288 };
289 */
290
291 // ============================================================================
292 // implementation
293 // ============================================================================
294
295 // ----------------------------------------------------------------------------
296 // tree traversal
297 // ----------------------------------------------------------------------------
298
299 bool wxTreeTraversal::DoTraverse (
300 const wxTreeItemId& rRoot
301 , bool bRecursively
302 )
303 {
304 if (!OnVisit(rRoot))
305 return false;
306
307 return Traverse( rRoot
308 ,bRecursively
309 );
310 } // end of wxTreeTraversal::DoTraverse
311
312 bool wxTreeTraversal::Traverse (
313 const wxTreeItemId& rRoot
314 , bool bRecursively
315 )
316 {
317 long lCookie;
318 wxTreeItemId vChild = m_pTree->GetFirstChild( rRoot
319 ,lCookie
320 );
321 while (vChild.IsOk())
322 {
323 //
324 // Depth first traversal
325 //
326 if (bRecursively && !Traverse(vChild, true))
327 return false;
328 if (!OnVisit(vChild))
329 return false;
330 vChild = m_pTree->GetNextChild( rRoot
331 ,lCookie
332 );
333 }
334 return true;
335 } // end of wxTreeTraversal::Traverse
336
337 // ----------------------------------------------------------------------------
338 // construction and destruction
339 // ----------------------------------------------------------------------------
340
341 void wxTreeCtrl::Init ()
342 {
343 m_pImageListNormal = NULL;
344 m_pImageListState = NULL;
345 m_bOwnsImageListNormal = false;
346 m_bOwnsImageListState = false;
347 m_bHasAnyAttr = false;
348 m_pDragImage = NULL;
349
350 //
351 // Initialize the global array of events now as it can't be done statically
352 // with the wxEVT_XXX values being allocated during run-time only
353 //
354 gs_expandEvents[IDX_COLLAPSE][IDX_DONE] = wxEVT_COMMAND_TREE_ITEM_COLLAPSED;
355 gs_expandEvents[IDX_COLLAPSE][IDX_DOING] = wxEVT_COMMAND_TREE_ITEM_COLLAPSING;
356 gs_expandEvents[IDX_EXPAND][IDX_DONE] = wxEVT_COMMAND_TREE_ITEM_EXPANDED;
357 gs_expandEvents[IDX_EXPAND][IDX_DOING] = wxEVT_COMMAND_TREE_ITEM_EXPANDING;
358 } // end of wxTreeCtrl::Init
359
360 bool wxTreeCtrl::Create (
361 wxWindow* pParent
362 , wxWindowID vId
363 , const wxPoint& rPos
364 , const wxSize& rSize
365 , long lStyle
366 , const wxValidator& rValidator
367 , const wxString& rsName
368 )
369 {
370 CNRINFO vCnrInfo;
371
372 Init();
373 if (!CreateControl( pParent
374 ,vId
375 ,rPos
376 ,rSize
377 ,lStyle
378 ,rValidator
379 ,rsName
380 ))
381 return false;
382
383 DWORD dwStyle = WS_VISIBLE | WS_TABSTOP;
384
385 if (m_windowStyle & wxCLIP_SIBLINGS)
386 dwStyle |= WS_CLIPSIBLINGS;
387
388 // Create the tree control.
389 if (!OS2CreateControl( "CONTAINER"
390 ,dwStyle
391 ))
392 return false;
393
394 //
395 // Now set the display attributes to show a TREE/ICON view of the
396 // OS/2 Container
397 //
398 if (!::WinSendMsg( GetHWND()
399 ,CM_QUERYCNRINFO
400 ,MPFROMP(&vCnrInfo)
401 ,(MPARAM)(USHORT)sizeof(CNRINFO)
402 ))
403
404 vCnrInfo.flWindowAttr = CV_TREE|CV_ICON;
405 vCnrInfo.flWindowAttr |= CA_DRAWBITMAP;
406 if (m_windowStyle & wxTR_NO_LINES)
407 vCnrInfo.flWindowAttr |= CA_TREELINE;
408
409 ::WinSendMsg( GetHWND()
410 ,CM_SETCNRINFO
411 ,MPFROMP(&vCnrInfo)
412 ,(MPARAM)CMA_FLWINDOWATTR
413 );
414
415 SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW));
416 SetForegroundColour(wxWindow::GetParent()->GetForegroundColour());
417 SetFont(*wxSMALL_FONT);
418 SetXComp(0);
419 SetYComp(0);
420 SetSize( rPos.x
421 ,rPos.y
422 ,rSize.x
423 ,rSize.y
424 );
425 return true;
426 } // end of wxTreeCtrl::Create
427
428 wxTreeCtrl::~wxTreeCtrl ()
429 {
430 //
431 // Delete any attributes
432 //
433 if (m_bHasAnyAttr)
434 {
435 for (wxNode* pNode = m_vAttrs.Next(); pNode; pNode = m_vAttrs.Next())
436 {
437 delete (wxTreeItemAttr *)pNode->Data();
438 }
439 m_bHasAnyAttr = false;
440 }
441 DeleteTextCtrl();
442
443 //
444 // Delete user data to prevent memory leaks
445 // also deletes hidden root node storage.
446 //
447 DeleteAllItems();
448 if (m_bOwnsImageListNormal)
449 delete m_pImageListNormal;
450 if (m_bOwnsImageListState)
451 delete m_pImageListState;
452 } // end of wxTreeCtrl::~wxTreeCtrl
453
454 // ----------------------------------------------------------------------------
455 // accessors
456 // ----------------------------------------------------------------------------
457
458 //
459 // simple wrappers which add error checking in debug mode. These methods
460 // assume the items are properly filled out already. If not, you get errors
461 //
462 bool wxTreeCtrl::DoGetItem (
463 wxTreeViewItem* pTvItem
464 ) const
465 {
466 PMYRECORD pRecord = FindOS2TreeRecordByID( GetHWND()
467 ,pTvItem->m_ulItemId
468 );
469
470 if (!pRecord)
471 {
472 wxLogLastError(wxT("Item not obtained"));
473 return false;
474 }
475 return true;
476 } // end of wxTreeCtrl::DoGetItem
477
478 void wxTreeCtrl::DoSetItem (
479 wxTreeViewItem* pTvItem
480 )
481 {
482 //
483 // Just invalidate the record to redisplay it
484 //
485 if (!::WinSendMsg( GetHWND()
486 ,CM_INVALIDATERECORD
487 ,MPFROMP(pTvItem)
488 ,MPFROM2SHORT(1, CMA_ERASE | CMA_REPOSITION | CMA_TEXTCHANGED)
489 ));
490 {
491 wxLogLastError(wxT("CM_INVALIDATERECORD"));
492 }
493 } // end of wxTreeCtrl::DoSetItem
494
495 unsigned int wxTreeCtrl::GetCount () const
496 {
497 CNRINFO vCnrInfo;
498
499 ::WinSendMsg( GetHWND()
500 ,CM_QUERYCNRINFO
501 ,MPFROMP(&vCnrInfo)
502 ,(MPARAM)(USHORT)sizeof(CNRINFO)
503 );
504
505 return (unsigned int)vCnrInfo.cRecords;
506 } // end of wxTreeCtrl::GetCount
507
508 unsigned int wxTreeCtrl::GetIndent () const
509 {
510 CNRINFO vCnrInfo;
511
512 ::WinSendMsg( GetHWND()
513 ,CM_QUERYCNRINFO
514 ,MPFROMP(&vCnrInfo)
515 ,(MPARAM)(USHORT)sizeof(CNRINFO)
516 );
517 return (unsigned int)vCnrInfo.cxTreeIndent;
518 } // end of wxTreeCtrl::GetIndent
519
520 void wxTreeCtrl::SetIndent (
521 unsigned int uIndent
522 )
523 {
524 CNRINFO vCnrInfo;
525
526 ::WinSendMsg( GetHWND()
527 ,CM_QUERYCNRINFO
528 ,MPFROMP(&vCnrInfo)
529 ,(MPARAM)(USHORT)sizeof(CNRINFO)
530 );
531 vCnrInfo.cxTreeIndent = (LONG)uIndent;
532 ::WinSendMsg( GetHWND()
533 ,CM_SETCNRINFO
534 ,MPFROMP(&vCnrInfo)
535 ,(MPARAM)CMA_CXTREEINDENT
536 );
537 } // end of wxTreeCtrl::SetIndent
538
539 wxImageList* wxTreeCtrl::GetImageList () const
540 {
541 return m_pImageListNormal;
542 } // end of wxTreeCtrl::GetImageList
543
544 #if WXWIN_COMPATIBILITY_2_4
545
546 wxImageList* wxTreeCtrl::GetImageList(int nVal) const
547 {
548 return GetImageList();
549 }
550
551 void wxTreeCtrl::SetImageList(wxImageList* pImageList, int nVal)
552 {
553 SetImageList(pImageList);
554 }
555
556 int wxTreeCtrl::GetItemSelectedImage(const wxTreeItemId& rItem) const
557 {
558 return GetItemImage(rItem, wxTreeItemIcon_Selected);
559 }
560
561 void wxTreeCtrl::SetItemSelectedImage(const wxTreeItemId& rItem, int nImage)
562 {
563 SetItemImage(rItem, nImage, wxTreeItemIcon_Selected);
564 }
565
566 #endif // WXWIN_COMPATIBILITY_2_4
567
568 wxImageList* wxTreeCtrl::GetStateImageList () const
569 {
570 return m_pImageListNormal;
571 } // end of wxTreeCtrl::GetStateImageList
572
573 //
574 // The SETS of imagelists really do nothing under OS2 as a RECORDCORE
575 // struct has the icon imbedded in it that it uses for the icon being
576 // displayed via the TREEITEMDESC member. Provided for interface
577 // compatibility only
578 //
579 void wxTreeCtrl::SetAnyImageList (
580 wxImageList* WXUNUSED(pImageList)
581 , int WXUNUSED(nWhich)
582 )
583 {
584 } // end of wxTreeCtrl::SetAnyImageList
585
586 void wxTreeCtrl::SetImageList (
587 wxImageList* WXUNUSED(pImageList)
588 )
589 {
590 if (m_bOwnsImageListNormal)
591 delete m_pImageListNormal;
592 m_bOwnsImageListNormal = false;
593 } // end of wxTreeCtrl::SetImageList
594
595 void wxTreeCtrl::SetStateImageList (
596 wxImageList* WXUNUSED(pImageList)
597 )
598 {
599 if (m_bOwnsImageListState)
600 delete m_pImageListState;
601 m_bOwnsImageListState = false;
602 } // end of wxTreeCtrl::SetStateImageList
603
604 void wxTreeCtrl::AssignImageList (
605 wxImageList* WXUNUSED(pImageList)
606 )
607 {
608 m_bOwnsImageListNormal = true;
609 } // end of wxTreeCtrl::AssignImageList
610
611 void wxTreeCtrl::AssignStateImageList (
612 wxImageList* WXUNUSED(pImageList)
613 )
614 {
615 m_bOwnsImageListState = true;
616 } // end of wxTreeCtrl::AssignStateImageList
617
618 size_t wxTreeCtrl::GetChildrenCount (
619 const wxTreeItemId& rItem
620 , bool bRecursively
621 ) const
622 {
623 TraverseCounter vCounter( this
624 ,rItem
625 ,bRecursively
626 );
627 return vCounter.GetCount() - 1;
628 } // end of wxTreeCtrl::GetChildrenCount
629
630 // ----------------------------------------------------------------------------
631 // control colours
632 // ----------------------------------------------------------------------------
633
634 bool wxTreeCtrl::SetBackgroundColour (
635 const wxColour& rColour
636 )
637 {
638 ULONG ulColor = wxColourToRGB(rColour);
639
640 if ( !wxWindowBase::SetBackgroundColour(rColour) )
641 return false;
642 ::WinSetPresParam( GetHWND()
643 ,PP_BACKGROUNDCOLOR
644 ,sizeof(ULONG)
645 ,&ulColor
646 );
647 return true;
648 } // end of wxTreeCtrl::SetBackgroundColour
649
650 bool wxTreeCtrl::SetForegroundColour (
651 const wxColour& rColour
652 )
653 {
654 ULONG ulColor = wxColourToRGB(rColour);
655
656 if (!wxWindowBase::SetForegroundColour(rColour))
657 return false;
658 ::WinSetPresParam( GetHWND()
659 ,PP_FOREGROUNDCOLOR
660 ,sizeof(ULONG)
661 ,&ulColor
662 );
663 return true;
664 } // end of wxTreeCtrl::SetForegroundColour
665
666 // ----------------------------------------------------------------------------
667 // Item access
668 // ----------------------------------------------------------------------------
669
670 wxString wxTreeCtrl::GetItemText (
671 const wxTreeItemId& rItem
672 ) const
673 {
674 wxChar zBuf[512]; // the size is arbitrary...
675 wxTreeViewItem vTvItem(rItem);
676
677 if (!DoGetItem(&vTvItem))
678 {
679 //
680 // Don't return some garbage which was on stack, but an empty string
681 //
682 zBuf[0] = wxT('\0');
683 }
684 else
685 strcpy(zBuf, vTvItem.m_vRecord.pszTree);
686 return wxString(zBuf);
687 } // end of wxTreeCtrl::GetItemText
688
689 void wxTreeCtrl::SetItemText (
690 const wxTreeItemId& rItem
691 , const wxString& rsText
692 )
693 {
694 wxTreeViewItem vTvItem(rItem);
695
696 vTvItem.m_vRecord.pszTree = (wxChar *)rsText.c_str(); // conversion is ok
697 DoSetItem(&vTvItem);
698 } // end of wxTreeCtrl::SetItemText
699
700 //
701 // These functions under OS/2 PM are not needed. OS/2 containers in tree view
702 // provide for storing a custom expanded and collapsed icons and selected
703 // and non selected icons, natively. For instance, by default, a disk display
704 // will display a tree list of folder icons with "+" icons (collapsed) beside
705 // those folder which contain child members. Double clicking a folder changes
706 // the closed folder icon to an open folder icon with hatched selection
707 // highlighting indicating an ICON view container of the folder is open
708 // elsewhere on the desktop. So the below is not really needed, but we will
709 // simply return the appropriate icon requested out of OS/2's native PM
710 // data structures.
711 //
712 int wxTreeCtrl::DoGetItemImageFromData (
713 const wxTreeItemId& WXUNUSED(rItem)
714 , wxTreeItemIcon nWhich
715 ) const
716 {
717 //
718 // Image handles stored in CNRINFO.
719 //
720 CNRINFO vCnrInfo;
721
722 ::WinSendMsg( GetHWND()
723 ,CM_QUERYCNRINFO
724 ,MPFROMP(&vCnrInfo)
725 ,(MPARAM)(USHORT)sizeof(CNRINFO)
726 );
727
728 //
729 // We really only have two to chose from. If not custom (set in CNRINFO
730 // then return the handle to system bitmap). OS/2 automatically provides
731 // in_use and selected bitmaps/icons
732 //
733 switch(nWhich)
734 {
735 case wxTreeItemIcon_Normal:
736 if (vCnrInfo.hbmCollapsed == NULLHANDLE)
737 return (int)::WinGetSysBitmap(HWND_DESKTOP, SBMP_TREEPLUS);
738 return vCnrInfo.hbmCollapsed;
739
740
741 case wxTreeItemIcon_Expanded:
742 if (vCnrInfo.hbmExpanded == NULLHANDLE)
743 return (int)::WinGetSysBitmap(HWND_DESKTOP, SBMP_TREEMINUS);
744 return vCnrInfo.hbmExpanded;
745
746 default:
747 return vCnrInfo.hbmCollapsed;
748 }
749 }
750
751 void wxTreeCtrl::DoSetItemImageFromData (
752 const wxTreeItemId& WXUNUSED(rItem)
753 , int nImage
754 , wxTreeItemIcon nWhich
755 ) const
756 {
757 //
758 // Image handles stored in CNRINFO.
759 //
760 CNRINFO vCnrInfo;
761
762 ::WinSendMsg( GetHWND()
763 ,CM_QUERYCNRINFO
764 ,MPFROMP(&vCnrInfo)
765 ,(MPARAM)(USHORT)sizeof(CNRINFO)
766 );
767 if (nWhich == wxTreeItemIcon_Normal)
768 vCnrInfo.hbmCollapsed = (HBITMAP)nImage;
769 if (nWhich == wxTreeItemIcon_Expanded)
770 vCnrInfo.hbmExpanded = (HBITMAP)nImage;
771 ::WinSendMsg( GetHWND()
772 ,CM_SETCNRINFO
773 ,MPFROMP(&vCnrInfo)
774 ,(MPARAM)CMA_TREEBITMAP
775 );
776 } // end of wxTreeCtrl::DoSetItemImageFromData
777
778 // Useless for OS/2
779 void wxTreeCtrl::DoSetItemImages (
780 const wxTreeItemId& rItem
781 , int nImage
782 , int nImageSel
783 )
784 {
785 } // end of wxTreeCtrl::DoSetItemImages
786
787 int wxTreeCtrl::GetItemImage (
788 const wxTreeItemId& rItem
789 , wxTreeItemIcon nWhich
790 ) const
791 {
792 if (HasIndirectData(rItem))
793 {
794 return DoGetItemImageFromData( rItem
795 ,nWhich
796 );
797 }
798
799 CNRINFO vCnrInfo;
800
801 ::WinSendMsg( GetHWND()
802 ,CM_QUERYCNRINFO
803 ,MPFROMP(&vCnrInfo)
804 ,(MPARAM)(USHORT)sizeof(CNRINFO)
805 );
806 switch (nWhich)
807 {
808 default:
809 wxFAIL_MSG( wxT("unknown tree item image type") );
810
811 case wxTreeItemIcon_Normal:
812 if (vCnrInfo.hbmCollapsed == NULLHANDLE)
813 return (int)::WinGetSysBitmap(HWND_DESKTOP, SBMP_TREEPLUS);
814 return vCnrInfo.hbmCollapsed;
815
816
817 case wxTreeItemIcon_Expanded:
818 if (vCnrInfo.hbmExpanded == NULLHANDLE)
819 return (int)::WinGetSysBitmap(HWND_DESKTOP, SBMP_TREEMINUS);
820 return vCnrInfo.hbmExpanded;
821
822 case wxTreeItemIcon_Selected:
823 case wxTreeItemIcon_SelectedExpanded:
824 return -1;
825 }
826 }
827
828 void wxTreeCtrl::SetItemImage (
829 const wxTreeItemId& WXUNUSED(rItem)
830 , int nImage
831 , wxTreeItemIcon nWhich
832 )
833 {
834 CNRINFO vCnrInfo;
835
836 ::WinSendMsg( GetHWND()
837 ,CM_QUERYCNRINFO
838 ,MPFROMP(&vCnrInfo)
839 ,(MPARAM)(USHORT)sizeof(CNRINFO)
840 );
841 switch (nWhich)
842 {
843 case wxTreeItemIcon_Normal:
844 vCnrInfo.hbmCollapsed = (HBITMAP)nImage;
845 break;
846
847 case wxTreeItemIcon_Expanded:
848 vCnrInfo.hbmExpanded = (HBITMAP)nImage;
849 break;
850
851 default:
852 wxFAIL_MSG( wxT("unknown tree item image type") );
853 }
854 ::WinSendMsg( GetHWND()
855 ,CM_SETCNRINFO
856 ,MPFROMP(&vCnrInfo)
857 ,(MPARAM)CMA_TREEBITMAP
858 );
859 } // end of wxTreeCtrl::SetItemImage
860
861 wxTreeItemData* wxTreeCtrl::GetItemData (
862 const wxTreeItemId& rItem
863 ) const
864 {
865 wxTreeViewItem vTvItem(rItem);
866
867 if (!DoGetItem(&vTvItem))
868 {
869 return NULL;
870 }
871
872 return (wxTreeItemData *)vTvItem.m_ulUserData;
873 } // end of wxTreeCtrl::GetItemData
874
875 void wxTreeCtrl::SetItemData (
876 const wxTreeItemId& rItem
877 , wxTreeItemData* pData
878 )
879 {
880 //
881 // first, associate this piece of data with this item
882 if (pData)
883 {
884 pData->SetId(rItem);
885 }
886
887 wxTreeViewItem vTvItem(rItem);
888
889 vTvItem.m_ulUserData = (ULONG)pData;
890 DoSetItem(&vTvItem);
891 } // end of wxTreeCtrl::SetItemData
892
893 // The following two do nothing under OS/2
894 void wxTreeCtrl::SetIndirectItemData (
895 const wxTreeItemId& WXUNUSED(rItem)
896 , wxTreeItemIndirectData* WXUNUSED(pData)
897 )
898 {
899 } // end of wxTreeCtrl::SetIndirectItemData
900
901 bool wxTreeCtrl::HasIndirectData (
902 const wxTreeItemId& WXUNUSED(rItem)
903 ) const
904 {
905 return false;
906 } // end of wxTreeCtrl::HasIndirectData
907
908 // Irreleveant under OS/2 --- item either has child records or it doesn't.
909 void wxTreeCtrl::SetItemHasChildren (
910 const wxTreeItemId& WXUNUSED(rItem)
911 , bool WXUNUSED(bHas)
912 )
913 {
914 } // end of wxTreeCtrl::SetItemHasChildren
915
916 // Irreleveant under OS/2 --- function of the font in PM
917 void wxTreeCtrl::SetItemBold (
918 const wxTreeItemId& WXUNUSED(rItem)
919 , bool WXUNUSED(bBold)
920 )
921 {
922 } // end of wxTreeCtrl::SetItemBold
923
924 void wxTreeCtrl::SetItemDropHighlight (
925 const wxTreeItemId& rItem
926 , bool bHighlight
927 )
928 {
929 wxTreeViewItem vTvItem(rItem);
930
931 ::WinSendMsg( GetHWND()
932 ,CM_SETRECORDEMPHASIS
933 ,MPFROMP(&vTvItem)
934 ,MPFROM2SHORT(bHighlight, CRA_SELECTED)
935 );
936 DoSetItem(&vTvItem);
937 } // end of wxTreeCtrl::SetItemDropHighlight
938
939 void wxTreeCtrl::RefreshItem (
940 const wxTreeItemId& rItem
941 )
942 {
943 wxTreeViewItem vTvItem(rItem);
944
945 //
946 // This just does a record invalidate causing it to be re-displayed
947 //
948 DoSetItem(&vTvItem);
949 } // end of wxTreeCtrl::RefreshItem
950
951 wxColour wxTreeCtrl::GetItemTextColour (
952 const wxTreeItemId& rItem
953 ) const
954 {
955 long lId = (long)rItem.m_pItem;
956 wxTreeItemAttr* pAttr = (wxTreeItemAttr *)m_vAttrs.Get(lId);
957
958 if (!pAttr)
959 {
960 return wxNullColour;
961 }
962 return pAttr->GetTextColour();
963 } // end of wxTreeCtrl::GetItemTextColour
964
965 wxColour wxTreeCtrl::GetItemBackgroundColour (
966 const wxTreeItemId& rItem
967 ) const
968 {
969 long lId = (long)rItem.m_pItem;
970 wxTreeItemAttr* pAttr = (wxTreeItemAttr *)m_vAttrs.Get(lId);
971
972 if (!pAttr)
973 {
974 return wxNullColour;
975 }
976 return pAttr->GetBackgroundColour();
977 } // end of wxTreeCtrl::GetItemBackgroundColour
978
979 wxFont wxTreeCtrl::GetItemFont (
980 const wxTreeItemId& rItem
981 ) const
982 {
983 long lId = (long)rItem.m_pItem;
984 wxTreeItemAttr* pAttr = (wxTreeItemAttr *)m_vAttrs.Get(lId);
985
986 if (!pAttr)
987 {
988 return wxNullFont;
989 }
990 return pAttr->GetFont();
991 } // end of wxTreeCtrl::GetItemFont
992
993 void wxTreeCtrl::SetItemTextColour (
994 const wxTreeItemId& rItem
995 , const wxColour& rCol
996 )
997 {
998 m_bHasAnyAttr = true;
999
1000 long lId = (long)rItem.m_pItem;
1001 wxTreeItemAttr* pAttr = (wxTreeItemAttr *)m_vAttrs.Get(lId);
1002
1003 if (!pAttr)
1004 {
1005 pAttr = new wxTreeItemAttr;
1006 m_vAttrs.Put(lId, (wxObject *)pAttr);
1007 }
1008 pAttr->SetTextColour(rCol);
1009 RefreshItem(rItem);
1010 } // end of wxTreeCtrl::SetItemTextColour
1011
1012 void wxTreeCtrl::SetItemBackgroundColour (
1013 const wxTreeItemId& rItem
1014 , const wxColour& rCol
1015 )
1016 {
1017 m_bHasAnyAttr = true;
1018
1019 long lId = (long)rItem.m_pItem;
1020 wxTreeItemAttr* pAttr = (wxTreeItemAttr *)m_vAttrs.Get(lId);
1021
1022 if (!pAttr)
1023 {
1024 pAttr = new wxTreeItemAttr;
1025 m_vAttrs.Put(lId, (wxObject *)pAttr);
1026 }
1027 pAttr->SetBackgroundColour(rCol);
1028 RefreshItem(rItem);
1029 } // end of wxTreeCtrl::SetItemBackgroundColour
1030
1031 void wxTreeCtrl::SetItemFont (
1032 const wxTreeItemId& rItem
1033 , const wxFont& rFont
1034 )
1035 {
1036 m_bHasAnyAttr = true;
1037
1038 long lId = (long)rItem.m_pItem;
1039 wxTreeItemAttr* pAttr = (wxTreeItemAttr *)m_vAttrs.Get(lId);
1040
1041 if (!pAttr)
1042 {
1043 pAttr = new wxTreeItemAttr;
1044 m_vAttrs.Put(lId, (wxObject *)pAttr);
1045 }
1046 pAttr->SetFont(rFont);
1047 RefreshItem(rItem);
1048 } // end of wxTreeCtrl::SetItemFont
1049
1050 // ----------------------------------------------------------------------------
1051 // Item status
1052 // ----------------------------------------------------------------------------
1053
1054 bool wxTreeCtrl::IsVisible (
1055 const wxTreeItemId& rItem
1056 ) const
1057 {
1058 // Bug in Gnu-Win32 headers, so don't use the macro TreeView_GetItemRect
1059 RECTL vRectRecord;
1060 RECTL vRectContainer;
1061 wxRect vWxRectRecord;
1062 wxRect vWxRectContainer;
1063 PMYRECORD pRecord = FindOS2TreeRecordByID ( GetHWND()
1064 ,rItem.m_pItem
1065 );
1066 QUERYRECORDRECT vQuery;
1067
1068 vQuery.cb = sizeof(QUERYRECORDRECT);
1069 vQuery.pRecord = (PRECORDCORE)pRecord;
1070 vQuery.fRightSplitWindow = FALSE;
1071 vQuery.fsExtent = CMA_TREEICON;
1072
1073 ::WinSendMsg( GetHWND()
1074 ,CM_QUERYVIEWPORTRECT
1075 ,MPFROMP(&vRectContainer)
1076 ,MPFROM2SHORT(CMA_WINDOW, FALSE)
1077 );
1078 ::WinSendMsg( GetHWND()
1079 ,CM_QUERYRECORDRECT
1080 ,MPFROMP(&vRectRecord)
1081 ,MPFROMP(&vQuery)
1082 );
1083 vWxRectRecord.SetLeft(vRectRecord.xLeft);
1084 vWxRectRecord.SetTop(vRectRecord.yTop);
1085 vWxRectRecord.SetRight(vRectRecord.xRight);
1086 vWxRectRecord.SetBottom(vRectRecord.yBottom);
1087
1088 vWxRectContainer.SetLeft(vRectContainer.xLeft);
1089 vWxRectContainer.SetTop(vRectContainer.yTop);
1090 vWxRectContainer.SetRight(vRectContainer.xRight);
1091 vWxRectContainer.SetBottom(vRectContainer.yBottom);
1092 return (vWxRectContainer.Inside(wxPoint(vWxRectRecord.x, vWxRectRecord.y)));
1093 } // end of wxTreeCtrl::IsVisible
1094
1095 bool wxTreeCtrl::ItemHasChildren (
1096 const wxTreeItemId& rItem
1097 ) const
1098 {
1099 wxTreeViewItem vTvItem(rItem);
1100 DoGetItem(&vTvItem);
1101
1102 //
1103 // A tree record with children will have one of these attributes
1104 //
1105 return (vTvItem.m_vRecord.flRecordAttr & CRA_EXPANDED ||
1106 vTvItem.m_vRecord.flRecordAttr & CRA_COLLAPSED) != 0;
1107 }
1108
1109 bool wxTreeCtrl::IsExpanded (
1110 const wxTreeItemId& rItem
1111 ) const
1112 {
1113 wxTreeViewItem vTvItem(rItem);
1114 DoGetItem(&vTvItem);
1115
1116 return (vTvItem.m_vRecord.flRecordAttr & CRA_EXPANDED) != 0;
1117 } // end of wxTreeCtrl::IsExpanded
1118
1119 bool wxTreeCtrl::IsSelected (
1120 const wxTreeItemId& rItem
1121 ) const
1122 {
1123 wxTreeViewItem vTvItem(rItem);
1124 DoGetItem(&vTvItem);
1125
1126 return (vTvItem.m_vRecord.flRecordAttr & CRA_SELECTED) != 0;
1127 } // end of wxTreeCtrl::IsSelected
1128
1129 // Not supported
1130 bool wxTreeCtrl::IsBold (
1131 const wxTreeItemId& rItem
1132 ) const
1133 {
1134 return false;
1135 } // end of wxTreeCtrl::IsBold
1136
1137 // ----------------------------------------------------------------------------
1138 // navigation
1139 // ----------------------------------------------------------------------------
1140
1141 wxTreeItemId wxTreeCtrl::GetRootItem () const
1142 {
1143 PMYRECORD pRecord = NULL;
1144
1145 pRecord = (PMYRECORD)PVOIDFROMMR(::WinSendMsg( GetHWND()
1146 ,CM_QUERYRECORD
1147 ,MPFROMP(pRecord)
1148 ,MPFROM2SHORT(CMA_FIRST, CMA_ITEMORDER)
1149 ));
1150
1151 if (!pRecord)
1152 return wxTreeItemId(-1L);
1153 return wxTreeItemId((long)pRecord->m_ulItemId);
1154 } // end of wxTreeCtrl::GetRootItem
1155
1156 wxTreeItemId wxTreeCtrl::GetSelection () const
1157 {
1158 wxCHECK_MSG( !(m_windowStyle & wxTR_MULTIPLE), (long)(WXHTREEITEM)0,
1159 wxT("this only works with single selection controls") );
1160
1161 PMYRECORD pRecord = NULL;
1162
1163 pRecord = (PMYRECORD)PVOIDFROMMR(::WinSendMsg( GetHWND()
1164 ,CM_QUERYRECORDEMPHASIS
1165 ,MPARAM(CMA_FIRST)
1166 ,MPARAM(CRA_SELECTED)
1167 ));
1168 if (!pRecord)
1169 return wxTreeItemId(-1L);
1170 return wxTreeItemId((long)pRecord->m_ulItemId);
1171 } // end of wxTreeCtrl::GetSelection
1172
1173 wxTreeItemId wxTreeCtrl::GetItemParent (
1174 const wxTreeItemId& rItem
1175 ) const
1176 {
1177 PMYRECORD pRecord = FindOS2TreeRecordByID ( GetHWND()
1178 ,rItem.m_pItem
1179 );
1180
1181 if (!pRecord)
1182 return wxTreeItemId(-1L);
1183 pRecord = (PMYRECORD)PVOIDFROMMR(::WinSendMsg( GetHWND()
1184 ,CM_QUERYRECORD
1185 ,MPFROMP(pRecord)
1186 ,MPFROM2SHORT(CMA_PARENT, CMA_ITEMORDER)
1187 ));
1188 if (!pRecord)
1189 return wxTreeItemId(-1L);
1190 return wxTreeItemId((long)pRecord->m_ulItemId);
1191 } // end of wxTreeCtrl::GetItemParent
1192
1193 wxTreeItemId wxTreeCtrl::GetFirstChild (
1194 const wxTreeItemId& rItem
1195 , long& rCookie
1196 ) const
1197 {
1198 PMYRECORD pRecord = FindOS2TreeRecordByID ( GetHWND()
1199 ,rItem.m_pItem
1200 );
1201
1202 if (!pRecord)
1203 return wxTreeItemId(-1L);
1204 pRecord = (PMYRECORD)PVOIDFROMMR(::WinSendMsg( GetHWND()
1205 ,CM_QUERYRECORD
1206 ,MPFROMP(pRecord)
1207 ,MPFROM2SHORT(CMA_FIRSTCHILD, CMA_ITEMORDER)
1208 ));
1209 if (!pRecord)
1210 return wxTreeItemId(-1L);
1211 //
1212 // Remember the last child returned in 'cookie'
1213 //
1214 rCookie = (long)pRecord->m_ulItemId;
1215 return wxTreeItemId(rCookie);
1216 } // end of wxTreeCtrl::GetFirstChild
1217
1218 wxTreeItemId wxTreeCtrl::GetNextChild (
1219 const wxTreeItemId& WXUNUSED(rItem)
1220 , long& rCookie
1221 ) const
1222 {
1223 PMYRECORD pRecord = FindOS2TreeRecordByID ( GetHWND()
1224 ,rCookie
1225 );
1226
1227 if (!pRecord)
1228 return wxTreeItemId(-1L);
1229 pRecord = (PMYRECORD)PVOIDFROMMR(::WinSendMsg( GetHWND()
1230 ,CM_QUERYRECORD
1231 ,MPFROMP(pRecord)
1232 ,MPFROM2SHORT(CMA_NEXT, CMA_ITEMORDER)
1233 ));
1234 if (!pRecord)
1235 return wxTreeItemId(-1L);
1236 rCookie = (long)pRecord->m_ulItemId;
1237 return wxTreeItemId(rCookie);
1238 } // end of wxTreeCtrl::GetNextChild
1239
1240 wxTreeItemId wxTreeCtrl::GetLastChild (
1241 const wxTreeItemId& rItem
1242 ) const
1243 {
1244 PMYRECORD pRecord = FindOS2TreeRecordByID ( GetHWND()
1245 ,rItem.m_pItem
1246 );
1247
1248 if (!pRecord)
1249 return wxTreeItemId(-1L);
1250 pRecord = (PMYRECORD)PVOIDFROMMR(::WinSendMsg( GetHWND()
1251 ,CM_QUERYRECORD
1252 ,MPFROMP(pRecord)
1253 ,MPFROM2SHORT(CMA_LASTCHILD, CMA_ITEMORDER)
1254 ));
1255 if (!pRecord)
1256 return wxTreeItemId(-1L);
1257 return wxTreeItemId((long)pRecord->m_ulItemId);
1258 } // end of wxTreeCtrl::GetLastChild
1259
1260 wxTreeItemId wxTreeCtrl::GetNextSibling (
1261 const wxTreeItemId& rItem
1262 ) const
1263 {
1264 PMYRECORD pRecord = FindOS2TreeRecordByID ( GetHWND()
1265 ,rItem.m_pItem
1266 );
1267
1268 if (!pRecord)
1269 return wxTreeItemId(-1L);
1270 pRecord = (PMYRECORD)PVOIDFROMMR(::WinSendMsg( GetHWND()
1271 ,CM_QUERYRECORD
1272 ,MPFROMP(pRecord)
1273 ,MPFROM2SHORT(CMA_NEXT, CMA_ITEMORDER)
1274 ));
1275 if (!pRecord)
1276 return wxTreeItemId(-1L);
1277 return wxTreeItemId((long)pRecord->m_ulItemId);
1278 } // end of wxTreeCtrl::GetNextSibling
1279
1280 wxTreeItemId wxTreeCtrl::GetPrevSibling (
1281 const wxTreeItemId& rItem
1282 ) const
1283 {
1284 PMYRECORD pRecord = FindOS2TreeRecordByID ( GetHWND()
1285 ,rItem.m_pItem
1286 );
1287
1288 if (!pRecord)
1289 return wxTreeItemId(-1L);
1290 pRecord = (PMYRECORD)PVOIDFROMMR(::WinSendMsg( GetHWND()
1291 ,CM_QUERYRECORD
1292 ,MPFROMP(pRecord)
1293 ,MPFROM2SHORT(CMA_PREV, CMA_ITEMORDER)
1294 ));
1295 if (!pRecord)
1296 return wxTreeItemId(-1L);
1297 return wxTreeItemId((long)pRecord->m_ulItemId);
1298 } // end of wxTreeCtrl::GetPrevSibling
1299
1300 wxTreeItemId wxTreeCtrl::GetFirstVisibleItem () const
1301 {
1302 PMYRECORD pRecord = (PMYRECORD)PVOIDFROMMR(::WinSendMsg( GetHWND()
1303 ,CM_QUERYRECORD
1304 ,MPFROMP(pRecord)
1305 ,MPFROM2SHORT(CMA_FIRST, CMA_ITEMORDER)
1306 ));
1307 if (!pRecord)
1308 return wxTreeItemId(-1L);
1309
1310 if (IsVisible(wxTreeItemId((long)pRecord->m_ulItemId)))
1311 return wxTreeItemId((long)pRecord->m_ulItemId);
1312 while(pRecord)
1313 {
1314 pRecord = (PMYRECORD)PVOIDFROMMR(::WinSendMsg( GetHWND()
1315 ,CM_QUERYRECORD
1316 ,MPFROMP(pRecord)
1317 ,MPFROM2SHORT(CMA_NEXT, CMA_ITEMORDER)
1318 ));
1319 if (!pRecord)
1320 return wxTreeItemId(-1L);
1321 if (IsVisible(wxTreeItemId((long)pRecord->m_ulItemId)))
1322 return wxTreeItemId((long)pRecord->m_ulItemId);
1323 }
1324 return wxTreeItemId(-1L);
1325 } // end of wxTreeCtrl::GetFirstVisibleItem
1326
1327 wxTreeItemId wxTreeCtrl::GetNextVisible (
1328 const wxTreeItemId& rItem
1329 ) const
1330 {
1331 wxASSERT_MSG(IsVisible(rItem), wxT("The item you call GetNextVisible() for must be visible itself!"));
1332
1333 PMYRECORD pRecord = FindOS2TreeRecordByID ( GetHWND()
1334 ,rItem.m_pItem
1335 );
1336
1337 if (!pRecord)
1338 return wxTreeItemId(-1L);
1339 while(pRecord)
1340 {
1341 pRecord = (PMYRECORD)PVOIDFROMMR(::WinSendMsg( GetHWND()
1342 ,CM_QUERYRECORD
1343 ,MPFROMP(pRecord)
1344 ,MPFROM2SHORT(CMA_NEXT, CMA_ITEMORDER)
1345 ));
1346 if (!pRecord)
1347 return wxTreeItemId(-1L);
1348 if (IsVisible(wxTreeItemId((long)pRecord->m_ulItemId)))
1349 return wxTreeItemId((long)pRecord->m_ulItemId);
1350 }
1351 return wxTreeItemId(-1L);
1352 } // end of wxTreeCtrl::GetNextVisible
1353
1354 wxTreeItemId wxTreeCtrl::GetPrevVisible (
1355 const wxTreeItemId& rItem
1356 ) const
1357 {
1358 wxASSERT_MSG( IsVisible(rItem), wxT("The item you call GetPrevVisible() for must be visible itself!"));
1359
1360 PMYRECORD pRecord = FindOS2TreeRecordByID ( GetHWND()
1361 ,rItem.m_pItem
1362 );
1363
1364 if (!pRecord)
1365 return wxTreeItemId(-1L);
1366 while(pRecord)
1367 {
1368 pRecord = (PMYRECORD)PVOIDFROMMR(::WinSendMsg( GetHWND()
1369 ,CM_QUERYRECORD
1370 ,MPFROMP(pRecord)
1371 ,MPFROM2SHORT(CMA_PREV, CMA_ITEMORDER)
1372 ));
1373 if (!pRecord)
1374 return wxTreeItemId(-1L);
1375 if (IsVisible(wxTreeItemId((long)pRecord->m_ulItemId)))
1376 return wxTreeItemId((long)pRecord->m_ulItemId);
1377 }
1378 return wxTreeItemId(-1L);
1379 } // end of wxTreeCtrl::GetPrevVisible
1380
1381 // ----------------------------------------------------------------------------
1382 // multiple selections emulation -- under OS/2 checked tree items is not
1383 // supported, but multisel is. So we'll just check for selections here.
1384 // ----------------------------------------------------------------------------
1385
1386 bool wxTreeCtrl::IsItemChecked (
1387 const wxTreeItemId& rItem
1388 ) const
1389 {
1390 wxTreeViewItem vTvItem(rItem);
1391
1392 DoGetItem(&vTvItem);
1393 return (vTvItem.m_vRecord.flRecordAttr & CRA_SELECTED);
1394 } // end of wxTreeCtrl::IsItemChecked
1395
1396 void wxTreeCtrl::SetItemCheck (
1397 const wxTreeItemId& rItem
1398 , bool bCheck
1399 )
1400 {
1401 wxTreeViewItem vTvItem(rItem);
1402
1403 DoGetItem(&vTvItem);
1404 ::WinSendMsg( GetHWND()
1405 ,CM_SETRECORDEMPHASIS
1406 ,MPFROMP(&vTvItem)
1407 ,MPFROM2SHORT(TRUE, CRA_SELECTED)
1408 );
1409 DoSetItem(&vTvItem);
1410 } // end of wxTreeCtrl::SetItemCheck
1411
1412 size_t wxTreeCtrl::GetSelections (
1413 wxArrayTreeItemIds& raSelections
1414 ) const
1415 {
1416 TraverseSelections vSelector( this
1417 ,raSelections
1418 );
1419 return vSelector.GetCount();
1420 } // end of wxTreeCtrl::GetSelections
1421
1422 // ----------------------------------------------------------------------------
1423 // Usual operations
1424 // ----------------------------------------------------------------------------
1425
1426 wxTreeItemId wxTreeCtrl::DoInsertItem (
1427 const wxTreeItemId& rParent
1428 , wxTreeItemId vInsertAfter
1429 , const wxString& rsText
1430 , int nImage
1431 , int selectedImage
1432 , wxTreeItemData* pData
1433 )
1434 {
1435 PMYRECORD pRecordAfter = FindOS2TreeRecordByID( GetHWND()
1436 ,vInsertAfter.m_pItem
1437 );
1438
1439 PMYRECORD pRecordParent = FindOS2TreeRecordByID( GetHWND()
1440 ,rParent.m_pItem
1441 );
1442
1443 PMYRECORD pRecord = (PMYRECORD)::WinSendMsg( GetHWND()
1444 ,CM_ALLOCRECORD
1445 ,MPFROMLONG(sizeof(MYRECORD) - sizeof(RECORDCORE))
1446 ,MPFROMLONG(1)
1447 );
1448 RECORDINSERT vInsert;
1449
1450 vInsert.cb = sizeof(RECORDINSERT);
1451 if (rParent.m_pItem == 0L)
1452 {
1453 if (vInsertAfter.m_pItem == -1)
1454 vInsert.pRecordOrder = (PRECORDCORE)CMA_END;
1455 else
1456 vInsert.pRecordOrder = (PRECORDCORE)CMA_FIRST;
1457 vInsert.pRecordParent = NULL;
1458 }
1459 else
1460 {
1461 if (vInsertAfter.m_pItem == 0)
1462 vInsert.pRecordOrder = (PRECORDCORE)CMA_FIRST;
1463 else if (vInsertAfter.m_pItem == -1)
1464 vInsert.pRecordOrder = (PRECORDCORE)CMA_END;
1465 else
1466 vInsert.pRecordOrder = (PRECORDCORE)pRecordAfter;
1467 vInsert.pRecordParent = (PRECORDCORE)pRecordParent;
1468 }
1469 vInsert.fInvalidateRecord = TRUE;
1470 vInsert.zOrder = CMA_TOP;
1471 vInsert.cRecordsInsert = 1;
1472
1473 pRecord->m_vRecord.pszTree = (wxChar*)rsText.c_str();
1474 pRecord->m_vRecord.hbmBitmap = nImage;
1475 pRecord->m_ulItemId = pRecordAfter->m_ulItemId + 1;
1476 if (pData != NULL)
1477 {
1478 pRecord->m_ulUserData = (ULONG)pData;
1479 }
1480 ::WinSendMsg( GetHWND()
1481 ,CM_INSERTRECORD
1482 ,MPFROMP(pRecord)
1483 ,MPFROMP(&vInsert)
1484 );
1485
1486 //
1487 // OS/2 must mannually bump the index's of following records
1488 //
1489 BumpTreeRecordIds( GetHWND()
1490 ,pRecord
1491 );
1492 if (pData != NULL)
1493 {
1494 //
1495 // Associate the application tree item with PM tree item handle
1496 //
1497 pData->SetId((long)pRecord->m_ulItemId);
1498 }
1499 return wxTreeItemId((long)pRecord->m_ulItemId);
1500 }
1501
1502 #if WXWIN_COMPATIBILITY_2_4
1503
1504 // for compatibility only
1505 wxTreeItemId wxTreeCtrl::InsertItem (
1506 const wxTreeItemId& rParent
1507 , const wxString& rsText
1508 , int nImage
1509 , int nSelImage
1510 , long lInsertAfter
1511 )
1512 {
1513 return DoInsertItem( rParent
1514 ,wxTreeItemId(lInsertAfter)
1515 ,rsText
1516 ,nImage
1517 ,nSelImage
1518 ,NULL
1519 );
1520 } // end of wxTreeCtrl::InsertItem
1521
1522 #endif // WXWIN_COMPATIBILITY_2_4
1523
1524 wxTreeItemId wxTreeCtrl::AddRoot (
1525 const wxString& rsText
1526 , int nImage
1527 , int nSelectedImage
1528 , wxTreeItemData* pData)
1529 {
1530
1531 return DoInsertItem( wxTreeItemId((long)0)
1532 ,wxTreeItemId((long)-1)
1533 ,rsText
1534 ,nImage
1535 ,nSelectedImage
1536 ,pData
1537 );
1538 } // end of wxTreeCtrl::AddRoot
1539
1540 wxTreeItemId wxTreeCtrl::PrependItem (
1541 const wxTreeItemId& rParent
1542 , const wxString& rsText
1543 , int nImage
1544 , int nSelectedImage
1545 , wxTreeItemData* pData
1546 )
1547 {
1548 return DoInsertItem( rParent
1549 ,wxTreeItemId((long)0)
1550 ,rsText
1551 ,nImage
1552 ,nSelectedImage
1553 ,pData
1554 );
1555 } // end of wxTreeCtrl::PrependItem
1556
1557 wxTreeItemId wxTreeCtrl::InsertItem (
1558 const wxTreeItemId& rParent
1559 , const wxTreeItemId& rIdPrevious
1560 , const wxString& rsText
1561 , int nImage
1562 , int nSelectedImage
1563 , wxTreeItemData* pData
1564 )
1565 {
1566 return DoInsertItem( rParent
1567 ,rIdPrevious
1568 ,rsText
1569 ,nImage
1570 ,nSelectedImage
1571 ,pData
1572 );
1573 } // end of wxTreeCtrl::InsertItem
1574
1575 wxTreeItemId wxTreeCtrl::InsertItem (
1576 const wxTreeItemId& rParent
1577 , size_t nIndex
1578 , const wxString& rsText
1579 , int nImage
1580 , int nSelectedImage
1581 , wxTreeItemData* pData
1582 )
1583 {
1584 return DoInsertItem( rParent
1585 ,wxTreeItemId((long)nIndex)
1586 ,rsText
1587 ,nImage
1588 ,nSelectedImage
1589 ,pData
1590 );
1591 } // end of wxTreeCtrl::InsertItem
1592
1593 wxTreeItemId wxTreeCtrl::AppendItem (
1594 const wxTreeItemId& rParent
1595 , const wxString& rsText
1596 , int nImage
1597 , int nSelectedImage
1598 , wxTreeItemData* pData
1599 )
1600 {
1601 return DoInsertItem( rParent
1602 ,wxTreeItemId((long)-1)
1603 ,rsText
1604 ,nImage
1605 ,nSelectedImage
1606 ,pData
1607 );
1608 } // end of wxTreeCtrl::AppendItem
1609
1610 void wxTreeCtrl::Delete (
1611 const wxTreeItemId& rItem
1612 )
1613 {
1614 //
1615 // OS/2 does not generate DELETEITEM events so do it here
1616 //
1617 wxEventType vEventType = wxEVT_NULL;
1618 wxTreeEvent vEvent( wxEVT_NULL
1619 ,m_windowId
1620 );
1621 PMYRECORD pRecord = FindOS2TreeRecordByID( GetHWND()
1622 ,rItem.m_pItem
1623 );
1624 vEvent.SetEventObject(this);
1625 ::WinSendMsg( GetHWND()
1626 ,CM_REMOVERECORD
1627 ,MPFROMP(pRecord)
1628 ,(MPARAM)(CMA_FREE | CMA_INVALIDATE)
1629 );
1630 vEvent.m_item = rItem.m_pItem;
1631 if (m_bHasAnyAttr)
1632 {
1633 delete (wxTreeItemAttr *)m_vAttrs.Delete((long)rItem.m_pItem);
1634 }
1635 vEvent.SetEventType(vEventType);
1636 GetEventHandler()->ProcessEvent(vEvent);
1637 } // end of wxTreeCtrl::Delete
1638
1639 // delete all children (but don't delete the item itself)
1640 void wxTreeCtrl::DeleteChildren (
1641 const wxTreeItemId& rItem
1642 )
1643 {
1644 long lCookie;
1645 wxArrayLong aChildren;
1646 wxTreeItemId vChild = GetFirstChild( rItem
1647 ,lCookie
1648 );
1649
1650 while (vChild.IsOk())
1651 {
1652 aChildren.Add((long)(WXHTREEITEM)vChild);
1653 vChild = GetNextChild( rItem
1654 ,lCookie
1655 );
1656 }
1657
1658 size_t nCount = aChildren.Count();
1659
1660 for (size_t n = 0; n < nCount; n++)
1661 {
1662 Delete(aChildren[n]);
1663 }
1664 } // end of wxTreeCtrl::DeleteChildren
1665
1666 void wxTreeCtrl::DeleteAllItems ()
1667 {
1668 ::WinSendMsg( GetHWND()
1669 ,CM_REMOVERECORD
1670 ,NULL // Remove all
1671 ,(MPARAM)(CMA_FREE | CMA_INVALIDATE)
1672 );
1673 } // end of wxTreeCtrl::DeleteAllItems
1674
1675 void wxTreeCtrl::DoExpand (
1676 const wxTreeItemId& rItem
1677 , int nFlag
1678 )
1679 {
1680 PMYRECORD pRecord = FindOS2TreeRecordByID( GetHWND()
1681 ,rItem.m_pItem
1682 );
1683 switch(nFlag)
1684 {
1685 case wxTREE_EXPAND_EXPAND:
1686 ::WinSendMsg( GetHWND()
1687 ,CM_EXPANDTREE
1688 ,MPFROMP(pRecord)
1689 ,NULL
1690 );
1691 break;
1692
1693 case wxTREE_EXPAND_COLLAPSE:
1694 ::WinSendMsg( GetHWND()
1695 ,CM_COLLAPSETREE
1696 ,MPFROMP(pRecord)
1697 ,NULL
1698 );
1699 break;
1700
1701 case wxTREE_EXPAND_COLLAPSE_RESET:
1702 ::WinSendMsg( GetHWND()
1703 ,CM_COLLAPSETREE
1704 ,MPFROMP(pRecord)
1705 ,NULL
1706 );
1707 DeleteChildren(rItem);
1708 break;
1709
1710 case wxTREE_EXPAND_TOGGLE:
1711 if (pRecord->m_vRecord.flRecordAttr & CRA_COLLAPSED)
1712 ::WinSendMsg( GetHWND()
1713 ,CM_EXPANDTREE
1714 ,MPFROMP(pRecord)
1715 ,NULL
1716 );
1717 else if (pRecord->m_vRecord.flRecordAttr & CRA_EXPANDED)
1718 ::WinSendMsg( GetHWND()
1719 ,CM_COLLAPSETREE
1720 ,MPFROMP(pRecord)
1721 ,NULL
1722 );
1723 break;
1724
1725 }
1726 } // end of wxTreeCtrl::DoExpand
1727
1728 void wxTreeCtrl::Expand (
1729 const wxTreeItemId& rItem
1730 )
1731 {
1732 DoExpand( rItem
1733 ,wxTREE_EXPAND_EXPAND
1734 );
1735 } // end of wxTreeCtrl::Expand
1736
1737 void wxTreeCtrl::Collapse (
1738 const wxTreeItemId& rItem
1739 )
1740 {
1741 DoExpand( rItem
1742 ,wxTREE_EXPAND_COLLAPSE
1743 );
1744 } // end of wxTreeCtrl::Collapse
1745
1746 void wxTreeCtrl::CollapseAndReset (
1747 const wxTreeItemId& rItem
1748 )
1749 {
1750 DoExpand( rItem
1751 ,wxTREE_EXPAND_COLLAPSE_RESET
1752 );
1753 } // end of wxTreeCtrl::CollapseAndReset
1754
1755 void wxTreeCtrl::Toggle (
1756 const wxTreeItemId& rItem
1757 )
1758 {
1759 DoExpand( rItem
1760 ,wxTREE_EXPAND_TOGGLE
1761 );
1762 } // end of wxTreeCtrl::Toggle
1763
1764 #if WXWIN_COMPATIBILITY_2_4
1765
1766 void wxTreeCtrl::ExpandItem (
1767 const wxTreeItemId& rItem
1768 , int nAction
1769 )
1770 {
1771 DoExpand( rItem
1772 ,nAction
1773 );
1774 } // end of wxTreeCtrl::ExpandItem
1775
1776 #endif // WXWIN_COMPATIBILITY_2_4
1777
1778 void wxTreeCtrl::Unselect ()
1779 {
1780 wxASSERT_MSG( !(m_windowStyle & wxTR_MULTIPLE),
1781 wxT("doesn't make sense, may be you want UnselectAll()?") );
1782
1783 //
1784 // Just remove the selection
1785 //
1786 SelectItem(wxTreeItemId((long)0));
1787 } // end of wxTreeCtrl::Unselect
1788
1789 void wxTreeCtrl::UnselectAll ()
1790 {
1791 if (m_windowStyle & wxTR_MULTIPLE)
1792 {
1793 wxArrayTreeItemIds aSelections;
1794 size_t nCount = GetSelections(aSelections);
1795
1796 for (size_t n = 0; n < nCount; n++)
1797 {
1798 SetItemCheck( aSelections[n]
1799 ,false
1800 );
1801 }
1802 }
1803 else
1804 {
1805 //
1806 // Just remove the selection
1807 //
1808 Unselect();
1809 }
1810 } // end of wxTreeCtrl::UnselectAll
1811
1812 void wxTreeCtrl::SelectItem (
1813 const wxTreeItemId& rItem
1814 )
1815 {
1816 SetItemCheck(rItem);
1817 } // end of wxTreeCtrl::SelectItem
1818
1819 void wxTreeCtrl::EnsureVisible (
1820 const wxTreeItemId& rItem
1821 )
1822 {
1823 wxTreeViewItem vTvItem(rItem);
1824
1825 DoGetItem(&vTvItem);
1826 if (!::WinSendMsg( GetHWND()
1827 ,CM_INVALIDATERECORD
1828 ,MPFROMP(&vTvItem)
1829 ,MPFROM2SHORT(1, CMA_ERASE | CMA_REPOSITION | CMA_TEXTCHANGED)
1830 ));
1831 } // end of wxTreeCtrl::EnsureVisible
1832
1833 void wxTreeCtrl::ScrollTo (
1834 const wxTreeItemId& rItem
1835 )
1836 {
1837 wxTreeViewItem vTvItem(rItem);
1838
1839 DoGetItem(&vTvItem);
1840 if (!::WinSendMsg( GetHWND()
1841 ,CM_INVALIDATERECORD
1842 ,MPFROMP(&vTvItem)
1843 ,MPFROM2SHORT(1, CMA_ERASE | CMA_REPOSITION | CMA_TEXTCHANGED)
1844 ));
1845 }
1846
1847 wxTextCtrl* wxTreeCtrl::EditLabel (
1848 const wxTreeItemId& rItem
1849 , wxClassInfo* WXUNUSED(pTextControlClass)
1850 )
1851 {
1852 CNREDITDATA vEdit;
1853 PMYRECORD pRecord = FindOS2TreeRecordByID( GetHWND()
1854 ,rItem.m_pItem
1855 );
1856
1857 vEdit.cb = sizeof(CNREDITDATA);
1858 vEdit.hwndCnr = GetHWND();
1859 vEdit.pRecord = &pRecord->m_vRecord;
1860 vEdit.pFieldInfo = NULL;
1861 vEdit.ppszText = NULL;
1862 vEdit.cbText = 0;
1863 vEdit.id = 0;
1864
1865 ::WinSendMsg( GetHWND()
1866 ,CM_OPENEDIT
1867 ,MPFROMP(&vEdit)
1868 ,(MPARAM)0
1869 );
1870 return NULL;
1871 } // end of wxTreeCtrl::EditLabel
1872
1873 // End label editing, optionally cancelling the edit
1874 void wxTreeCtrl::EndEditLabel (
1875 const wxTreeItemId& WXUNUSED(rItem)
1876 , bool WXUNUSED(bDiscardChanges)
1877 )
1878 {
1879 ::WinSendMsg( GetHWND()
1880 ,CM_CLOSEEDIT
1881 ,(MPARAM)0
1882 ,(MPARAM)0
1883 );
1884 } // end of wxTreeCtrl::EndEditLabel
1885
1886 wxTreeItemId wxTreeCtrl::HitTest (
1887 const wxPoint& rPoint
1888 , int& WXUNUSED(rFlags)
1889 )
1890 {
1891 PMYRECORD pRecord = NULL;
1892 QUERYRECFROMRECT vQueryRect;
1893 RECTL vRect;
1894 long lHeight;
1895
1896 //
1897 // Get height for OS/2 point conversion
1898 //
1899 ::WinSendMsg( GetHWND()
1900 ,CM_QUERYVIEWPORTRECT
1901 ,MPFROMP(&vRect)
1902 ,MPFROM2SHORT(CMA_WINDOW, TRUE)
1903 );
1904 lHeight = vRect.yTop - vRect.yBottom;
1905
1906 //
1907 // For now just try and get a record in the general vicinity and forget
1908 // the flag
1909 //
1910 vRect.xLeft = rPoint.x - 2;
1911 vRect.xRight = rPoint.x + 2;
1912 vRect.yTop = (lHeight - rPoint.y) + 2;
1913 vRect.yBottom = (lHeight - rPoint.y) - 2;
1914
1915 vQueryRect.cb = sizeof(QUERYRECFROMRECT);
1916 vQueryRect.rect = vRect;
1917 vQueryRect.fsSearch = CMA_PARTIAL;
1918
1919 pRecord = (PMYRECORD)::WinSendMsg( GetHWND()
1920 ,CM_QUERYRECORDFROMRECT
1921 ,(MPARAM)CMA_FIRST
1922 ,MPFROMP(&vQueryRect)
1923 );
1924
1925 if (!pRecord)
1926 return -1L;
1927 return wxTreeItemId((long)pRecord->m_ulItemId);
1928 } // end of wxTreeCtrl::HitTest
1929
1930 bool wxTreeCtrl::GetBoundingRect (
1931 const wxTreeItemId& rItem
1932 , wxRect& rRect
1933 , bool bTextOnly
1934 ) const
1935 {
1936 RECTL vRectRecord;
1937 PMYRECORD pRecord = FindOS2TreeRecordByID ( GetHWND()
1938 ,rItem.m_pItem
1939 );
1940 QUERYRECORDRECT vQuery;
1941
1942 vQuery.cb = sizeof(QUERYRECORDRECT);
1943 vQuery.pRecord = (PRECORDCORE)pRecord;
1944 vQuery.fRightSplitWindow = FALSE;
1945 if (bTextOnly)
1946 vQuery.fsExtent = CMA_TEXT;
1947 else
1948 vQuery.fsExtent = CMA_TREEICON | CMA_TEXT;
1949
1950 if (!::WinSendMsg( GetHWND()
1951 ,CM_QUERYRECORDRECT
1952 ,MPFROMP(&vRectRecord)
1953 ,MPFROMP(&vQuery)
1954 ))
1955 return false;
1956 rRect.SetLeft(vRectRecord.xLeft);
1957 rRect.SetTop(vRectRecord.yTop);
1958 rRect.SetRight(vRectRecord.xRight);
1959 rRect.SetBottom(vRectRecord.yBottom);
1960 return true;
1961 } // end of wxTreeCtrl::GetBoundingRect
1962
1963 // ----------------------------------------------------------------------------
1964 // sorting stuff
1965 // ----------------------------------------------------------------------------
1966
1967 SHORT EXPENTRY InternalDataCompareTreeFunc (
1968 PMYRECORD p1
1969 , PMYRECORD p2
1970 , PVOID pStorage
1971 )
1972 {
1973 wxCHECK_MSG( p1 && p2, 0,
1974 wxT("sorting tree without data doesn't make sense") );
1975
1976 wxTreeCtrl* pTree = (wxTreeCtrl*)pStorage;
1977
1978 return pTree->OnCompareItems( p1->m_ulItemId
1979 ,p2->m_ulItemId
1980 );
1981 } // end of wxTreeSortHelper::Compare
1982
1983 int wxTreeCtrl::OnCompareItems (
1984 const wxTreeItemId& rItem1
1985 , const wxTreeItemId& rItem2
1986 )
1987 {
1988 return wxStrcmp( GetItemText(rItem1)
1989 ,GetItemText(rItem2)
1990 );
1991 } // end of wxTreeCtrl::OnCompareItems
1992
1993 void wxTreeCtrl::SortChildren (
1994 const wxTreeItemId& rItem
1995 )
1996 {
1997 ::WinSendMsg( GetHWND()
1998 ,CM_SORTRECORD
1999 ,(PFN)InternalDataCompareTreeFunc
2000 ,NULL
2001 );
2002 } // end of wxTreeCtrl::SortChildren
2003
2004 // ----------------------------------------------------------------------------
2005 // implementation
2006 // ----------------------------------------------------------------------------
2007
2008 bool wxTreeCtrl::OS2Command (
2009 WXUINT uCmd
2010 , WXWORD wId
2011 )
2012 {
2013 if (uCmd == CN_ENDEDIT)
2014 {
2015 wxCommandEvent vEvent( wxEVT_COMMAND_TEXT_UPDATED
2016 ,wId
2017 );
2018
2019 vEvent.SetEventObject( this );
2020 ProcessCommand(vEvent);
2021 return true;
2022 }
2023 else if (uCmd == CN_KILLFOCUS)
2024 {
2025 wxCommandEvent vEvent( wxEVT_KILL_FOCUS
2026 ,wId
2027 );
2028 vEvent.SetEventObject( this );
2029 ProcessCommand(vEvent);
2030 return true;
2031 }
2032 else
2033 return false;
2034 } // end of wxTreeCtrl::OS2Command
2035
2036 //
2037 // TODO: Fully implement direct manipulation when I figure it out
2038 //
2039 MRESULT wxTreeCtrl::OS2WindowProc (
2040 WXUINT uMsg
2041 , WXWPARAM wParam
2042 , WXLPARAM lParam
2043 )
2044 {
2045 bool bProcessed = false;
2046 MRESULT mRc = 0;
2047 wxTreeEvent vEvent( wxEVT_NULL
2048 ,m_windowId
2049 );
2050 wxEventType vEventType = wxEVT_NULL;
2051 PCNRDRAGINIT pDragInit = NULL;
2052 PCNREDITDATA pEditData = NULL;
2053 PNOTIFYRECORDENTER pNotifyEnter = NULL;
2054
2055 vEvent.SetEventObject(this);
2056 switch (uMsg)
2057 {
2058 case WM_CONTROL:
2059 switch(SHORT2FROMMP(wParam))
2060 {
2061 case CN_INITDRAG:
2062 pDragInit = (PCNRDRAGINIT)lParam;
2063 if (pDragInit)
2064 {
2065 PMYRECORD pRecord = (PMYRECORD)pDragInit->pRecord;
2066
2067 vEventType = wxEVT_COMMAND_TREE_BEGIN_DRAG;
2068 vEvent.m_item = pRecord->m_ulItemId;
2069 vEvent.m_pointDrag.x = pDragInit->x;
2070 vEvent.m_pointDrag.y = pDragInit->y;
2071 }
2072 break;
2073
2074 case CN_BEGINEDIT:
2075 pEditData = (PCNREDITDATA)lParam;
2076 if (pEditData)
2077 {
2078 PMYRECORD pRecord = (PMYRECORD)pEditData->pRecord;
2079
2080 vEventType = wxEVT_COMMAND_TREE_BEGIN_LABEL_EDIT;
2081 vEvent.m_item = pRecord->m_ulItemId;
2082 vEvent.m_label = pRecord->m_vRecord.pszTree;
2083 vEvent.m_editCancelled = false;
2084 }
2085 break;
2086
2087 case CN_ENDEDIT:
2088 pEditData = (PCNREDITDATA)lParam;
2089 if (pEditData)
2090 {
2091 PMYRECORD pRecord = (PMYRECORD)pEditData->pRecord;
2092
2093 vEventType = wxEVT_COMMAND_TREE_END_LABEL_EDIT;
2094 vEvent.m_item = pRecord->m_ulItemId;
2095 vEvent.m_label = pRecord->m_vRecord.pszTree;
2096 if (pRecord->m_vRecord.pszTree == NULL)
2097 {
2098 vEvent.m_editCancelled = true;
2099 }
2100 else
2101 {
2102 vEvent.m_editCancelled = false;
2103 }
2104 }
2105 break;
2106
2107 case CN_EXPANDTREE:
2108 {
2109 PMYRECORD pRecord = (PMYRECORD)lParam;
2110
2111 vEventType = gs_expandEvents[IDX_EXPAND][IDX_DONE];
2112 vEvent.m_item = pRecord->m_ulItemId;
2113 }
2114 break;
2115 }
2116 vEvent.SetEventType(vEventType);
2117 bProcessed = GetEventHandler()->ProcessEvent(vEvent);
2118 break;
2119 }
2120 if (!bProcessed)
2121 mRc = wxControl::OS2WindowProc( uMsg
2122 ,wParam
2123 ,lParam
2124 );
2125 return mRc;
2126 } // end of wxTreeCtrl::OS2WindowProc
2127
2128 #endif // wxUSE_TREECTRL