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