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