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