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