]> git.saurik.com Git - wxWidgets.git/blob - src/msw/treectrl.cpp
* Fixed a bug in notebook.tex
[wxWidgets.git] / src / msw / treectrl.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: treectrl.cpp
3 // Purpose: wxTreeCtrl
4 // Author: Julian Smart
5 // Modified by:
6 // Created: 1997
7 // RCS-ID: $Id$
8 // Copyright: (c) Julian Smart
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
11
12 #ifdef __GNUG__
13 #pragma implementation "treectrl.h"
14 #endif
15
16 // For compilers that support precompilation, includes "wx.h".
17 #include "wx/wxprec.h"
18
19 #ifdef __BORLANDC__
20 #pragma hdrstop
21 #endif
22
23 #ifndef WX_PRECOMP
24 #include "wx.h"
25 #endif
26
27 #include "wx/log.h"
28
29 #if defined(__WIN95__)
30
31 #include "wx/treectrl.h"
32 #include "wx/msw/private.h"
33
34 #ifndef __GNUWIN32__
35 #include <commctrl.h>
36 #endif
37
38 // Bug in headers, sometimes
39 #ifndef TVIS_FOCUSED
40 #define TVIS_FOCUSED 0x0001
41 #endif
42
43 static void wxConvertToMSWTreeItem(wxTreeItem& info, TV_ITEM& tvItem);
44 static void wxConvertFromMSWTreeItem(wxTreeItem& info, TV_ITEM& tvItem, HWND getFullInfo = 0);
45
46 #if !USE_SHARED_LIBRARY
47 IMPLEMENT_DYNAMIC_CLASS(wxTreeCtrl, wxControl)
48 IMPLEMENT_DYNAMIC_CLASS(wxTreeItem, wxObject)
49
50 #endif
51
52 wxTreeCtrl::wxTreeCtrl(void)
53 {
54 m_imageListNormal = NULL;
55 m_imageListState = NULL;
56 m_textCtrl = NULL;
57 }
58
59 bool wxTreeCtrl::Create(wxWindow *parent, wxWindowID id, const wxPoint& pos, const wxSize& size,
60 long style, const wxValidator& validator, const wxString& name)
61 {
62 wxSystemSettings settings;
63 SetBackgroundColour(settings.GetSystemColour(wxSYS_COLOUR_WINDOW));
64 SetForegroundColour(parent->GetDefaultForegroundColour());
65
66 SetName(name);
67 SetValidator(validator);
68
69 m_imageListNormal = NULL;
70 m_imageListState = NULL;
71 m_textCtrl = NULL;
72
73 int x = pos.x;
74 int y = pos.y;
75 int width = size.x;
76 int height = size.y;
77
78 m_windowStyle = style;
79
80 // SetFont(wxTheFontList->FindOrCreateFont(11, wxSWISS, wxNORMAL, wxNORMAL));
81
82 SetParent(parent);
83
84 if (width <= 0)
85 width = 100;
86 if (height <= 0)
87 height = 30;
88 if (x < 0)
89 x = 0;
90 if (y < 0)
91 y = 0;
92
93 m_windowId = (id == -1) ? NewControlId() : id;
94
95 DWORD wstyle = WS_VISIBLE | WS_CHILD | WS_TABSTOP | TVS_HASLINES;
96
97 bool want3D;
98 WXDWORD exStyle = Determine3DEffects(WS_EX_CLIENTEDGE, &want3D) ;
99
100 // Even with extended styles, need to combine with WS_BORDER
101 // for them to look right.
102 if (want3D || (m_windowStyle & wxSIMPLE_BORDER) || (m_windowStyle & wxRAISED_BORDER) ||
103 (m_windowStyle & wxSUNKEN_BORDER) || (m_windowStyle & wxDOUBLE_BORDER))
104 wstyle |= WS_BORDER;
105
106 if ( m_windowStyle & wxTR_HAS_BUTTONS )
107 wstyle |= TVS_HASBUTTONS;
108
109 if ( m_windowStyle & wxTR_EDIT_LABELS )
110 wstyle |= TVS_EDITLABELS;
111
112 if ( m_windowStyle & wxTR_LINES_AT_ROOT )
113 wstyle |= TVS_LINESATROOT;
114
115 // Create the toolbar control.
116 HWND hWndTreeControl = CreateWindowEx(exStyle,
117 WC_TREEVIEW,
118 "",
119 wstyle,
120 x, y, width, height,
121 (HWND) parent->GetHWND(),
122 (HMENU)m_windowId,
123 wxGetInstance(),
124 NULL );
125
126 m_hWnd = (WXHWND) hWndTreeControl;
127 if (parent) parent->AddChild(this);
128
129 SubclassWin((WXHWND) m_hWnd);
130
131 return TRUE;
132 }
133
134 wxTreeCtrl::~wxTreeCtrl(void)
135 {
136 if (m_textCtrl)
137 {
138 m_textCtrl->UnsubclassWin();
139 m_textCtrl->SetHWND((WXHWND) 0);
140 delete m_textCtrl;
141 }
142 }
143
144 // Attributes
145 int wxTreeCtrl::GetCount(void) const
146 {
147 return (int) TreeView_GetCount((HWND) GetHWND());
148 }
149
150 int wxTreeCtrl::GetIndent(void) const
151 {
152 return (int) TreeView_GetIndent((HWND) GetHWND());
153 }
154
155 void wxTreeCtrl::SetIndent(int indent)
156 {
157 TreeView_SetIndent((HWND) GetHWND(), indent);
158 }
159
160 wxImageList *wxTreeCtrl::GetImageList(int which) const
161 {
162 if ( which == wxIMAGE_LIST_NORMAL )
163 {
164 return m_imageListNormal;
165 }
166 else if ( which == wxIMAGE_LIST_STATE )
167 {
168 return m_imageListState;
169 }
170 return NULL;
171 }
172
173 void wxTreeCtrl::SetImageList(wxImageList *imageList, int which)
174 {
175 int flags = 0;
176 if ( which == wxIMAGE_LIST_NORMAL )
177 {
178 flags = TVSIL_NORMAL;
179 m_imageListNormal = imageList;
180 }
181 else if ( which == wxIMAGE_LIST_STATE )
182 {
183 flags = TVSIL_STATE;
184 m_imageListState = imageList;
185 }
186 TreeView_SetImageList((HWND) GetHWND(), (HIMAGELIST) imageList ? imageList->GetHIMAGELIST() : 0, flags);
187 }
188
189 long wxTreeCtrl::GetNextItem(long item, int code) const
190 {
191 UINT flag = 0;
192 switch ( code )
193 {
194 case wxTREE_NEXT_CARET:
195 flag = TVGN_CARET;
196 break;
197 case wxTREE_NEXT_CHILD:
198 flag = TVGN_CHILD;
199 break;
200 case wxTREE_NEXT_DROPHILITE:
201 flag = TVGN_DROPHILITE;
202 break;
203 case wxTREE_NEXT_FIRSTVISIBLE:
204 flag = TVGN_FIRSTVISIBLE;
205 break;
206 case wxTREE_NEXT_NEXT:
207 flag = TVGN_NEXT;
208 break;
209 case wxTREE_NEXT_NEXTVISIBLE:
210 flag = TVGN_NEXTVISIBLE;
211 break;
212 case wxTREE_NEXT_PARENT:
213 flag = TVGN_PARENT;
214 break;
215 case wxTREE_NEXT_PREVIOUS:
216 flag = TVGN_PREVIOUS;
217 break;
218 case wxTREE_NEXT_PREVIOUSVISIBLE:
219 flag = TVGN_PREVIOUSVISIBLE;
220 break;
221 case wxTREE_NEXT_ROOT:
222 flag = TVGN_ROOT;
223 break;
224
225 default :
226 break;
227 }
228 return (long) TreeView_GetNextItem( (HWND) GetHWND(), (HTREEITEM) item, flag);
229 }
230
231 bool wxTreeCtrl::ItemHasChildren(long item) const
232 {
233 TV_ITEM item2;
234 item2.hItem = (HTREEITEM) item;
235 item2.mask = TVIF_CHILDREN;
236 TreeView_GetItem((HWND) GetHWND(), &item2);
237 return (item2.cChildren != 0);
238 }
239
240 long wxTreeCtrl::GetChild(long item) const
241 {
242 return (long) ::SendMessage((HWND) GetHWND(), TVM_GETNEXTITEM, TVGN_CHILD, (LPARAM)item);
243 }
244
245 long wxTreeCtrl::GetParent(long item) const
246 {
247 return (long) ::SendMessage((HWND) GetHWND(), TVM_GETNEXTITEM, TVGN_PARENT, (LPARAM)item);
248 }
249
250 long wxTreeCtrl::GetFirstVisibleItem(void) const
251 {
252 return (long) ::SendMessage((HWND) GetHWND(), TVM_GETNEXTITEM, TVGN_FIRSTVISIBLE, 0);
253 }
254
255 long wxTreeCtrl::GetNextVisibleItem(long item) const
256 {
257 return (long) ::SendMessage((HWND) GetHWND(), TVM_GETNEXTITEM, TVGN_NEXTVISIBLE, (LPARAM)item);
258 }
259
260 long wxTreeCtrl::GetSelection(void) const
261 {
262 return (long) ::SendMessage((HWND) GetHWND(), TVM_GETNEXTITEM, TVGN_CARET, 0);
263 }
264
265 long wxTreeCtrl::GetRootItem(void) const
266 {
267 return (long) ::SendMessage((HWND) GetHWND(), TVM_GETNEXTITEM, TVGN_ROOT, 0);
268 }
269
270 bool wxTreeCtrl::GetItem(wxTreeItem& info) const
271 {
272 TV_ITEM tvItem;
273 tvItem.hItem = (HTREEITEM)info.m_itemId;
274 tvItem.pszText = NULL;
275 tvItem.mask =
276 tvItem.stateMask = 0;
277
278 // TODO: convert other bits in the mask
279 if ( info.m_mask & wxTREE_MASK_TEXT )
280 {
281 tvItem.mask |= TVIF_TEXT;
282 tvItem.pszText = new char[513];
283 tvItem.cchTextMax = 512;
284 }
285 if ( info.m_mask & wxTREE_MASK_DATA )
286 tvItem.mask |= TVIF_PARAM;
287 if ( info.m_stateMask & wxTREE_STATE_EXPANDED ) {
288 tvItem.mask |= TVIF_STATE;
289 tvItem.stateMask |= TVIS_EXPANDED;
290 }
291
292 bool success = TreeView_GetItem((HWND)GetHWND(), &tvItem) != 0;
293
294 if ( !success )
295 {
296 wxLogSysError("TreeView_GetItem failed");
297
298 if (tvItem.pszText)
299 delete[] tvItem.pszText;
300
301 return FALSE;
302 }
303
304 wxConvertFromMSWTreeItem(info, tvItem);
305
306 if (tvItem.pszText)
307 delete[] tvItem.pszText;
308
309 return success;
310 }
311
312 bool wxTreeCtrl::SetItem(wxTreeItem& info)
313 {
314 TV_ITEM item;
315 wxConvertToMSWTreeItem(info, item);
316 return (::SendMessage((HWND) GetHWND(), TVM_SETITEM, 0, (LPARAM)&item) != 0);
317 }
318
319 int wxTreeCtrl::GetItemState(long item, long stateMask) const
320 {
321 wxTreeItem info;
322
323 info.m_mask = wxTREE_MASK_STATE ;
324 info.m_stateMask = stateMask;
325 info.m_itemId = item;
326
327 if (!GetItem(info))
328 return 0;
329
330 return info.m_state;
331 }
332
333 bool wxTreeCtrl::SetItemState(long item, long state, long stateMask)
334 {
335 wxTreeItem info;
336
337 info.m_mask = wxTREE_MASK_STATE ;
338 info.m_state = state;
339 info.m_stateMask = stateMask;
340 info.m_itemId = item;
341
342 return SetItem(info);
343 }
344
345 bool wxTreeCtrl::SetItemImage(long item, int image, int selImage)
346 {
347 wxTreeItem info;
348
349 info.m_mask = wxTREE_MASK_IMAGE ;
350 info.m_image = image;
351 if ( selImage > -1)
352 {
353 info.m_selectedImage = selImage;
354 info.m_mask |= wxTREE_MASK_SELECTED_IMAGE;
355 }
356 info.m_itemId = item;
357
358 return SetItem(info);
359 }
360
361 wxString wxTreeCtrl::GetItemText(long item) const
362 {
363 wxTreeItem info;
364
365 info.m_mask = wxTREE_MASK_TEXT ;
366 info.m_itemId = item;
367
368 if (!GetItem(info))
369 return wxString("");
370 return info.m_text;
371 }
372
373 void wxTreeCtrl::SetItemText(long item, const wxString& str)
374 {
375 wxTreeItem info;
376
377 info.m_mask = wxTREE_MASK_TEXT ;
378 info.m_itemId = item;
379 info.m_text = str;
380
381 SetItem(info);
382 }
383
384 long wxTreeCtrl::GetItemData(long item) const
385 {
386 wxTreeItem info;
387
388 info.m_mask = wxTREE_MASK_DATA ;
389 info.m_itemId = item;
390
391 if (!GetItem(info))
392 return 0;
393 return info.m_data;
394 }
395
396 bool wxTreeCtrl::SetItemData(long item, long data)
397 {
398 wxTreeItem info;
399
400 info.m_mask = wxTREE_MASK_DATA ;
401 info.m_itemId = item;
402 info.m_data = data;
403
404 return SetItem(info);
405 }
406
407 bool wxTreeCtrl::GetItemRect(long item, wxRectangle& rect, bool textOnly) const
408 {
409 RECT rect2;
410
411 *(HTREEITEM*)& rect2 = (HTREEITEM) item;
412 bool success = (::SendMessage((HWND) GetHWND(), TVM_GETITEMRECT, (WPARAM)textOnly,
413 (LPARAM)&rect2) != 0);
414
415 rect.x = rect2.left;
416 rect.y = rect2.top;
417 rect.width = rect2.right - rect2.left;
418 rect.height = rect2.bottom - rect2.left;
419 return success;
420 }
421
422 wxTextCtrl* wxTreeCtrl::GetEditControl(void) const
423 {
424 return m_textCtrl;
425 }
426
427 // Operations
428 bool wxTreeCtrl::DeleteItem(long item)
429 {
430 return (TreeView_DeleteItem((HWND) GetHWND(), (HTREEITEM) item) != 0);
431 }
432
433 bool wxTreeCtrl::ExpandItem(long item, int action)
434 {
435 UINT mswAction = TVE_EXPAND;
436 switch ( action )
437 {
438 case wxTREE_EXPAND_EXPAND:
439 mswAction = TVE_EXPAND;
440 break;
441
442 case wxTREE_EXPAND_COLLAPSE:
443 mswAction = TVE_COLLAPSE;
444 break;
445
446 case wxTREE_EXPAND_COLLAPSE_RESET:
447 // @@@ it should also delete all the items! currently, if you do use this
448 // code your program will probaly crash. Feel free to remove this if
449 // it does work
450 wxFAIL_MSG("wxTREE_EXPAND_COLLAPSE_RESET probably doesn't work.");
451 mswAction = TVE_COLLAPSERESET;
452 break;
453
454 case wxTREE_EXPAND_TOGGLE:
455 mswAction = TVE_TOGGLE;
456 break;
457
458 default:
459 wxFAIL_MSG("unknown action in wxTreeCtrl::ExpandItem");
460 }
461
462 bool bOk = TreeView_Expand((HWND)GetHWND(), (HTREEITEM)item, mswAction) != 0;
463
464 // TreeView_Expand doesn't send TVN_EXPAND(ING) messages, so emulate them
465 if ( bOk ) {
466 wxTreeEvent event(wxEVT_NULL, m_windowId);
467 event.m_item.m_itemId = item;
468 event.m_item.m_mask =
469 event.m_item.m_stateMask = 0xffff; // get all
470 GetItem(event.m_item);
471
472 bool bIsExpanded = (event.m_item.m_state & wxTREE_STATE_EXPANDED) != 0;
473
474 event.m_code = action;
475 event.SetEventObject(this);
476
477 // @@@ return values of {EXPAND|COLLAPS}ING event handler is discarded
478 event.SetEventType(bIsExpanded ? wxEVT_COMMAND_TREE_ITEM_EXPANDING
479 : wxEVT_COMMAND_TREE_ITEM_COLLAPSING);
480 GetEventHandler()->ProcessEvent(event);
481
482 event.SetEventType(bIsExpanded ? wxEVT_COMMAND_TREE_ITEM_EXPANDED
483 : wxEVT_COMMAND_TREE_ITEM_COLLAPSED);
484 GetEventHandler()->ProcessEvent(event);
485 }
486
487 return bOk;
488 }
489
490 long wxTreeCtrl::InsertItem(long parent, wxTreeItem& info, long insertAfter)
491 {
492 TV_INSERTSTRUCT tvInsertStruct;
493 tvInsertStruct.hParent = (HTREEITEM) parent ;
494 tvInsertStruct.hInsertAfter = (HTREEITEM) insertAfter ;
495
496 wxConvertToMSWTreeItem(info, tvInsertStruct.item);
497
498 return (long) TreeView_InsertItem((HWND) GetHWND(), & tvInsertStruct);
499 }
500
501 long wxTreeCtrl::InsertItem(long parent, const wxString& label, int image, int selImage,
502 long insertAfter)
503 {
504 wxTreeItem info;
505 info.m_text = label;
506 info.m_mask = wxTREE_MASK_TEXT;
507 if ( image > -1 )
508 {
509 info.m_mask |= wxTREE_MASK_IMAGE | wxTREE_MASK_SELECTED_IMAGE;
510 info.m_image = image;
511 if ( selImage == -1 )
512 info.m_selectedImage = image;
513 else
514 info.m_selectedImage = selImage;
515 }
516
517 return InsertItem(parent, info, insertAfter);
518 }
519
520 bool wxTreeCtrl::SelectItem(long item)
521 {
522 return (TreeView_SelectItem((HWND) GetHWND(), (HTREEITEM) item) != 0);
523 }
524
525 bool wxTreeCtrl::ScrollTo(long item)
526 {
527 return (TreeView_SelectSetFirstVisible((HWND) GetHWND(), (HTREEITEM) item) != 0);
528 }
529
530 bool wxTreeCtrl::DeleteAllItems(void)
531 {
532 return (TreeView_DeleteAllItems((HWND) GetHWND()) != 0);
533 }
534
535 wxTextCtrl* wxTreeCtrl::EditLabel(long item, wxClassInfo* textControlClass)
536 {
537 wxASSERT( (textControlClass->IsKindOf(CLASSINFO(wxTextCtrl))) );
538
539 HWND hWnd = (HWND) TreeView_EditLabel((HWND) GetHWND(), item);
540
541 if (m_textCtrl)
542 {
543 m_textCtrl->UnsubclassWin();
544 m_textCtrl->SetHWND(0);
545 delete m_textCtrl;
546 m_textCtrl = NULL;
547 }
548
549 m_textCtrl = (wxTextCtrl*) textControlClass->CreateObject();
550 m_textCtrl->SetHWND((WXHWND) hWnd);
551 m_textCtrl->SubclassWin((WXHWND) hWnd);
552
553 return m_textCtrl;
554 }
555
556 // End label editing, optionally cancelling the edit
557 bool wxTreeCtrl::EndEditLabel(bool cancel)
558 {
559 bool success = (TreeView_EndEditLabelNow((HWND) GetHWND(), cancel) != 0);
560
561 if (m_textCtrl)
562 {
563 m_textCtrl->UnsubclassWin();
564 m_textCtrl->SetHWND(0);
565 delete m_textCtrl;
566 m_textCtrl = NULL;
567 }
568 return success;
569 }
570
571 long wxTreeCtrl::HitTest(const wxPoint& point, int& flags)
572 {
573 TV_HITTESTINFO hitTestInfo;
574 hitTestInfo.pt.x = (int) point.x;
575 hitTestInfo.pt.y = (int) point.y;
576
577 TreeView_HitTest((HWND) GetHWND(), & hitTestInfo);
578
579 flags = 0;
580 if ( hitTestInfo.flags & TVHT_ABOVE )
581 flags |= wxTREE_HITTEST_ABOVE;
582 if ( hitTestInfo.flags & TVHT_BELOW )
583 flags |= wxTREE_HITTEST_BELOW;
584 if ( hitTestInfo.flags & TVHT_NOWHERE )
585 flags |= wxTREE_HITTEST_NOWHERE;
586 if ( hitTestInfo.flags & TVHT_ONITEMBUTTON )
587 flags |= wxTREE_HITTEST_ONITEMBUTTON;
588 if ( hitTestInfo.flags & TVHT_ONITEMICON )
589 flags |= wxTREE_HITTEST_ONITEMICON;
590 if ( hitTestInfo.flags & TVHT_ONITEMINDENT )
591 flags |= wxTREE_HITTEST_ONITEMINDENT;
592 if ( hitTestInfo.flags & TVHT_ONITEMLABEL )
593 flags |= wxTREE_HITTEST_ONITEMLABEL;
594 if ( hitTestInfo.flags & TVHT_ONITEMRIGHT )
595 flags |= wxTREE_HITTEST_ONITEMRIGHT;
596 if ( hitTestInfo.flags & TVHT_ONITEMSTATEICON )
597 flags |= wxTREE_HITTEST_ONITEMSTATEICON;
598 if ( hitTestInfo.flags & TVHT_TOLEFT )
599 flags |= wxTREE_HITTEST_TOLEFT;
600 if ( hitTestInfo.flags & TVHT_TORIGHT )
601 flags |= wxTREE_HITTEST_TORIGHT;
602
603 return (long) hitTestInfo.hItem ;
604 }
605
606 /*
607 wxImageList *wxTreeCtrl::CreateDragImage(long item)
608 {
609 }
610 */
611
612 bool wxTreeCtrl::SortChildren(long item)
613 {
614 return (TreeView_SortChildren((HWND) GetHWND(), (HTREEITEM) item, 0) != 0);
615 }
616
617 bool wxTreeCtrl::EnsureVisible(long item)
618 {
619 return (TreeView_EnsureVisible((HWND) GetHWND(), (HTREEITEM) item) != 0);
620 }
621
622 bool wxTreeCtrl::MSWCommand(WXUINT cmd, WXWORD id)
623 {
624 if (cmd == EN_UPDATE)
625 {
626 wxCommandEvent event(wxEVT_COMMAND_TEXT_UPDATED, id);
627 event.SetEventObject( this );
628 ProcessCommand(event);
629 return TRUE;
630 }
631 else if (cmd == EN_KILLFOCUS)
632 {
633 wxCommandEvent event(wxEVT_KILL_FOCUS, id);
634 event.SetEventObject( this );
635 ProcessCommand(event);
636 return TRUE;
637 }
638 else return FALSE;
639 }
640
641 bool wxTreeCtrl::MSWNotify(WXWPARAM wParam, WXLPARAM lParam)
642 {
643 wxTreeEvent event(wxEVT_NULL, m_windowId);
644 wxEventType eventType = wxEVT_NULL;
645 NMHDR* hdr1 = (NMHDR*) lParam;
646 switch ( hdr1->code )
647 {
648 case TVN_BEGINDRAG:
649 {
650 eventType = wxEVT_COMMAND_TREE_BEGIN_DRAG;
651 NM_TREEVIEW* hdr = (NM_TREEVIEW*)lParam;
652 wxConvertFromMSWTreeItem(event.m_item, hdr->itemNew, (HWND) GetHWND());
653 event.m_pointDrag.x = hdr->ptDrag.x;
654 event.m_pointDrag.y = hdr->ptDrag.y;
655 break;
656 }
657 case TVN_BEGINLABELEDIT:
658 {
659 eventType = wxEVT_COMMAND_TREE_BEGIN_LABEL_EDIT;
660 TV_DISPINFO *info = (TV_DISPINFO *)lParam;
661 wxConvertFromMSWTreeItem(event.m_item, info->item, (HWND) GetHWND());
662 break;
663 }
664 case TVN_BEGINRDRAG:
665 {
666 eventType = wxEVT_COMMAND_TREE_BEGIN_RDRAG;
667 NM_TREEVIEW* hdr = (NM_TREEVIEW*)lParam;
668 wxConvertFromMSWTreeItem(event.m_item, hdr->itemNew, (HWND) GetHWND());
669 event.m_pointDrag.x = hdr->ptDrag.x;
670 event.m_pointDrag.y = hdr->ptDrag.y;
671 break;
672 }
673 case TVN_DELETEITEM:
674 {
675 eventType = wxEVT_COMMAND_TREE_DELETE_ITEM;
676 NM_TREEVIEW* hdr = (NM_TREEVIEW*)lParam;
677 wxConvertFromMSWTreeItem(event.m_item, hdr->itemOld, (HWND) GetHWND());
678 event.m_pointDrag.x = hdr->ptDrag.x;
679 event.m_pointDrag.y = hdr->ptDrag.y;
680 break;
681 }
682 case TVN_ENDLABELEDIT:
683 {
684 eventType = wxEVT_COMMAND_TREE_END_LABEL_EDIT;
685 TV_DISPINFO *info = (TV_DISPINFO *)lParam;
686 wxConvertFromMSWTreeItem(event.m_item, info->item, (HWND) GetHWND());
687 break;
688 }
689 case TVN_GETDISPINFO:
690 {
691 eventType = wxEVT_COMMAND_TREE_GET_INFO;
692 TV_DISPINFO *info = (TV_DISPINFO *)lParam;
693 wxConvertFromMSWTreeItem(event.m_item, info->item, (HWND) GetHWND());
694 break;
695 }
696 case TVN_ITEMEXPANDING:
697 {
698 NM_TREEVIEW* hdr = (NM_TREEVIEW*)lParam;
699 wxConvertFromMSWTreeItem(event.m_item, hdr->itemNew, (HWND) GetHWND());
700
701 switch ( hdr->action )
702 {
703 case TVE_EXPAND:
704 eventType = wxEVT_COMMAND_TREE_ITEM_EXPANDING;
705 break;
706
707 case TVE_COLLAPSE:
708 eventType = wxEVT_COMMAND_TREE_ITEM_COLLAPSING;
709 break;
710
711 case TVE_COLLAPSERESET:
712 case TVE_TOGGLE:
713 wxLogDebug("unexpected code in TVN_ITEMEXPANDING message");
714 break;
715 }
716 break;
717 }
718
719 case TVN_ITEMEXPANDED:
720 {
721 NM_TREEVIEW* hdr = (NM_TREEVIEW*)lParam;
722 wxConvertFromMSWTreeItem(event.m_item, hdr->itemNew, (HWND) GetHWND());
723 switch ( hdr->action )
724 {
725 case TVE_EXPAND:
726 eventType = wxEVT_COMMAND_TREE_ITEM_EXPANDED;
727 break;
728
729 case TVE_COLLAPSE:
730 eventType = wxEVT_COMMAND_TREE_ITEM_COLLAPSED;
731 break;
732
733 case TVE_COLLAPSERESET:
734 case TVE_TOGGLE:
735 wxLogDebug("unexpected code in TVN_ITEMEXPANDED message");
736 break;
737 }
738 break;
739 }
740 case TVN_KEYDOWN:
741 {
742 eventType = wxEVT_COMMAND_TREE_KEY_DOWN;
743 TV_KEYDOWN *info = (TV_KEYDOWN *)lParam;
744 event.m_code = wxCharCodeMSWToWX(info->wVKey);
745 break;
746 }
747 case TVN_SELCHANGED:
748 {
749 eventType = wxEVT_COMMAND_TREE_SEL_CHANGED;
750 NM_TREEVIEW* hdr = (NM_TREEVIEW*)lParam;
751 wxConvertFromMSWTreeItem(event.m_item, hdr->itemNew, (HWND) GetHWND());
752 event.m_oldItem = (long) hdr->itemNew.hItem;
753
754 break;
755 }
756 case TVN_SELCHANGING:
757 {
758 eventType = wxEVT_COMMAND_TREE_SEL_CHANGING;
759 NM_TREEVIEW* hdr = (NM_TREEVIEW*)lParam;
760 wxConvertFromMSWTreeItem(event.m_item, hdr->itemNew, (HWND) GetHWND());
761 event.m_oldItem = (long) hdr->itemNew.hItem;
762 break;
763 }
764 case TVN_SETDISPINFO:
765 {
766 eventType = wxEVT_COMMAND_TREE_SET_INFO;
767 TV_DISPINFO *info = (TV_DISPINFO *)lParam;
768 wxConvertFromMSWTreeItem(event.m_item, info->item, (HWND) GetHWND());
769 break;
770 }
771
772 default :
773 return wxControl::MSWNotify(wParam, lParam);
774 break;
775 }
776
777 event.SetEventObject(this);
778 event.SetEventType(eventType);
779
780 if ( !GetEventHandler()->ProcessEvent(event) )
781 return FALSE;
782
783 if (hdr1->code == TVN_GETDISPINFO)
784 {
785 TV_DISPINFO *info = (TV_DISPINFO *)lParam;
786 wxConvertToMSWTreeItem(event.m_item, info->item);
787 }
788
789 return TRUE;
790 }
791
792 // Tree item structure
793 wxTreeItem::wxTreeItem(void)
794 {
795 m_mask = 0;
796 m_itemId = 0;
797 m_state = 0;
798 m_stateMask = 0;
799 m_image = -1;
800 m_selectedImage = -1;
801 m_children = 0;
802 m_data = 0;
803 }
804
805 // If getFullInfo is TRUE, we explicitly query for more info if we haven't got it all.
806 static void wxConvertFromMSWTreeItem(wxTreeItem& info, TV_ITEM& tvItem, HWND getFullInfo)
807 {
808 info.m_data = tvItem.lParam;
809 info.m_mask = 0;
810 info.m_state = 0;
811 info.m_stateMask = 0;
812
813 long oldMask = tvItem.mask;
814
815 bool needText = FALSE;
816 if (getFullInfo != 0)
817 {
818 if ( tvItem.mask & TVIF_TEXT )
819 needText = FALSE;
820 else
821 needText = TRUE;
822
823 if ( needText )
824 {
825 tvItem.pszText = new char[513];
826 tvItem.cchTextMax = 512;
827 }
828 tvItem.mask |= TVIF_HANDLE | TVIF_STATE | TVIF_TEXT | TVIF_IMAGE | TVIF_SELECTEDIMAGE | TVIF_CHILDREN | TVIF_PARAM ;
829 ::SendMessage(getFullInfo, TVM_GETITEM, 0, (LPARAM)& tvItem) ;
830 }
831
832 if ( tvItem.mask & TVIF_HANDLE )
833 {
834 info.m_mask |= wxTREE_MASK_HANDLE;
835 info.m_itemId = (long) tvItem.hItem;
836 }
837 if ( tvItem.mask & TVIF_STATE )
838 {
839 info.m_mask |= wxTREE_MASK_STATE;
840 if ( tvItem.stateMask & TVIS_BOLD)
841 {
842 info.m_stateMask |= wxTREE_STATE_BOLD ;
843 if ( tvItem.state & TVIS_BOLD )
844 info.m_state |= wxTREE_STATE_BOLD ;
845 }
846
847 if ( tvItem.stateMask & TVIS_CUT)
848 {
849 info.m_stateMask |= wxTREE_STATE_CUT ;
850 if ( tvItem.state & TVIS_CUT )
851 info.m_state |= wxTREE_STATE_CUT ;
852 }
853
854 if ( tvItem.stateMask & TVIS_DROPHILITED)
855 {
856 info.m_stateMask |= wxTREE_STATE_DROPHILITED ;
857 if ( tvItem.state & TVIS_DROPHILITED )
858 info.m_state |= wxTREE_STATE_DROPHILITED ;
859 }
860 if ( tvItem.stateMask & TVIS_EXPANDED)
861 {
862 info.m_stateMask |= wxTREE_STATE_EXPANDED ;
863 if ( tvItem.state & TVIS_EXPANDED )
864 info.m_state |= wxTREE_STATE_EXPANDED ;
865 }
866 if ( tvItem.stateMask & TVIS_EXPANDEDONCE)
867 {
868 info.m_stateMask |= wxTREE_STATE_EXPANDEDONCE ;
869 if ( tvItem.state & TVIS_EXPANDEDONCE )
870 info.m_state |= wxTREE_STATE_EXPANDEDONCE ;
871 }
872 if ( tvItem.stateMask & TVIS_FOCUSED)
873 {
874 info.m_stateMask |= wxTREE_STATE_FOCUSED ;
875 if ( tvItem.state & TVIS_FOCUSED )
876 info.m_state |= wxTREE_STATE_FOCUSED ;
877 }
878 if ( tvItem.stateMask & TVIS_SELECTED)
879 {
880 info.m_stateMask |= wxTREE_STATE_SELECTED ;
881 if ( tvItem.state & TVIS_SELECTED )
882 info.m_state |= wxTREE_STATE_SELECTED ;
883 }
884 }
885
886 if ( tvItem.mask & TVIF_TEXT )
887 {
888 info.m_mask |= wxTREE_MASK_TEXT;
889 info.m_text = tvItem.pszText;
890 }
891 if ( tvItem.mask & TVIF_IMAGE )
892 {
893 info.m_mask |= wxTREE_MASK_IMAGE;
894 info.m_image = tvItem.iImage;
895 }
896 if ( tvItem.mask & TVIF_SELECTEDIMAGE )
897 {
898 info.m_mask |= wxTREE_MASK_SELECTED_IMAGE;
899 info.m_selectedImage = tvItem.iSelectedImage;
900 }
901 if ( tvItem.mask & TVIF_CHILDREN )
902 {
903 info.m_mask |= wxTREE_MASK_CHILDREN;
904 info.m_children = tvItem.cChildren;
905 }
906 if ( tvItem.mask & TVIF_PARAM )
907 info.m_mask |= wxTREE_MASK_DATA;
908
909 if (needText)
910 {
911 if (tvItem.pszText)
912 delete[] tvItem.pszText;
913 }
914 tvItem.mask = oldMask ;
915 }
916
917 static void wxConvertToMSWTreeItem(wxTreeItem& info, TV_ITEM& tvItem)
918 {
919 tvItem.hItem = (HTREEITEM) info.m_itemId ;
920
921 tvItem.iImage = info.m_image ;
922 tvItem.iSelectedImage = info.m_selectedImage;
923 tvItem.cChildren = info.m_children;
924 tvItem.lParam = info.m_data;
925 tvItem.mask = 0;
926 tvItem.stateMask = 0;
927 tvItem.state = 0;
928
929 if (info.m_mask & wxTREE_MASK_HANDLE)
930 tvItem.mask |= TVIF_HANDLE ;
931 if (info.m_mask & wxTREE_MASK_STATE)
932 tvItem.mask |= TVIF_STATE ;
933 if (info.m_mask & wxTREE_MASK_TEXT)
934 {
935 tvItem.mask |= TVIF_TEXT ;
936 tvItem.pszText = (char *) (const char *)info.m_text ;
937 if ( tvItem.pszText )
938 tvItem.cchTextMax = info.m_text.Length();
939 else
940 tvItem.cchTextMax = 0;
941 }
942 if (info.m_mask & wxTREE_MASK_IMAGE)
943 tvItem.mask |= TVIF_IMAGE ;
944 if (info.m_mask & wxTREE_MASK_SELECTED_IMAGE)
945 tvItem.mask |= TVIF_SELECTEDIMAGE ;
946 if (info.m_mask & wxTREE_MASK_CHILDREN)
947 tvItem.mask |= TVIF_CHILDREN ;
948 if (info.m_mask & wxTREE_MASK_DATA)
949 tvItem.mask |= TVIF_PARAM ;
950
951 if (info.m_stateMask & wxTREE_STATE_BOLD)
952 {
953 tvItem.stateMask |= TVIS_BOLD ;
954 tvItem.state |= TVIS_BOLD;
955 }
956 if (info.m_stateMask & wxTREE_STATE_CUT)
957 {
958 tvItem.stateMask |= TVIS_CUT ;
959 if ( info.m_state & wxTREE_STATE_CUT )
960 tvItem.state |= TVIS_CUT;
961 }
962 if (info.m_stateMask & wxTREE_STATE_DROPHILITED)
963 {
964 tvItem.stateMask |= TVIS_DROPHILITED;
965 if ( info.m_state & wxTREE_STATE_DROPHILITED )
966 tvItem.state |= TVIS_DROPHILITED;
967 }
968 if (info.m_stateMask & wxTREE_STATE_EXPANDED)
969 {
970 tvItem.stateMask |= TVIS_EXPANDED;
971 if ( info.m_state & wxTREE_STATE_EXPANDED )
972 tvItem.state |= TVIS_EXPANDED;
973 }
974 if (info.m_stateMask & wxTREE_STATE_EXPANDEDONCE)
975 {
976 tvItem.stateMask |= TVIS_EXPANDEDONCE;
977 if ( info.m_state & wxTREE_STATE_EXPANDEDONCE )
978 tvItem.state |= TVIS_EXPANDEDONCE;
979 }
980 if (info.m_stateMask & wxTREE_STATE_FOCUSED)
981 {
982 tvItem.stateMask |= TVIS_FOCUSED;
983 if ( info.m_state & wxTREE_STATE_FOCUSED )
984 tvItem.state |= TVIS_FOCUSED;
985 }
986 if (info.m_stateMask & wxTREE_STATE_SELECTED)
987 {
988 tvItem.stateMask |= TVIS_SELECTED;
989 if ( info.m_state & wxTREE_STATE_SELECTED )
990 tvItem.state |= TVIS_SELECTED;
991 }
992 }
993
994 // Tree event
995 IMPLEMENT_DYNAMIC_CLASS(wxTreeEvent, wxCommandEvent)
996
997 wxTreeEvent::wxTreeEvent(wxEventType commandType, int id):
998 wxCommandEvent(commandType, id)
999 {
1000 m_code = 0;
1001 m_oldItem = 0;
1002 }
1003
1004 #endif
1005