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