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