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