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