]> git.saurik.com Git - wxWidgets.git/blob - src/os2/treectrl.cpp
calculating vis regions as rects (faster for Quartz) and caching the results for...
[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 #ifdef __GNUG__
21 #pragma implementation "treectrl.h"
22 #endif
23
24 // For compilers that support precompilation, includes "wx.h".
25 #include "wx/wxprec.h"
26
27 #ifdef __BORLANDC__
28 #pragma hdrstop
29 #endif
30
31 #if wxUSE_TREECTRL
32
33 #include "wx/os2/private.h"
34
35 #include "wx/app.h"
36 #include "wx/log.h"
37 #include "wx/dynarray.h"
38 #include "wx/imaglist.h"
39 #include "wx/settings.h"
40 #include "wx/os2/treectrl.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 size_t wxTreeCtrl::GetCount () const
500 {
501 CNRINFO vCnrInfo;
502
503 ::WinSendMsg( GetHWND()
504 ,CM_QUERYCNRINFO
505 ,MPFROMP(&vCnrInfo)
506 ,(MPARAM)(USHORT)sizeof(CNRINFO)
507 );
508 return (size_t)vCnrInfo.cRecords;
509 } // end of wxTreeCtrl::GetCount
510
511 unsigned int wxTreeCtrl::GetIndent () const
512 {
513 CNRINFO vCnrInfo;
514
515 ::WinSendMsg( GetHWND()
516 ,CM_QUERYCNRINFO
517 ,MPFROMP(&vCnrInfo)
518 ,(MPARAM)(USHORT)sizeof(CNRINFO)
519 );
520 return (unsigned int)vCnrInfo.cxTreeIndent;
521 } // end of wxTreeCtrl::GetIndent
522
523 void wxTreeCtrl::SetIndent (
524 unsigned int uIndent
525 )
526 {
527 CNRINFO vCnrInfo;
528
529 ::WinSendMsg( GetHWND()
530 ,CM_QUERYCNRINFO
531 ,MPFROMP(&vCnrInfo)
532 ,(MPARAM)(USHORT)sizeof(CNRINFO)
533 );
534 vCnrInfo.cxTreeIndent = (LONG)uIndent;
535 ::WinSendMsg( GetHWND()
536 ,CM_SETCNRINFO
537 ,MPFROMP(&vCnrInfo)
538 ,(MPARAM)CMA_CXTREEINDENT
539 );
540 } // end of wxTreeCtrl::SetIndent
541
542 wxImageList* wxTreeCtrl::GetImageList () const
543 {
544 return m_pImageListNormal;
545 } // end of wxTreeCtrl::GetImageList
546
547 #if WXWIN_COMPATIBILITY_2_4
548
549 wxImageList* wxTreeCtrl::GetImageList(int nVal) const
550 {
551 return GetImageList();
552 }
553
554 void wxTreeCtrl::SetImageList(wxImageList* pImageList, int nVal)
555 {
556 SetImageList(pImageList);
557 }
558
559 int wxTreeCtrl::GetItemSelectedImage(const wxTreeItemId& rItem) const
560 {
561 return GetItemImage(rItem, wxTreeItemIcon_Selected);
562 }
563
564 void wxTreeCtrl::SetItemSelectedImage(const wxTreeItemId& rItem, int nImage)
565 {
566 SetItemImage(rItem, nImage, wxTreeItemIcon_Selected);
567 }
568
569 #endif // WXWIN_COMPATIBILITY_2_4
570
571 wxImageList* wxTreeCtrl::GetStateImageList () const
572 {
573 return m_pImageListNormal;
574 } // end of wxTreeCtrl::GetStateImageList
575
576 //
577 // The SETS of imagelists really do nothing under OS2 as a RECORDCORE
578 // struct has the icon imbedded in it that it uses for the icon being
579 // displayed via the TREEITEMDESC member. Provided for interface
580 // compatibility only
581 //
582 void wxTreeCtrl::SetAnyImageList (
583 wxImageList* WXUNUSED(pImageList)
584 , int WXUNUSED(nWhich)
585 )
586 {
587 } // end of wxTreeCtrl::SetAnyImageList
588
589 void wxTreeCtrl::SetImageList (
590 wxImageList* WXUNUSED(pImageList)
591 )
592 {
593 if (m_bOwnsImageListNormal)
594 delete m_pImageListNormal;
595 m_bOwnsImageListNormal = false;
596 } // end of wxTreeCtrl::SetImageList
597
598 void wxTreeCtrl::SetStateImageList (
599 wxImageList* WXUNUSED(pImageList)
600 )
601 {
602 if (m_bOwnsImageListState)
603 delete m_pImageListState;
604 m_bOwnsImageListState = false;
605 } // end of wxTreeCtrl::SetStateImageList
606
607 void wxTreeCtrl::AssignImageList (
608 wxImageList* WXUNUSED(pImageList)
609 )
610 {
611 m_bOwnsImageListNormal = true;
612 } // end of wxTreeCtrl::AssignImageList
613
614 void wxTreeCtrl::AssignStateImageList (
615 wxImageList* WXUNUSED(pImageList)
616 )
617 {
618 m_bOwnsImageListState = true;
619 } // end of wxTreeCtrl::AssignStateImageList
620
621 size_t wxTreeCtrl::GetChildrenCount (
622 const wxTreeItemId& rItem
623 , bool bRecursively
624 ) const
625 {
626 TraverseCounter vCounter( this
627 ,rItem
628 ,bRecursively
629 );
630 return vCounter.GetCount() - 1;
631 } // end of wxTreeCtrl::GetChildrenCount
632
633 // ----------------------------------------------------------------------------
634 // control colours
635 // ----------------------------------------------------------------------------
636
637 bool wxTreeCtrl::SetBackgroundColour (
638 const wxColour& rColour
639 )
640 {
641 ULONG ulColor = wxColourToRGB(rColour);
642
643 if ( !wxWindowBase::SetBackgroundColour(rColour) )
644 return false;
645 ::WinSetPresParam( GetHWND()
646 ,PP_BACKGROUNDCOLOR
647 ,sizeof(ULONG)
648 ,&ulColor
649 );
650 return true;
651 } // end of wxTreeCtrl::SetBackgroundColour
652
653 bool wxTreeCtrl::SetForegroundColour (
654 const wxColour& rColour
655 )
656 {
657 ULONG ulColor = wxColourToRGB(rColour);
658
659 if (!wxWindowBase::SetForegroundColour(rColour))
660 return false;
661 ::WinSetPresParam( GetHWND()
662 ,PP_FOREGROUNDCOLOR
663 ,sizeof(ULONG)
664 ,&ulColor
665 );
666 return true;
667 } // end of wxTreeCtrl::SetForegroundColour
668
669 // ----------------------------------------------------------------------------
670 // Item access
671 // ----------------------------------------------------------------------------
672
673 wxString wxTreeCtrl::GetItemText (
674 const wxTreeItemId& rItem
675 ) const
676 {
677 wxChar zBuf[512]; // the size is arbitrary...
678 wxTreeViewItem vTvItem(rItem);
679
680 if (!DoGetItem(&vTvItem))
681 {
682 //
683 // Don't return some garbage which was on stack, but an empty string
684 //
685 zBuf[0] = wxT('\0');
686 }
687 else
688 strcpy(zBuf, vTvItem.m_vRecord.pszTree);
689 return wxString(zBuf);
690 } // end of wxTreeCtrl::GetItemText
691
692 void wxTreeCtrl::SetItemText (
693 const wxTreeItemId& rItem
694 , const wxString& rsText
695 )
696 {
697 wxTreeViewItem vTvItem(rItem);
698
699 vTvItem.m_vRecord.pszTree = (wxChar *)rsText.c_str(); // conversion is ok
700 DoSetItem(&vTvItem);
701 } // end of wxTreeCtrl::SetItemText
702
703 //
704 // These functions under OS/2 PM are not needed. OS/2 containers in tree view
705 // provide for storing a custom expanded and collapsed icons and selected
706 // and non selected icons, natively. For instance, by default, a disk display
707 // will display a tree list of folder icons with "+" icons (collapsed) beside
708 // those folder which contain child members. Double clicking a folder changes
709 // the closed folder icon to an open folder icon with hatched selection
710 // highlighting indicating an ICON view container of the folder is open
711 // elsewhere on the desktop. So the below is not really needed, but we will
712 // simply return the appropriate icon requested out of OS/2's native PM
713 // data structures.
714 //
715 int wxTreeCtrl::DoGetItemImageFromData (
716 const wxTreeItemId& WXUNUSED(rItem)
717 , wxTreeItemIcon nWhich
718 ) const
719 {
720 //
721 // Image handles stored in CNRINFO.
722 //
723 CNRINFO vCnrInfo;
724
725 ::WinSendMsg( GetHWND()
726 ,CM_QUERYCNRINFO
727 ,MPFROMP(&vCnrInfo)
728 ,(MPARAM)(USHORT)sizeof(CNRINFO)
729 );
730
731 //
732 // We really only have two to chose from. If not custom (set in CNRINFO
733 // then return the handle to system bitmap). OS/2 automatically provides
734 // in_use and selected bitmaps/icons
735 //
736 switch(nWhich)
737 {
738 case wxTreeItemIcon_Normal:
739 if (vCnrInfo.hbmCollapsed == NULLHANDLE)
740 return (int)::WinGetSysBitmap(HWND_DESKTOP, SBMP_TREEPLUS);
741 return vCnrInfo.hbmCollapsed;
742
743
744 case wxTreeItemIcon_Expanded:
745 if (vCnrInfo.hbmExpanded == NULLHANDLE)
746 return (int)::WinGetSysBitmap(HWND_DESKTOP, SBMP_TREEMINUS);
747 return vCnrInfo.hbmExpanded;
748
749 default:
750 return vCnrInfo.hbmCollapsed;
751 }
752 }
753
754 void wxTreeCtrl::DoSetItemImageFromData (
755 const wxTreeItemId& WXUNUSED(rItem)
756 , int nImage
757 , wxTreeItemIcon nWhich
758 ) const
759 {
760 //
761 // Image handles stored in CNRINFO.
762 //
763 CNRINFO vCnrInfo;
764
765 ::WinSendMsg( GetHWND()
766 ,CM_QUERYCNRINFO
767 ,MPFROMP(&vCnrInfo)
768 ,(MPARAM)(USHORT)sizeof(CNRINFO)
769 );
770 if (nWhich == wxTreeItemIcon_Normal)
771 vCnrInfo.hbmCollapsed = (HBITMAP)nImage;
772 if (nWhich == wxTreeItemIcon_Expanded)
773 vCnrInfo.hbmExpanded = (HBITMAP)nImage;
774 ::WinSendMsg( GetHWND()
775 ,CM_SETCNRINFO
776 ,MPFROMP(&vCnrInfo)
777 ,(MPARAM)CMA_TREEBITMAP
778 );
779 } // end of wxTreeCtrl::DoSetItemImageFromData
780
781 // Useless for OS/2
782 void wxTreeCtrl::DoSetItemImages (
783 const wxTreeItemId& rItem
784 , int nImage
785 , int nImageSel
786 )
787 {
788 } // end of wxTreeCtrl::DoSetItemImages
789
790 int wxTreeCtrl::GetItemImage (
791 const wxTreeItemId& rItem
792 , wxTreeItemIcon nWhich
793 ) const
794 {
795 if (HasIndirectData(rItem))
796 {
797 return DoGetItemImageFromData( rItem
798 ,nWhich
799 );
800 }
801
802 CNRINFO vCnrInfo;
803
804 ::WinSendMsg( GetHWND()
805 ,CM_QUERYCNRINFO
806 ,MPFROMP(&vCnrInfo)
807 ,(MPARAM)(USHORT)sizeof(CNRINFO)
808 );
809 switch (nWhich)
810 {
811 default:
812 wxFAIL_MSG( wxT("unknown tree item image type") );
813
814 case wxTreeItemIcon_Normal:
815 if (vCnrInfo.hbmCollapsed == NULLHANDLE)
816 return (int)::WinGetSysBitmap(HWND_DESKTOP, SBMP_TREEPLUS);
817 return vCnrInfo.hbmCollapsed;
818
819
820 case wxTreeItemIcon_Expanded:
821 if (vCnrInfo.hbmExpanded == NULLHANDLE)
822 return (int)::WinGetSysBitmap(HWND_DESKTOP, SBMP_TREEMINUS);
823 return vCnrInfo.hbmExpanded;
824
825 case wxTreeItemIcon_Selected:
826 case wxTreeItemIcon_SelectedExpanded:
827 return -1;
828 }
829 }
830
831 void wxTreeCtrl::SetItemImage (
832 const wxTreeItemId& WXUNUSED(rItem)
833 , int nImage
834 , wxTreeItemIcon nWhich
835 )
836 {
837 CNRINFO vCnrInfo;
838
839 ::WinSendMsg( GetHWND()
840 ,CM_QUERYCNRINFO
841 ,MPFROMP(&vCnrInfo)
842 ,(MPARAM)(USHORT)sizeof(CNRINFO)
843 );
844 switch (nWhich)
845 {
846 case wxTreeItemIcon_Normal:
847 vCnrInfo.hbmCollapsed = (HBITMAP)nImage;
848 break;
849
850 case wxTreeItemIcon_Expanded:
851 vCnrInfo.hbmExpanded = (HBITMAP)nImage;
852 break;
853
854 default:
855 wxFAIL_MSG( wxT("unknown tree item image type") );
856 }
857 ::WinSendMsg( GetHWND()
858 ,CM_SETCNRINFO
859 ,MPFROMP(&vCnrInfo)
860 ,(MPARAM)CMA_TREEBITMAP
861 );
862 } // end of wxTreeCtrl::SetItemImage
863
864 wxTreeItemData* wxTreeCtrl::GetItemData (
865 const wxTreeItemId& rItem
866 ) const
867 {
868 wxTreeViewItem vTvItem(rItem);
869
870 if (!DoGetItem(&vTvItem))
871 {
872 return NULL;
873 }
874
875 return (wxTreeItemData *)vTvItem.m_ulUserData;
876 } // end of wxTreeCtrl::GetItemData
877
878 void wxTreeCtrl::SetItemData (
879 const wxTreeItemId& rItem
880 , wxTreeItemData* pData
881 )
882 {
883 //
884 // first, associate this piece of data with this item
885 if (pData)
886 {
887 pData->SetId(rItem);
888 }
889
890 wxTreeViewItem vTvItem(rItem);
891
892 vTvItem.m_ulUserData = (ULONG)pData;
893 DoSetItem(&vTvItem);
894 } // end of wxTreeCtrl::SetItemData
895
896 // The following two do nothing under OS/2
897 void wxTreeCtrl::SetIndirectItemData (
898 const wxTreeItemId& WXUNUSED(rItem)
899 , wxTreeItemIndirectData* WXUNUSED(pData)
900 )
901 {
902 } // end of wxTreeCtrl::SetIndirectItemData
903
904 bool wxTreeCtrl::HasIndirectData (
905 const wxTreeItemId& WXUNUSED(rItem)
906 ) const
907 {
908 return false;
909 } // end of wxTreeCtrl::HasIndirectData
910
911 // Irreleveant under OS/2 --- item either has child records or it doesn't.
912 void wxTreeCtrl::SetItemHasChildren (
913 const wxTreeItemId& WXUNUSED(rItem)
914 , bool WXUNUSED(bHas)
915 )
916 {
917 } // end of wxTreeCtrl::SetItemHasChildren
918
919 // Irreleveant under OS/2 --- function of the font in PM
920 void wxTreeCtrl::SetItemBold (
921 const wxTreeItemId& WXUNUSED(rItem)
922 , bool WXUNUSED(bBold)
923 )
924 {
925 } // end of wxTreeCtrl::SetItemBold
926
927 void wxTreeCtrl::SetItemDropHighlight (
928 const wxTreeItemId& rItem
929 , bool bHighlight
930 )
931 {
932 wxTreeViewItem vTvItem(rItem);
933
934 ::WinSendMsg( GetHWND()
935 ,CM_SETRECORDEMPHASIS
936 ,MPFROMP(&vTvItem)
937 ,MPFROM2SHORT(bHighlight, CRA_SELECTED)
938 );
939 DoSetItem(&vTvItem);
940 } // end of wxTreeCtrl::SetItemDropHighlight
941
942 void wxTreeCtrl::RefreshItem (
943 const wxTreeItemId& rItem
944 )
945 {
946 wxTreeViewItem vTvItem(rItem);
947
948 //
949 // This just does a record invalidate causing it to be re-displayed
950 //
951 DoSetItem(&vTvItem);
952 } // end of wxTreeCtrl::RefreshItem
953
954 wxColour wxTreeCtrl::GetItemTextColour (
955 const wxTreeItemId& rItem
956 ) const
957 {
958 long lId = (long)rItem.m_pItem;
959 wxTreeItemAttr* pAttr = (wxTreeItemAttr *)m_vAttrs.Get(lId);
960
961 if (!pAttr)
962 {
963 return wxNullColour;
964 }
965 return pAttr->GetTextColour();
966 } // end of wxTreeCtrl::GetItemTextColour
967
968 wxColour wxTreeCtrl::GetItemBackgroundColour (
969 const wxTreeItemId& rItem
970 ) const
971 {
972 long lId = (long)rItem.m_pItem;
973 wxTreeItemAttr* pAttr = (wxTreeItemAttr *)m_vAttrs.Get(lId);
974
975 if (!pAttr)
976 {
977 return wxNullColour;
978 }
979 return pAttr->GetBackgroundColour();
980 } // end of wxTreeCtrl::GetItemBackgroundColour
981
982 wxFont wxTreeCtrl::GetItemFont (
983 const wxTreeItemId& rItem
984 ) const
985 {
986 long lId = (long)rItem.m_pItem;
987 wxTreeItemAttr* pAttr = (wxTreeItemAttr *)m_vAttrs.Get(lId);
988
989 if (!pAttr)
990 {
991 return wxNullFont;
992 }
993 return pAttr->GetFont();
994 } // end of wxTreeCtrl::GetItemFont
995
996 void wxTreeCtrl::SetItemTextColour (
997 const wxTreeItemId& rItem
998 , const wxColour& rCol
999 )
1000 {
1001 m_bHasAnyAttr = true;
1002
1003 long lId = (long)rItem.m_pItem;
1004 wxTreeItemAttr* pAttr = (wxTreeItemAttr *)m_vAttrs.Get(lId);
1005
1006 if (!pAttr)
1007 {
1008 pAttr = new wxTreeItemAttr;
1009 m_vAttrs.Put(lId, (wxObject *)pAttr);
1010 }
1011 pAttr->SetTextColour(rCol);
1012 RefreshItem(rItem);
1013 } // end of wxTreeCtrl::SetItemTextColour
1014
1015 void wxTreeCtrl::SetItemBackgroundColour (
1016 const wxTreeItemId& rItem
1017 , const wxColour& rCol
1018 )
1019 {
1020 m_bHasAnyAttr = true;
1021
1022 long lId = (long)rItem.m_pItem;
1023 wxTreeItemAttr* pAttr = (wxTreeItemAttr *)m_vAttrs.Get(lId);
1024
1025 if (!pAttr)
1026 {
1027 pAttr = new wxTreeItemAttr;
1028 m_vAttrs.Put(lId, (wxObject *)pAttr);
1029 }
1030 pAttr->SetBackgroundColour(rCol);
1031 RefreshItem(rItem);
1032 } // end of wxTreeCtrl::SetItemBackgroundColour
1033
1034 void wxTreeCtrl::SetItemFont (
1035 const wxTreeItemId& rItem
1036 , const wxFont& rFont
1037 )
1038 {
1039 m_bHasAnyAttr = true;
1040
1041 long lId = (long)rItem.m_pItem;
1042 wxTreeItemAttr* pAttr = (wxTreeItemAttr *)m_vAttrs.Get(lId);
1043
1044 if (!pAttr)
1045 {
1046 pAttr = new wxTreeItemAttr;
1047 m_vAttrs.Put(lId, (wxObject *)pAttr);
1048 }
1049 pAttr->SetFont(rFont);
1050 RefreshItem(rItem);
1051 } // end of wxTreeCtrl::SetItemFont
1052
1053 // ----------------------------------------------------------------------------
1054 // Item status
1055 // ----------------------------------------------------------------------------
1056
1057 bool wxTreeCtrl::IsVisible (
1058 const wxTreeItemId& rItem
1059 ) const
1060 {
1061 // Bug in Gnu-Win32 headers, so don't use the macro TreeView_GetItemRect
1062 RECTL vRectRecord;
1063 RECTL vRectContainer;
1064 wxRect vWxRectRecord;
1065 wxRect vWxRectContainer;
1066 PMYRECORD pRecord = FindOS2TreeRecordByID ( GetHWND()
1067 ,rItem.m_pItem
1068 );
1069 QUERYRECORDRECT vQuery;
1070
1071 vQuery.cb = sizeof(QUERYRECORDRECT);
1072 vQuery.pRecord = (PRECORDCORE)pRecord;
1073 vQuery.fRightSplitWindow = FALSE;
1074 vQuery.fsExtent = CMA_TREEICON;
1075
1076 ::WinSendMsg( GetHWND()
1077 ,CM_QUERYVIEWPORTRECT
1078 ,MPFROMP(&vRectContainer)
1079 ,MPFROM2SHORT(CMA_WINDOW, FALSE)
1080 );
1081 ::WinSendMsg( GetHWND()
1082 ,CM_QUERYRECORDRECT
1083 ,MPFROMP(&vRectRecord)
1084 ,MPFROMP(&vQuery)
1085 );
1086 vWxRectRecord.SetLeft(vRectRecord.xLeft);
1087 vWxRectRecord.SetTop(vRectRecord.yTop);
1088 vWxRectRecord.SetRight(vRectRecord.xRight);
1089 vWxRectRecord.SetBottom(vRectRecord.yBottom);
1090
1091 vWxRectContainer.SetLeft(vRectContainer.xLeft);
1092 vWxRectContainer.SetTop(vRectContainer.yTop);
1093 vWxRectContainer.SetRight(vRectContainer.xRight);
1094 vWxRectContainer.SetBottom(vRectContainer.yBottom);
1095 return (vWxRectContainer.Inside(wxPoint(vWxRectRecord.x, vWxRectRecord.y)));
1096 } // end of wxTreeCtrl::IsVisible
1097
1098 bool wxTreeCtrl::ItemHasChildren (
1099 const wxTreeItemId& rItem
1100 ) const
1101 {
1102 wxTreeViewItem vTvItem(rItem);
1103 DoGetItem(&vTvItem);
1104
1105 //
1106 // A tree record with children will have one of these attributes
1107 //
1108 return (vTvItem.m_vRecord.flRecordAttr & CRA_EXPANDED ||
1109 vTvItem.m_vRecord.flRecordAttr & CRA_COLLAPSED) != 0;
1110 }
1111
1112 bool wxTreeCtrl::IsExpanded (
1113 const wxTreeItemId& rItem
1114 ) const
1115 {
1116 wxTreeViewItem vTvItem(rItem);
1117 DoGetItem(&vTvItem);
1118
1119 return (vTvItem.m_vRecord.flRecordAttr & CRA_EXPANDED) != 0;
1120 } // end of wxTreeCtrl::IsExpanded
1121
1122 bool wxTreeCtrl::IsSelected (
1123 const wxTreeItemId& rItem
1124 ) const
1125 {
1126 wxTreeViewItem vTvItem(rItem);
1127 DoGetItem(&vTvItem);
1128
1129 return (vTvItem.m_vRecord.flRecordAttr & CRA_SELECTED) != 0;
1130 } // end of wxTreeCtrl::IsSelected
1131
1132 // Not supported
1133 bool wxTreeCtrl::IsBold (
1134 const wxTreeItemId& rItem
1135 ) const
1136 {
1137 return false;
1138 } // end of wxTreeCtrl::IsBold
1139
1140 // ----------------------------------------------------------------------------
1141 // navigation
1142 // ----------------------------------------------------------------------------
1143
1144 wxTreeItemId wxTreeCtrl::GetRootItem () const
1145 {
1146 PMYRECORD pRecord = NULL;
1147
1148 pRecord = (PMYRECORD)PVOIDFROMMR(::WinSendMsg( GetHWND()
1149 ,CM_QUERYRECORD
1150 ,MPFROMP(pRecord)
1151 ,MPFROM2SHORT(CMA_FIRST, CMA_ITEMORDER)
1152 ));
1153
1154 if (!pRecord)
1155 return wxTreeItemId(-1L);
1156 return wxTreeItemId((long)pRecord->m_ulItemId);
1157 } // end of wxTreeCtrl::GetRootItem
1158
1159 wxTreeItemId wxTreeCtrl::GetSelection () const
1160 {
1161 wxCHECK_MSG( !(m_windowStyle & wxTR_MULTIPLE), (long)(WXHTREEITEM)0,
1162 wxT("this only works with single selection controls") );
1163
1164 PMYRECORD pRecord = NULL;
1165
1166 pRecord = (PMYRECORD)PVOIDFROMMR(::WinSendMsg( GetHWND()
1167 ,CM_QUERYRECORDEMPHASIS
1168 ,MPARAM(CMA_FIRST)
1169 ,MPARAM(CRA_SELECTED)
1170 ));
1171 if (!pRecord)
1172 return wxTreeItemId(-1L);
1173 return wxTreeItemId((long)pRecord->m_ulItemId);
1174 } // end of wxTreeCtrl::GetSelection
1175
1176 wxTreeItemId wxTreeCtrl::GetItemParent (
1177 const wxTreeItemId& rItem
1178 ) const
1179 {
1180 PMYRECORD pRecord = FindOS2TreeRecordByID ( GetHWND()
1181 ,rItem.m_pItem
1182 );
1183
1184 if (!pRecord)
1185 return wxTreeItemId(-1L);
1186 pRecord = (PMYRECORD)PVOIDFROMMR(::WinSendMsg( GetHWND()
1187 ,CM_QUERYRECORD
1188 ,MPFROMP(pRecord)
1189 ,MPFROM2SHORT(CMA_PARENT, CMA_ITEMORDER)
1190 ));
1191 if (!pRecord)
1192 return wxTreeItemId(-1L);
1193 return wxTreeItemId((long)pRecord->m_ulItemId);
1194 } // end of wxTreeCtrl::GetItemParent
1195
1196 wxTreeItemId wxTreeCtrl::GetFirstChild (
1197 const wxTreeItemId& rItem
1198 , long& rCookie
1199 ) const
1200 {
1201 PMYRECORD pRecord = FindOS2TreeRecordByID ( GetHWND()
1202 ,rItem.m_pItem
1203 );
1204
1205 if (!pRecord)
1206 return wxTreeItemId(-1L);
1207 pRecord = (PMYRECORD)PVOIDFROMMR(::WinSendMsg( GetHWND()
1208 ,CM_QUERYRECORD
1209 ,MPFROMP(pRecord)
1210 ,MPFROM2SHORT(CMA_FIRSTCHILD, CMA_ITEMORDER)
1211 ));
1212 if (!pRecord)
1213 return wxTreeItemId(-1L);
1214 //
1215 // Remember the last child returned in 'cookie'
1216 //
1217 rCookie = (long)pRecord->m_ulItemId;
1218 return wxTreeItemId(rCookie);
1219 } // end of wxTreeCtrl::GetFirstChild
1220
1221 wxTreeItemId wxTreeCtrl::GetNextChild (
1222 const wxTreeItemId& WXUNUSED(rItem)
1223 , long& rCookie
1224 ) const
1225 {
1226 PMYRECORD pRecord = FindOS2TreeRecordByID ( GetHWND()
1227 ,rCookie
1228 );
1229
1230 if (!pRecord)
1231 return wxTreeItemId(-1L);
1232 pRecord = (PMYRECORD)PVOIDFROMMR(::WinSendMsg( GetHWND()
1233 ,CM_QUERYRECORD
1234 ,MPFROMP(pRecord)
1235 ,MPFROM2SHORT(CMA_NEXT, CMA_ITEMORDER)
1236 ));
1237 if (!pRecord)
1238 return wxTreeItemId(-1L);
1239 rCookie = (long)pRecord->m_ulItemId;
1240 return wxTreeItemId(rCookie);
1241 } // end of wxTreeCtrl::GetNextChild
1242
1243 wxTreeItemId wxTreeCtrl::GetLastChild (
1244 const wxTreeItemId& rItem
1245 ) const
1246 {
1247 PMYRECORD pRecord = FindOS2TreeRecordByID ( GetHWND()
1248 ,rItem.m_pItem
1249 );
1250
1251 if (!pRecord)
1252 return wxTreeItemId(-1L);
1253 pRecord = (PMYRECORD)PVOIDFROMMR(::WinSendMsg( GetHWND()
1254 ,CM_QUERYRECORD
1255 ,MPFROMP(pRecord)
1256 ,MPFROM2SHORT(CMA_LASTCHILD, CMA_ITEMORDER)
1257 ));
1258 if (!pRecord)
1259 return wxTreeItemId(-1L);
1260 return wxTreeItemId((long)pRecord->m_ulItemId);
1261 } // end of wxTreeCtrl::GetLastChild
1262
1263 wxTreeItemId wxTreeCtrl::GetNextSibling (
1264 const wxTreeItemId& rItem
1265 ) const
1266 {
1267 PMYRECORD pRecord = FindOS2TreeRecordByID ( GetHWND()
1268 ,rItem.m_pItem
1269 );
1270
1271 if (!pRecord)
1272 return wxTreeItemId(-1L);
1273 pRecord = (PMYRECORD)PVOIDFROMMR(::WinSendMsg( GetHWND()
1274 ,CM_QUERYRECORD
1275 ,MPFROMP(pRecord)
1276 ,MPFROM2SHORT(CMA_NEXT, CMA_ITEMORDER)
1277 ));
1278 if (!pRecord)
1279 return wxTreeItemId(-1L);
1280 return wxTreeItemId((long)pRecord->m_ulItemId);
1281 } // end of wxTreeCtrl::GetNextSibling
1282
1283 wxTreeItemId wxTreeCtrl::GetPrevSibling (
1284 const wxTreeItemId& rItem
1285 ) const
1286 {
1287 PMYRECORD pRecord = FindOS2TreeRecordByID ( GetHWND()
1288 ,rItem.m_pItem
1289 );
1290
1291 if (!pRecord)
1292 return wxTreeItemId(-1L);
1293 pRecord = (PMYRECORD)PVOIDFROMMR(::WinSendMsg( GetHWND()
1294 ,CM_QUERYRECORD
1295 ,MPFROMP(pRecord)
1296 ,MPFROM2SHORT(CMA_PREV, CMA_ITEMORDER)
1297 ));
1298 if (!pRecord)
1299 return wxTreeItemId(-1L);
1300 return wxTreeItemId((long)pRecord->m_ulItemId);
1301 } // end of wxTreeCtrl::GetPrevSibling
1302
1303 wxTreeItemId wxTreeCtrl::GetFirstVisibleItem () const
1304 {
1305 PMYRECORD pRecord = (PMYRECORD)PVOIDFROMMR(::WinSendMsg( GetHWND()
1306 ,CM_QUERYRECORD
1307 ,MPFROMP(pRecord)
1308 ,MPFROM2SHORT(CMA_FIRST, CMA_ITEMORDER)
1309 ));
1310 if (!pRecord)
1311 return wxTreeItemId(-1L);
1312
1313 if (IsVisible(wxTreeItemId((long)pRecord->m_ulItemId)))
1314 return wxTreeItemId((long)pRecord->m_ulItemId);
1315 while(pRecord)
1316 {
1317 pRecord = (PMYRECORD)PVOIDFROMMR(::WinSendMsg( GetHWND()
1318 ,CM_QUERYRECORD
1319 ,MPFROMP(pRecord)
1320 ,MPFROM2SHORT(CMA_NEXT, CMA_ITEMORDER)
1321 ));
1322 if (!pRecord)
1323 return wxTreeItemId(-1L);
1324 if (IsVisible(wxTreeItemId((long)pRecord->m_ulItemId)))
1325 return wxTreeItemId((long)pRecord->m_ulItemId);
1326 }
1327 return wxTreeItemId(-1L);
1328 } // end of wxTreeCtrl::GetFirstVisibleItem
1329
1330 wxTreeItemId wxTreeCtrl::GetNextVisible (
1331 const wxTreeItemId& rItem
1332 ) const
1333 {
1334 wxASSERT_MSG(IsVisible(rItem), wxT("The item you call GetNextVisible() for must be visible itself!"));
1335
1336 PMYRECORD pRecord = FindOS2TreeRecordByID ( GetHWND()
1337 ,rItem.m_pItem
1338 );
1339
1340 if (!pRecord)
1341 return wxTreeItemId(-1L);
1342 while(pRecord)
1343 {
1344 pRecord = (PMYRECORD)PVOIDFROMMR(::WinSendMsg( GetHWND()
1345 ,CM_QUERYRECORD
1346 ,MPFROMP(pRecord)
1347 ,MPFROM2SHORT(CMA_NEXT, CMA_ITEMORDER)
1348 ));
1349 if (!pRecord)
1350 return wxTreeItemId(-1L);
1351 if (IsVisible(wxTreeItemId((long)pRecord->m_ulItemId)))
1352 return wxTreeItemId((long)pRecord->m_ulItemId);
1353 }
1354 return wxTreeItemId(-1L);
1355 } // end of wxTreeCtrl::GetNextVisible
1356
1357 wxTreeItemId wxTreeCtrl::GetPrevVisible (
1358 const wxTreeItemId& rItem
1359 ) const
1360 {
1361 wxASSERT_MSG( IsVisible(rItem), wxT("The item you call GetPrevVisible() for must be visible itself!"));
1362
1363 PMYRECORD pRecord = FindOS2TreeRecordByID ( GetHWND()
1364 ,rItem.m_pItem
1365 );
1366
1367 if (!pRecord)
1368 return wxTreeItemId(-1L);
1369 while(pRecord)
1370 {
1371 pRecord = (PMYRECORD)PVOIDFROMMR(::WinSendMsg( GetHWND()
1372 ,CM_QUERYRECORD
1373 ,MPFROMP(pRecord)
1374 ,MPFROM2SHORT(CMA_PREV, CMA_ITEMORDER)
1375 ));
1376 if (!pRecord)
1377 return wxTreeItemId(-1L);
1378 if (IsVisible(wxTreeItemId((long)pRecord->m_ulItemId)))
1379 return wxTreeItemId((long)pRecord->m_ulItemId);
1380 }
1381 return wxTreeItemId(-1L);
1382 } // end of wxTreeCtrl::GetPrevVisible
1383
1384 // ----------------------------------------------------------------------------
1385 // multiple selections emulation -- under OS/2 checked tree items is not
1386 // supported, but multisel is. So we'll just check for selections here.
1387 // ----------------------------------------------------------------------------
1388
1389 bool wxTreeCtrl::IsItemChecked (
1390 const wxTreeItemId& rItem
1391 ) const
1392 {
1393 wxTreeViewItem vTvItem(rItem);
1394
1395 DoGetItem(&vTvItem);
1396 return (vTvItem.m_vRecord.flRecordAttr & CRA_SELECTED);
1397 } // end of wxTreeCtrl::IsItemChecked
1398
1399 void wxTreeCtrl::SetItemCheck (
1400 const wxTreeItemId& rItem
1401 , bool bCheck
1402 )
1403 {
1404 wxTreeViewItem vTvItem(rItem);
1405
1406 DoGetItem(&vTvItem);
1407 ::WinSendMsg( GetHWND()
1408 ,CM_SETRECORDEMPHASIS
1409 ,MPFROMP(&vTvItem)
1410 ,MPFROM2SHORT(TRUE, CRA_SELECTED)
1411 );
1412 DoSetItem(&vTvItem);
1413 } // end of wxTreeCtrl::SetItemCheck
1414
1415 size_t wxTreeCtrl::GetSelections (
1416 wxArrayTreeItemIds& raSelections
1417 ) const
1418 {
1419 TraverseSelections vSelector( this
1420 ,raSelections
1421 );
1422 return vSelector.GetCount();
1423 } // end of wxTreeCtrl::GetSelections
1424
1425 // ----------------------------------------------------------------------------
1426 // Usual operations
1427 // ----------------------------------------------------------------------------
1428
1429 wxTreeItemId wxTreeCtrl::DoInsertItem (
1430 const wxTreeItemId& rParent
1431 , wxTreeItemId vInsertAfter
1432 , const wxString& rsText
1433 , int nImage
1434 , int selectedImage
1435 , wxTreeItemData* pData
1436 )
1437 {
1438 PMYRECORD pRecordAfter = FindOS2TreeRecordByID( GetHWND()
1439 ,vInsertAfter.m_pItem
1440 );
1441
1442 PMYRECORD pRecordParent = FindOS2TreeRecordByID( GetHWND()
1443 ,rParent.m_pItem
1444 );
1445
1446 PMYRECORD pRecord = (PMYRECORD)::WinSendMsg( GetHWND()
1447 ,CM_ALLOCRECORD
1448 ,MPFROMLONG(sizeof(MYRECORD) - sizeof(RECORDCORE))
1449 ,MPFROMLONG(1)
1450 );
1451 RECORDINSERT vInsert;
1452
1453 vInsert.cb = sizeof(RECORDINSERT);
1454 if (rParent.m_pItem == 0L)
1455 {
1456 if (vInsertAfter.m_pItem == -1)
1457 vInsert.pRecordOrder = (PRECORDCORE)CMA_END;
1458 else
1459 vInsert.pRecordOrder = (PRECORDCORE)CMA_FIRST;
1460 vInsert.pRecordParent = NULL;
1461 }
1462 else
1463 {
1464 if (vInsertAfter.m_pItem == 0)
1465 vInsert.pRecordOrder = (PRECORDCORE)CMA_FIRST;
1466 else if (vInsertAfter.m_pItem == -1)
1467 vInsert.pRecordOrder = (PRECORDCORE)CMA_END;
1468 else
1469 vInsert.pRecordOrder = (PRECORDCORE)pRecordAfter;
1470 vInsert.pRecordParent = (PRECORDCORE)pRecordParent;
1471 }
1472 vInsert.fInvalidateRecord = TRUE;
1473 vInsert.zOrder = CMA_TOP;
1474 vInsert.cRecordsInsert = 1;
1475
1476 pRecord->m_vRecord.pszTree = (wxChar*)rsText.c_str();
1477 pRecord->m_vRecord.hbmBitmap = nImage;
1478 pRecord->m_ulItemId = pRecordAfter->m_ulItemId + 1;
1479 if (pData != NULL)
1480 {
1481 pRecord->m_ulUserData = (ULONG)pData;
1482 }
1483 ::WinSendMsg( GetHWND()
1484 ,CM_INSERTRECORD
1485 ,MPFROMP(pRecord)
1486 ,MPFROMP(&vInsert)
1487 );
1488
1489 //
1490 // OS/2 must mannually bump the index's of following records
1491 //
1492 BumpTreeRecordIds( GetHWND()
1493 ,pRecord
1494 );
1495 if (pData != NULL)
1496 {
1497 //
1498 // Associate the application tree item with PM tree item handle
1499 //
1500 pData->SetId((long)pRecord->m_ulItemId);
1501 }
1502 return wxTreeItemId((long)pRecord->m_ulItemId);
1503 }
1504
1505 #if WXWIN_COMPATIBILITY_2_4
1506
1507 // for compatibility only
1508 wxTreeItemId wxTreeCtrl::InsertItem (
1509 const wxTreeItemId& rParent
1510 , const wxString& rsText
1511 , int nImage
1512 , int nSelImage
1513 , long lInsertAfter
1514 )
1515 {
1516 return DoInsertItem( rParent
1517 ,wxTreeItemId(lInsertAfter)
1518 ,rsText
1519 ,nImage
1520 ,nSelImage
1521 ,NULL
1522 );
1523 } // end of wxTreeCtrl::InsertItem
1524
1525 #endif // WXWIN_COMPATIBILITY_2_4
1526
1527 wxTreeItemId wxTreeCtrl::AddRoot (
1528 const wxString& rsText
1529 , int nImage
1530 , int nSelectedImage
1531 , wxTreeItemData* pData)
1532 {
1533
1534 return DoInsertItem( wxTreeItemId((long)0)
1535 ,wxTreeItemId((long)-1)
1536 ,rsText
1537 ,nImage
1538 ,nSelectedImage
1539 ,pData
1540 );
1541 } // end of wxTreeCtrl::AddRoot
1542
1543 wxTreeItemId wxTreeCtrl::PrependItem (
1544 const wxTreeItemId& rParent
1545 , const wxString& rsText
1546 , int nImage
1547 , int nSelectedImage
1548 , wxTreeItemData* pData
1549 )
1550 {
1551 return DoInsertItem( rParent
1552 ,wxTreeItemId((long)0)
1553 ,rsText
1554 ,nImage
1555 ,nSelectedImage
1556 ,pData
1557 );
1558 } // end of wxTreeCtrl::PrependItem
1559
1560 wxTreeItemId wxTreeCtrl::InsertItem (
1561 const wxTreeItemId& rParent
1562 , const wxTreeItemId& rIdPrevious
1563 , const wxString& rsText
1564 , int nImage
1565 , int nSelectedImage
1566 , wxTreeItemData* pData
1567 )
1568 {
1569 return DoInsertItem( rParent
1570 ,rIdPrevious
1571 ,rsText
1572 ,nImage
1573 ,nSelectedImage
1574 ,pData
1575 );
1576 } // end of wxTreeCtrl::InsertItem
1577
1578 wxTreeItemId wxTreeCtrl::InsertItem (
1579 const wxTreeItemId& rParent
1580 , size_t nIndex
1581 , const wxString& rsText
1582 , int nImage
1583 , int nSelectedImage
1584 , wxTreeItemData* pData
1585 )
1586 {
1587 return DoInsertItem( rParent
1588 ,wxTreeItemId((long)nIndex)
1589 ,rsText
1590 ,nImage
1591 ,nSelectedImage
1592 ,pData
1593 );
1594 } // end of wxTreeCtrl::InsertItem
1595
1596 wxTreeItemId wxTreeCtrl::AppendItem (
1597 const wxTreeItemId& rParent
1598 , const wxString& rsText
1599 , int nImage
1600 , int nSelectedImage
1601 , wxTreeItemData* pData
1602 )
1603 {
1604 return DoInsertItem( rParent
1605 ,wxTreeItemId((long)-1)
1606 ,rsText
1607 ,nImage
1608 ,nSelectedImage
1609 ,pData
1610 );
1611 } // end of wxTreeCtrl::AppendItem
1612
1613 void wxTreeCtrl::Delete (
1614 const wxTreeItemId& rItem
1615 )
1616 {
1617 //
1618 // OS/2 does not generate DELETEITEM events so do it here
1619 //
1620 wxEventType vEventType = wxEVT_NULL;
1621 wxTreeEvent vEvent( wxEVT_NULL
1622 ,m_windowId
1623 );
1624 PMYRECORD pRecord = FindOS2TreeRecordByID( GetHWND()
1625 ,rItem.m_pItem
1626 );
1627 vEvent.SetEventObject(this);
1628 ::WinSendMsg( GetHWND()
1629 ,CM_REMOVERECORD
1630 ,MPFROMP(pRecord)
1631 ,(MPARAM)(CMA_FREE | CMA_INVALIDATE)
1632 );
1633 vEvent.m_item = rItem.m_pItem;
1634 if (m_bHasAnyAttr)
1635 {
1636 delete (wxTreeItemAttr *)m_vAttrs.Delete((long)rItem.m_pItem);
1637 }
1638 vEvent.SetEventType(vEventType);
1639 GetEventHandler()->ProcessEvent(vEvent);
1640 } // end of wxTreeCtrl::Delete
1641
1642 // delete all children (but don't delete the item itself)
1643 void wxTreeCtrl::DeleteChildren (
1644 const wxTreeItemId& rItem
1645 )
1646 {
1647 long lCookie;
1648 wxArrayLong aChildren;
1649 wxTreeItemId vChild = GetFirstChild( rItem
1650 ,lCookie
1651 );
1652
1653 while (vChild.IsOk())
1654 {
1655 aChildren.Add((long)(WXHTREEITEM)vChild);
1656 vChild = GetNextChild( rItem
1657 ,lCookie
1658 );
1659 }
1660
1661 size_t nCount = aChildren.Count();
1662
1663 for (size_t n = 0; n < nCount; n++)
1664 {
1665 Delete(aChildren[n]);
1666 }
1667 } // end of wxTreeCtrl::DeleteChildren
1668
1669 void wxTreeCtrl::DeleteAllItems ()
1670 {
1671 ::WinSendMsg( GetHWND()
1672 ,CM_REMOVERECORD
1673 ,NULL // Remove all
1674 ,(MPARAM)(CMA_FREE | CMA_INVALIDATE)
1675 );
1676 } // end of wxTreeCtrl::DeleteAllItems
1677
1678 void wxTreeCtrl::DoExpand (
1679 const wxTreeItemId& rItem
1680 , int nFlag
1681 )
1682 {
1683 PMYRECORD pRecord = FindOS2TreeRecordByID( GetHWND()
1684 ,rItem.m_pItem
1685 );
1686 switch(nFlag)
1687 {
1688 case wxTREE_EXPAND_EXPAND:
1689 ::WinSendMsg( GetHWND()
1690 ,CM_EXPANDTREE
1691 ,MPFROMP(pRecord)
1692 ,NULL
1693 );
1694 break;
1695
1696 case wxTREE_EXPAND_COLLAPSE:
1697 ::WinSendMsg( GetHWND()
1698 ,CM_COLLAPSETREE
1699 ,MPFROMP(pRecord)
1700 ,NULL
1701 );
1702 break;
1703
1704 case wxTREE_EXPAND_COLLAPSE_RESET:
1705 ::WinSendMsg( GetHWND()
1706 ,CM_COLLAPSETREE
1707 ,MPFROMP(pRecord)
1708 ,NULL
1709 );
1710 DeleteChildren(rItem);
1711 break;
1712
1713 case wxTREE_EXPAND_TOGGLE:
1714 if (pRecord->m_vRecord.flRecordAttr & CRA_COLLAPSED)
1715 ::WinSendMsg( GetHWND()
1716 ,CM_EXPANDTREE
1717 ,MPFROMP(pRecord)
1718 ,NULL
1719 );
1720 else if (pRecord->m_vRecord.flRecordAttr & CRA_EXPANDED)
1721 ::WinSendMsg( GetHWND()
1722 ,CM_COLLAPSETREE
1723 ,MPFROMP(pRecord)
1724 ,NULL
1725 );
1726 break;
1727
1728 }
1729 } // end of wxTreeCtrl::DoExpand
1730
1731 void wxTreeCtrl::Expand (
1732 const wxTreeItemId& rItem
1733 )
1734 {
1735 DoExpand( rItem
1736 ,wxTREE_EXPAND_EXPAND
1737 );
1738 } // end of wxTreeCtrl::Expand
1739
1740 void wxTreeCtrl::Collapse (
1741 const wxTreeItemId& rItem
1742 )
1743 {
1744 DoExpand( rItem
1745 ,wxTREE_EXPAND_COLLAPSE
1746 );
1747 } // end of wxTreeCtrl::Collapse
1748
1749 void wxTreeCtrl::CollapseAndReset (
1750 const wxTreeItemId& rItem
1751 )
1752 {
1753 DoExpand( rItem
1754 ,wxTREE_EXPAND_COLLAPSE_RESET
1755 );
1756 } // end of wxTreeCtrl::CollapseAndReset
1757
1758 void wxTreeCtrl::Toggle (
1759 const wxTreeItemId& rItem
1760 )
1761 {
1762 DoExpand( rItem
1763 ,wxTREE_EXPAND_TOGGLE
1764 );
1765 } // end of wxTreeCtrl::Toggle
1766
1767 #if WXWIN_COMPATIBILITY_2_4
1768
1769 void wxTreeCtrl::ExpandItem (
1770 const wxTreeItemId& rItem
1771 , int nAction
1772 )
1773 {
1774 DoExpand( rItem
1775 ,nAction
1776 );
1777 } // end of wxTreeCtrl::ExpandItem
1778
1779 #endif // WXWIN_COMPATIBILITY_2_4
1780
1781 void wxTreeCtrl::Unselect ()
1782 {
1783 wxASSERT_MSG( !(m_windowStyle & wxTR_MULTIPLE),
1784 wxT("doesn't make sense, may be you want UnselectAll()?") );
1785
1786 //
1787 // Just remove the selection
1788 //
1789 SelectItem(wxTreeItemId((long)0));
1790 } // end of wxTreeCtrl::Unselect
1791
1792 void wxTreeCtrl::UnselectAll ()
1793 {
1794 if (m_windowStyle & wxTR_MULTIPLE)
1795 {
1796 wxArrayTreeItemIds aSelections;
1797 size_t nCount = GetSelections(aSelections);
1798
1799 for (size_t n = 0; n < nCount; n++)
1800 {
1801 SetItemCheck( aSelections[n]
1802 ,false
1803 );
1804 }
1805 }
1806 else
1807 {
1808 //
1809 // Just remove the selection
1810 //
1811 Unselect();
1812 }
1813 } // end of wxTreeCtrl::UnselectAll
1814
1815 void wxTreeCtrl::SelectItem (
1816 const wxTreeItemId& rItem
1817 )
1818 {
1819 SetItemCheck(rItem);
1820 } // end of wxTreeCtrl::SelectItem
1821
1822 void wxTreeCtrl::EnsureVisible (
1823 const wxTreeItemId& rItem
1824 )
1825 {
1826 wxTreeViewItem vTvItem(rItem);
1827
1828 DoGetItem(&vTvItem);
1829 if (!::WinSendMsg( GetHWND()
1830 ,CM_INVALIDATERECORD
1831 ,MPFROMP(&vTvItem)
1832 ,MPFROM2SHORT(1, CMA_ERASE | CMA_REPOSITION | CMA_TEXTCHANGED)
1833 ));
1834 } // end of wxTreeCtrl::EnsureVisible
1835
1836 void wxTreeCtrl::ScrollTo (
1837 const wxTreeItemId& rItem
1838 )
1839 {
1840 wxTreeViewItem vTvItem(rItem);
1841
1842 DoGetItem(&vTvItem);
1843 if (!::WinSendMsg( GetHWND()
1844 ,CM_INVALIDATERECORD
1845 ,MPFROMP(&vTvItem)
1846 ,MPFROM2SHORT(1, CMA_ERASE | CMA_REPOSITION | CMA_TEXTCHANGED)
1847 ));
1848 }
1849
1850 wxTextCtrl* wxTreeCtrl::EditLabel (
1851 const wxTreeItemId& rItem
1852 , wxClassInfo* WXUNUSED(pTextControlClass)
1853 )
1854 {
1855 CNREDITDATA vEdit;
1856 PMYRECORD pRecord = FindOS2TreeRecordByID( GetHWND()
1857 ,rItem.m_pItem
1858 );
1859
1860 vEdit.cb = sizeof(CNREDITDATA);
1861 vEdit.hwndCnr = GetHWND();
1862 vEdit.pRecord = &pRecord->m_vRecord;
1863 vEdit.pFieldInfo = NULL;
1864 vEdit.ppszText = NULL;
1865 vEdit.cbText = 0;
1866 vEdit.id = 0;
1867
1868 ::WinSendMsg( GetHWND()
1869 ,CM_OPENEDIT
1870 ,MPFROMP(&vEdit)
1871 ,(MPARAM)0
1872 );
1873 return NULL;
1874 } // end of wxTreeCtrl::EditLabel
1875
1876 // End label editing, optionally cancelling the edit
1877 void wxTreeCtrl::EndEditLabel (
1878 const wxTreeItemId& WXUNUSED(rItem)
1879 , bool WXUNUSED(bDiscardChanges)
1880 )
1881 {
1882 ::WinSendMsg( GetHWND()
1883 ,CM_CLOSEEDIT
1884 ,(MPARAM)0
1885 ,(MPARAM)0
1886 );
1887 } // end of wxTreeCtrl::EndEditLabel
1888
1889 wxTreeItemId wxTreeCtrl::HitTest (
1890 const wxPoint& rPoint
1891 , int& WXUNUSED(rFlags)
1892 )
1893 {
1894 PMYRECORD pRecord = NULL;
1895 QUERYRECFROMRECT vQueryRect;
1896 RECTL vRect;
1897 long lHeight;
1898
1899 //
1900 // Get height for OS/2 point conversion
1901 //
1902 ::WinSendMsg( GetHWND()
1903 ,CM_QUERYVIEWPORTRECT
1904 ,MPFROMP(&vRect)
1905 ,MPFROM2SHORT(CMA_WINDOW, TRUE)
1906 );
1907 lHeight = vRect.yTop - vRect.yBottom;
1908
1909 //
1910 // For now just try and get a record in the general vicinity and forget
1911 // the flag
1912 //
1913 vRect.xLeft = rPoint.x - 2;
1914 vRect.xRight = rPoint.x + 2;
1915 vRect.yTop = (lHeight - rPoint.y) + 2;
1916 vRect.yBottom = (lHeight - rPoint.y) - 2;
1917
1918 vQueryRect.cb = sizeof(QUERYRECFROMRECT);
1919 vQueryRect.rect = vRect;
1920 vQueryRect.fsSearch = CMA_PARTIAL;
1921
1922 pRecord = (PMYRECORD)::WinSendMsg( GetHWND()
1923 ,CM_QUERYRECORDFROMRECT
1924 ,(MPARAM)CMA_FIRST
1925 ,MPFROMP(&vQueryRect)
1926 );
1927
1928 if (!pRecord)
1929 return -1L;
1930 return wxTreeItemId((long)pRecord->m_ulItemId);
1931 } // end of wxTreeCtrl::HitTest
1932
1933 bool wxTreeCtrl::GetBoundingRect (
1934 const wxTreeItemId& rItem
1935 , wxRect& rRect
1936 , bool bTextOnly
1937 ) const
1938 {
1939 RECTL vRectRecord;
1940 PMYRECORD pRecord = FindOS2TreeRecordByID ( GetHWND()
1941 ,rItem.m_pItem
1942 );
1943 QUERYRECORDRECT vQuery;
1944
1945 vQuery.cb = sizeof(QUERYRECORDRECT);
1946 vQuery.pRecord = (PRECORDCORE)pRecord;
1947 vQuery.fRightSplitWindow = FALSE;
1948 if (bTextOnly)
1949 vQuery.fsExtent = CMA_TEXT;
1950 else
1951 vQuery.fsExtent = CMA_TREEICON | CMA_TEXT;
1952
1953 if (!::WinSendMsg( GetHWND()
1954 ,CM_QUERYRECORDRECT
1955 ,MPFROMP(&vRectRecord)
1956 ,MPFROMP(&vQuery)
1957 ))
1958 return false;
1959 rRect.SetLeft(vRectRecord.xLeft);
1960 rRect.SetTop(vRectRecord.yTop);
1961 rRect.SetRight(vRectRecord.xRight);
1962 rRect.SetBottom(vRectRecord.yBottom);
1963 return true;
1964 } // end of wxTreeCtrl::GetBoundingRect
1965
1966 // ----------------------------------------------------------------------------
1967 // sorting stuff
1968 // ----------------------------------------------------------------------------
1969
1970 SHORT EXPENTRY InternalDataCompareTreeFunc (
1971 PMYRECORD p1
1972 , PMYRECORD p2
1973 , PVOID pStorage
1974 )
1975 {
1976 wxCHECK_MSG( p1 && p2, 0,
1977 wxT("sorting tree without data doesn't make sense") );
1978
1979 wxTreeCtrl* pTree = (wxTreeCtrl*)pStorage;
1980
1981 return pTree->OnCompareItems( p1->m_ulItemId
1982 ,p2->m_ulItemId
1983 );
1984 } // end of wxTreeSortHelper::Compare
1985
1986 int wxTreeCtrl::OnCompareItems (
1987 const wxTreeItemId& rItem1
1988 , const wxTreeItemId& rItem2
1989 )
1990 {
1991 return wxStrcmp( GetItemText(rItem1)
1992 ,GetItemText(rItem2)
1993 );
1994 } // end of wxTreeCtrl::OnCompareItems
1995
1996 void wxTreeCtrl::SortChildren (
1997 const wxTreeItemId& rItem
1998 )
1999 {
2000 ::WinSendMsg( GetHWND()
2001 ,CM_SORTRECORD
2002 ,(PFN)InternalDataCompareTreeFunc
2003 ,NULL
2004 );
2005 } // end of wxTreeCtrl::SortChildren
2006
2007 // ----------------------------------------------------------------------------
2008 // implementation
2009 // ----------------------------------------------------------------------------
2010
2011 bool wxTreeCtrl::OS2Command (
2012 WXUINT uCmd
2013 , WXWORD wId
2014 )
2015 {
2016 if (uCmd == CN_ENDEDIT)
2017 {
2018 wxCommandEvent vEvent( wxEVT_COMMAND_TEXT_UPDATED
2019 ,wId
2020 );
2021
2022 vEvent.SetEventObject( this );
2023 ProcessCommand(vEvent);
2024 return true;
2025 }
2026 else if (uCmd == CN_KILLFOCUS)
2027 {
2028 wxCommandEvent vEvent( wxEVT_KILL_FOCUS
2029 ,wId
2030 );
2031 vEvent.SetEventObject( this );
2032 ProcessCommand(vEvent);
2033 return true;
2034 }
2035 else
2036 return false;
2037 } // end of wxTreeCtrl::OS2Command
2038
2039 //
2040 // TODO: Fully implement direct manipulation when I figure it out
2041 //
2042 MRESULT wxTreeCtrl::OS2WindowProc (
2043 WXUINT uMsg
2044 , WXWPARAM wParam
2045 , WXLPARAM lParam
2046 )
2047 {
2048 bool bProcessed = false;
2049 MRESULT mRc = 0;
2050 wxTreeEvent vEvent( wxEVT_NULL
2051 ,m_windowId
2052 );
2053 wxEventType vEventType = wxEVT_NULL;
2054 PCNRDRAGINIT pDragInit = NULL;
2055 PCNREDITDATA pEditData = NULL;
2056 PNOTIFYRECORDENTER pNotifyEnter = NULL;
2057
2058 vEvent.SetEventObject(this);
2059 switch (uMsg)
2060 {
2061 case WM_CONTROL:
2062 switch(SHORT2FROMMP(wParam))
2063 {
2064 case CN_INITDRAG:
2065 pDragInit = (PCNRDRAGINIT)lParam;
2066 if (pDragInit)
2067 {
2068 PMYRECORD pRecord = (PMYRECORD)pDragInit->pRecord;
2069
2070 vEventType = wxEVT_COMMAND_TREE_BEGIN_DRAG;
2071 vEvent.m_item = pRecord->m_ulItemId;
2072 vEvent.m_pointDrag.x = pDragInit->x;
2073 vEvent.m_pointDrag.y = pDragInit->y;
2074 }
2075 break;
2076
2077 case CN_BEGINEDIT:
2078 pEditData = (PCNREDITDATA)lParam;
2079 if (pEditData)
2080 {
2081 PMYRECORD pRecord = (PMYRECORD)pEditData->pRecord;
2082
2083 vEventType = wxEVT_COMMAND_TREE_BEGIN_LABEL_EDIT;
2084 vEvent.m_item = pRecord->m_ulItemId;
2085 vEvent.m_label = pRecord->m_vRecord.pszTree;
2086 vEvent.m_editCancelled = false;
2087 }
2088 break;
2089
2090 case CN_ENDEDIT:
2091 pEditData = (PCNREDITDATA)lParam;
2092 if (pEditData)
2093 {
2094 PMYRECORD pRecord = (PMYRECORD)pEditData->pRecord;
2095
2096 vEventType = wxEVT_COMMAND_TREE_END_LABEL_EDIT;
2097 vEvent.m_item = pRecord->m_ulItemId;
2098 vEvent.m_label = pRecord->m_vRecord.pszTree;
2099 if (pRecord->m_vRecord.pszTree == NULL)
2100 {
2101 vEvent.m_editCancelled = true;
2102 }
2103 else
2104 {
2105 vEvent.m_editCancelled = false;
2106 }
2107 }
2108 break;
2109
2110 case CN_EXPANDTREE:
2111 {
2112 PMYRECORD pRecord = (PMYRECORD)lParam;
2113
2114 vEventType = gs_expandEvents[IDX_EXPAND][IDX_DONE];
2115 vEvent.m_item = pRecord->m_ulItemId;
2116 }
2117 break;
2118 }
2119 vEvent.SetEventType(vEventType);
2120 bProcessed = GetEventHandler()->ProcessEvent(vEvent);
2121 break;
2122 }
2123 if (!bProcessed)
2124 mRc = wxControl::OS2WindowProc( uMsg
2125 ,wParam
2126 ,lParam
2127 );
2128 return mRc;
2129 } // end of wxTreeCtrl::OS2WindowProc
2130
2131 #if WXWIN_COMPATIBILITY_2_2
2132
2133 wxTreeItemId wxTreeCtrl::GetParent(const wxTreeItemId& item) const
2134 {
2135 return GetItemParent( item );
2136 }
2137
2138 #endif // WXWIN_COMPATIBILITY_2_2
2139
2140 #endif // wxUSE_TREECTRL