]> git.saurik.com Git - wxWidgets.git/blame - src/msw/treectrl.cpp
wxLogDebug/Trace in release mode now don't give compiler warnings
[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
debe6624
JS
58bool wxTreeCtrl::Create(wxWindow *parent, wxWindowID id, const wxPoint& pos, const wxSize& size,
59 long style, const wxValidator& validator, const wxString& name)
2bda0e17
KB
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
7798a18e 93 DWORD wstyle = WS_VISIBLE | WS_CHILD | WS_TABSTOP | TVS_HASLINES;
2bda0e17
KB
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 )
7798a18e 105 wstyle |= TVS_HASBUTTONS;
2bda0e17
KB
106
107 if ( m_windowStyle & wxTR_EDIT_LABELS )
7798a18e
JS
108 wstyle |= TVS_EDITLABELS;
109
110 if ( m_windowStyle & wxTR_LINES_AT_ROOT )
111 wstyle |= TVS_LINESATROOT;
2bda0e17
KB
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
132wxTreeCtrl::~wxTreeCtrl(void)
133{
134 m_textCtrl.SetHWND((WXHWND) NULL);
135}
136
137// Attributes
138int wxTreeCtrl::GetCount(void) const
139{
140 return (int) TreeView_GetCount((HWND) GetHWND());
141}
142
143int wxTreeCtrl::GetIndent(void) const
144{
145 return (int) TreeView_GetIndent((HWND) GetHWND());
146}
147
148void wxTreeCtrl::SetIndent(int indent)
149{
150 TreeView_SetIndent((HWND) GetHWND(), indent);
151}
152
debe6624 153wxImageList *wxTreeCtrl::GetImageList(int which) const
2bda0e17
KB
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
debe6624 166void wxTreeCtrl::SetImageList(wxImageList *imageList, int which)
2bda0e17
KB
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
debe6624 182long wxTreeCtrl::GetNextItem(long item, int code) const
2bda0e17
KB
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
debe6624 224bool wxTreeCtrl::ItemHasChildren(long item) const
2bda0e17
KB
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
debe6624 233long wxTreeCtrl::GetChild(long item) const
2bda0e17
KB
234{
235 return (long) ::SendMessage((HWND) GetHWND(), TVM_GETNEXTITEM, TVGN_CHILD, (LPARAM)item);
236}
237
debe6624 238long wxTreeCtrl::GetParent(long item) const
2bda0e17
KB
239{
240 return (long) ::SendMessage((HWND) GetHWND(), TVM_GETNEXTITEM, TVGN_PARENT, (LPARAM)item);
241}
242
243long wxTreeCtrl::GetFirstVisibleItem(void) const
244{
245 return (long) ::SendMessage((HWND) GetHWND(), TVM_GETNEXTITEM, TVGN_FIRSTVISIBLE, 0);
246}
247
debe6624 248long wxTreeCtrl::GetNextVisibleItem(long item) const
2bda0e17
KB
249{
250 return (long) ::SendMessage((HWND) GetHWND(), TVM_GETNEXTITEM, TVGN_NEXTVISIBLE, (LPARAM)item);
251}
252
253long wxTreeCtrl::GetSelection(void) const
254{
255 return (long) ::SendMessage((HWND) GetHWND(), TVM_GETNEXTITEM, TVGN_CARET, 0);
256}
257
258long wxTreeCtrl::GetRootItem(void) const
259{
260 return (long) ::SendMessage((HWND) GetHWND(), TVM_GETNEXTITEM, TVGN_ROOT, 0);
261}
262
2bda0e17
KB
263bool wxTreeCtrl::GetItem(wxTreeItem& info) const
264{
265 TV_ITEM tvItem;
266 tvItem.hItem = (HTREEITEM)info.m_itemId;
267 tvItem.pszText = NULL;
02ce7b72
VZ
268 tvItem.mask =
269 tvItem.stateMask = 0;
270
271 // TODO: convert other bits in the mask
2bda0e17
KB
272 if ( info.m_mask & wxTREE_MASK_TEXT )
273 {
274 tvItem.mask |= TVIF_TEXT;
275 tvItem.pszText = new char[513];
276 tvItem.cchTextMax = 512;
277 }
278 if ( info.m_mask & wxTREE_MASK_DATA )
279 tvItem.mask |= TVIF_PARAM;
02ce7b72
VZ
280 if ( info.m_stateMask & wxTREE_STATE_EXPANDED ) {
281 tvItem.mask |= TVIF_STATE;
282 tvItem.stateMask |= TVIS_EXPANDED;
283 }
2bda0e17
KB
284
285 bool success = TreeView_GetItem((HWND)GetHWND(), &tvItem) != 0;
286
287 if ( !success )
288 {
289 wxLogSysError("TreeView_GetItem failed");
290
291 if (tvItem.pszText)
292 delete[] tvItem.pszText;
293
294 return FALSE;
295 }
296
297 wxConvertFromMSWTreeItem(info, tvItem);
298
299 if (tvItem.pszText)
300 delete[] tvItem.pszText;
301
302 return success;
303}
304
305bool wxTreeCtrl::SetItem(wxTreeItem& info)
306{
307 TV_ITEM item;
308 wxConvertToMSWTreeItem(info, item);
309 return (::SendMessage((HWND) GetHWND(), TVM_SETITEM, 0, (LPARAM)&item) != 0);
310}
311
02ce7b72 312int wxTreeCtrl::GetItemState(long item, long stateMask) const
2bda0e17
KB
313{
314 wxTreeItem info;
315
316 info.m_mask = wxTREE_MASK_STATE ;
317 info.m_stateMask = stateMask;
318 info.m_itemId = item;
319
320 if (!GetItem(info))
321 return 0;
322
323 return info.m_state;
324}
325
debe6624 326bool wxTreeCtrl::SetItemState(long item, long state, long stateMask)
2bda0e17
KB
327{
328 wxTreeItem info;
329
330 info.m_mask = wxTREE_MASK_STATE ;
331 info.m_state = state;
332 info.m_stateMask = stateMask;
333 info.m_itemId = item;
334
335 return SetItem(info);
336}
337
debe6624 338bool wxTreeCtrl::SetItemImage(long item, int image, int selImage)
2bda0e17
KB
339{
340 wxTreeItem info;
341
342 info.m_mask = wxTREE_MASK_IMAGE ;
343 info.m_image = image;
344 if ( selImage > -1)
345 {
346 info.m_selectedImage = selImage;
347 info.m_mask |= wxTREE_MASK_SELECTED_IMAGE;
348 }
349 info.m_itemId = item;
350
351 return SetItem(info);
352}
353
debe6624 354wxString wxTreeCtrl::GetItemText(long item) const
2bda0e17
KB
355{
356 wxTreeItem info;
357
358 info.m_mask = wxTREE_MASK_TEXT ;
359 info.m_itemId = item;
360
361 if (!GetItem(info))
362 return wxString("");
363 return info.m_text;
364}
365
debe6624 366void wxTreeCtrl::SetItemText(long item, const wxString& str)
2bda0e17
KB
367{
368 wxTreeItem info;
369
370 info.m_mask = wxTREE_MASK_TEXT ;
371 info.m_itemId = item;
372 info.m_text = str;
373
374 SetItem(info);
375}
376
debe6624 377long wxTreeCtrl::GetItemData(long item) const
2bda0e17
KB
378{
379 wxTreeItem info;
380
381 info.m_mask = wxTREE_MASK_DATA ;
382 info.m_itemId = item;
383
384 if (!GetItem(info))
385 return 0;
386 return info.m_data;
387}
388
debe6624 389bool wxTreeCtrl::SetItemData(long item, long data)
2bda0e17
KB
390{
391 wxTreeItem info;
392
393 info.m_mask = wxTREE_MASK_DATA ;
394 info.m_itemId = item;
395 info.m_data = data;
396
397 return SetItem(info);
398}
399
debe6624 400bool wxTreeCtrl::GetItemRect(long item, wxRectangle& rect, bool textOnly) const
2bda0e17
KB
401{
402 RECT rect2;
403
404 *(HTREEITEM*)& rect2 = (HTREEITEM) item;
405 bool success = (::SendMessage((HWND) GetHWND(), TVM_GETITEMRECT, (WPARAM)textOnly,
406 (LPARAM)&rect2) != 0);
407
408 rect.x = rect2.left;
409 rect.y = rect2.top;
410 rect.width = rect2.right - rect2.left;
411 rect.height = rect2.bottom - rect2.left;
412 return success;
413}
414
415wxTextCtrl& wxTreeCtrl::GetEditControl(void) const
416{
417 HWND hWnd = (HWND) TreeView_GetEditControl((HWND) GetHWND());
418 ((wxTreeCtrl *)this)->m_textCtrl.SetHWND((WXHWND) hWnd);
419 return (wxTextCtrl&) m_textCtrl;
420}
421
422// Operations
debe6624 423bool wxTreeCtrl::DeleteItem(long item)
2bda0e17
KB
424{
425 return (TreeView_DeleteItem((HWND) GetHWND(), (HTREEITEM) item) != 0);
426}
427
debe6624 428bool wxTreeCtrl::ExpandItem(long item, int action)
2bda0e17
KB
429{
430 UINT mswAction = TVE_EXPAND;
431 switch ( action )
432 {
433 case wxTREE_EXPAND_EXPAND:
434 mswAction = TVE_EXPAND;
435 break;
02ce7b72 436
2bda0e17
KB
437 case wxTREE_EXPAND_COLLAPSE:
438 mswAction = TVE_COLLAPSE;
02ce7b72
VZ
439 break;
440
2bda0e17 441 case wxTREE_EXPAND_COLLAPSE_RESET:
02ce7b72
VZ
442 // @@@ it should also delete all the items! currently, if you do use this
443 // code your program will probaly crash. Feel free to remove this if
444 // it does work
445 wxFAIL_MSG("wxTREE_EXPAND_COLLAPSE_RESET probably doesn't work.");
2bda0e17 446 mswAction = TVE_COLLAPSERESET;
02ce7b72
VZ
447 break;
448
2bda0e17
KB
449 case wxTREE_EXPAND_TOGGLE:
450 mswAction = TVE_TOGGLE;
451 break;
02ce7b72
VZ
452
453 default:
454 wxFAIL_MSG("unknown action in wxTreeCtrl::ExpandItem");
2bda0e17 455 }
02ce7b72
VZ
456
457 bool bOk = TreeView_Expand((HWND)GetHWND(), (HTREEITEM)item, mswAction) != 0;
458
459 // TreeView_Expand doesn't send TVN_EXPAND(ING) messages, so emulate them
460 if ( bOk ) {
461 wxTreeEvent event(wxEVT_NULL, m_windowId);
462 event.m_item.m_itemId = item;
463 event.m_item.m_mask =
464 event.m_item.m_stateMask = 0xffff; // get all
465 GetItem(event.m_item);
466
467 bool bIsExpanded = (event.m_item.m_state & wxTREE_STATE_EXPANDED) != 0;
468
469 event.m_code = action;
470 event.SetEventObject(this);
471
472 // @@@ return values of {EXPAND|COLLAPS}ING event handler is discarded
473 event.SetEventType(bIsExpanded ? wxEVT_COMMAND_TREE_ITEM_EXPANDING
474 : wxEVT_COMMAND_TREE_ITEM_COLLAPSING);
475 GetEventHandler()->ProcessEvent(event);
476
477 event.SetEventType(bIsExpanded ? wxEVT_COMMAND_TREE_ITEM_EXPANDED
478 : wxEVT_COMMAND_TREE_ITEM_COLLAPSED);
479 GetEventHandler()->ProcessEvent(event);
480 }
481
482 return bOk;
2bda0e17
KB
483}
484
debe6624 485long wxTreeCtrl::InsertItem(long parent, wxTreeItem& info, long insertAfter)
2bda0e17
KB
486{
487 TV_INSERTSTRUCT tvInsertStruct;
488 tvInsertStruct.hParent = (HTREEITEM) parent ;
489 tvInsertStruct.hInsertAfter = (HTREEITEM) insertAfter ;
490
491 wxConvertToMSWTreeItem(info, tvInsertStruct.item);
492
493 return (long) TreeView_InsertItem((HWND) GetHWND(), & tvInsertStruct);
494}
495
debe6624
JS
496long wxTreeCtrl::InsertItem(long parent, const wxString& label, int image, int selImage,
497 long insertAfter)
2bda0e17
KB
498{
499 wxTreeItem info;
500 info.m_text = label;
501 info.m_mask = wxTREE_MASK_TEXT;
502 if ( image > -1 )
503 {
504 info.m_mask |= wxTREE_MASK_IMAGE | wxTREE_MASK_SELECTED_IMAGE;
505 info.m_image = image;
506 if ( selImage == -1 )
507 info.m_selectedImage = image;
508 else
509 info.m_selectedImage = selImage;
510 }
511
512 return InsertItem(parent, info, insertAfter);
513}
514
debe6624 515bool wxTreeCtrl::SelectItem(long item)
2bda0e17
KB
516{
517 return (TreeView_SelectItem((HWND) GetHWND(), (HTREEITEM) item) != 0);
518}
519
debe6624 520bool wxTreeCtrl::ScrollTo(long item)
2bda0e17
KB
521{
522 return (TreeView_SelectSetFirstVisible((HWND) GetHWND(), (HTREEITEM) item) != 0);
523}
524
525bool wxTreeCtrl::DeleteAllItems(void)
526{
527 return (TreeView_DeleteAllItems((HWND) GetHWND()) != 0);
528}
529
debe6624 530wxTextCtrl& wxTreeCtrl::Edit(long item)
2bda0e17
KB
531{
532 HWND hWnd = (HWND) TreeView_EditLabel((HWND) GetHWND(), item);
533 m_textCtrl.SetHWND((WXHWND) hWnd);
534 return m_textCtrl;
535}
536
537long wxTreeCtrl::HitTest(const wxPoint& point, int& flags)
538{
539 TV_HITTESTINFO hitTestInfo;
540 hitTestInfo.pt.x = (int) point.x;
541 hitTestInfo.pt.y = (int) point.y;
542
543 TreeView_HitTest((HWND) GetHWND(), & hitTestInfo);
544
545 flags = 0;
546 if ( hitTestInfo.flags & TVHT_ABOVE )
547 flags |= wxTREE_HITTEST_ABOVE;
548 if ( hitTestInfo.flags & TVHT_BELOW )
549 flags |= wxTREE_HITTEST_BELOW;
550 if ( hitTestInfo.flags & TVHT_NOWHERE )
551 flags |= wxTREE_HITTEST_NOWHERE;
552 if ( hitTestInfo.flags & TVHT_ONITEMBUTTON )
553 flags |= wxTREE_HITTEST_ONITEMBUTTON;
554 if ( hitTestInfo.flags & TVHT_ONITEMICON )
555 flags |= wxTREE_HITTEST_ONITEMICON;
556 if ( hitTestInfo.flags & TVHT_ONITEMINDENT )
557 flags |= wxTREE_HITTEST_ONITEMINDENT;
558 if ( hitTestInfo.flags & TVHT_ONITEMLABEL )
559 flags |= wxTREE_HITTEST_ONITEMLABEL;
560 if ( hitTestInfo.flags & TVHT_ONITEMRIGHT )
561 flags |= wxTREE_HITTEST_ONITEMRIGHT;
562 if ( hitTestInfo.flags & TVHT_ONITEMSTATEICON )
563 flags |= wxTREE_HITTEST_ONITEMSTATEICON;
564 if ( hitTestInfo.flags & TVHT_TOLEFT )
565 flags |= wxTREE_HITTEST_TOLEFT;
566 if ( hitTestInfo.flags & TVHT_TORIGHT )
567 flags |= wxTREE_HITTEST_TORIGHT;
568
569 return (long) hitTestInfo.hItem ;
570}
571
572/*
debe6624 573wxImageList *wxTreeCtrl::CreateDragImage(long item)
2bda0e17
KB
574{
575}
576*/
577
debe6624 578bool wxTreeCtrl::SortChildren(long item)
2bda0e17
KB
579{
580 return (TreeView_SortChildren((HWND) GetHWND(), (HTREEITEM) item, 0) != 0);
581}
582
debe6624 583bool wxTreeCtrl::EnsureVisible(long item)
2bda0e17
KB
584{
585 return (TreeView_EnsureVisible((HWND) GetHWND(), (HTREEITEM) item) != 0);
586}
587
debe6624 588bool wxTreeCtrl::MSWCommand(WXUINT cmd, WXWORD id)
2bda0e17
KB
589{
590 if (cmd == EN_UPDATE)
591 {
592 wxCommandEvent event(wxEVT_COMMAND_TEXT_UPDATED, id);
593 event.SetEventObject( this );
594 ProcessCommand(event);
595 return TRUE;
596 }
597 else if (cmd == EN_KILLFOCUS)
598 {
599 wxCommandEvent event(wxEVT_KILL_FOCUS, id);
600 event.SetEventObject( this );
601 ProcessCommand(event);
602 return TRUE;
603 }
604 else return FALSE;
605}
606
debe6624 607bool wxTreeCtrl::MSWNotify(WXWPARAM wParam, WXLPARAM lParam)
2bda0e17 608{
7798a18e
JS
609 wxTreeEvent event(wxEVT_NULL, m_windowId);
610 wxEventType eventType = wxEVT_NULL;
2bda0e17
KB
611 NMHDR* hdr1 = (NMHDR*) lParam;
612 switch ( hdr1->code )
613 {
614 case TVN_BEGINDRAG:
615 {
616 eventType = wxEVT_COMMAND_TREE_BEGIN_DRAG;
617 NM_TREEVIEW* hdr = (NM_TREEVIEW*)lParam;
618 wxConvertFromMSWTreeItem(event.m_item, hdr->itemNew, (HWND) GetHWND());
619 event.m_pointDrag.x = hdr->ptDrag.x;
620 event.m_pointDrag.y = hdr->ptDrag.y;
621 break;
622 }
623 case TVN_BEGINLABELEDIT:
624 {
625 eventType = wxEVT_COMMAND_TREE_BEGIN_LABEL_EDIT;
626 TV_DISPINFO *info = (TV_DISPINFO *)lParam;
627 wxConvertFromMSWTreeItem(event.m_item, info->item, (HWND) GetHWND());
628 break;
629 }
630 case TVN_BEGINRDRAG:
631 {
632 eventType = wxEVT_COMMAND_TREE_BEGIN_RDRAG;
633 NM_TREEVIEW* hdr = (NM_TREEVIEW*)lParam;
634 wxConvertFromMSWTreeItem(event.m_item, hdr->itemNew, (HWND) GetHWND());
635 event.m_pointDrag.x = hdr->ptDrag.x;
636 event.m_pointDrag.y = hdr->ptDrag.y;
637 break;
638 }
639 case TVN_DELETEITEM:
640 {
641 eventType = wxEVT_COMMAND_TREE_DELETE_ITEM;
642 NM_TREEVIEW* hdr = (NM_TREEVIEW*)lParam;
643 wxConvertFromMSWTreeItem(event.m_item, hdr->itemOld, (HWND) GetHWND());
644 event.m_pointDrag.x = hdr->ptDrag.x;
645 event.m_pointDrag.y = hdr->ptDrag.y;
646 break;
647 }
648 case TVN_ENDLABELEDIT:
649 {
650 eventType = wxEVT_COMMAND_TREE_END_LABEL_EDIT;
651 TV_DISPINFO *info = (TV_DISPINFO *)lParam;
652 wxConvertFromMSWTreeItem(event.m_item, info->item, (HWND) GetHWND());
653 break;
654 }
655 case TVN_GETDISPINFO:
656 {
657 eventType = wxEVT_COMMAND_TREE_GET_INFO;
658 TV_DISPINFO *info = (TV_DISPINFO *)lParam;
659 wxConvertFromMSWTreeItem(event.m_item, info->item, (HWND) GetHWND());
660 break;
661 }
662 case TVN_ITEMEXPANDING:
663 {
2bda0e17
KB
664 NM_TREEVIEW* hdr = (NM_TREEVIEW*)lParam;
665 wxConvertFromMSWTreeItem(event.m_item, hdr->itemNew, (HWND) GetHWND());
666
667 switch ( hdr->action )
668 {
669 case TVE_EXPAND:
02ce7b72 670 eventType = wxEVT_COMMAND_TREE_ITEM_EXPANDING;
2bda0e17 671 break;
02ce7b72 672
2bda0e17 673 case TVE_COLLAPSE:
02ce7b72
VZ
674 eventType = wxEVT_COMMAND_TREE_ITEM_COLLAPSING;
675 break;
676
2bda0e17 677 case TVE_COLLAPSERESET:
2bda0e17 678 case TVE_TOGGLE:
02ce7b72 679 wxLogDebug("unexpected code in TVN_ITEMEXPANDING message");
2bda0e17
KB
680 break;
681 }
682 break;
683 }
02ce7b72 684
2bda0e17
KB
685 case TVN_ITEMEXPANDED:
686 {
2bda0e17
KB
687 NM_TREEVIEW* hdr = (NM_TREEVIEW*)lParam;
688 wxConvertFromMSWTreeItem(event.m_item, hdr->itemNew, (HWND) GetHWND());
689 switch ( hdr->action )
690 {
691 case TVE_EXPAND:
02ce7b72 692 eventType = wxEVT_COMMAND_TREE_ITEM_EXPANDED;
2bda0e17 693 break;
02ce7b72 694
2bda0e17 695 case TVE_COLLAPSE:
02ce7b72
VZ
696 eventType = wxEVT_COMMAND_TREE_ITEM_COLLAPSED;
697 break;
698
2bda0e17 699 case TVE_COLLAPSERESET:
2bda0e17 700 case TVE_TOGGLE:
02ce7b72 701 wxLogDebug("unexpected code in TVN_ITEMEXPANDED message");
2bda0e17
KB
702 break;
703 }
704 break;
705 }
706 case TVN_KEYDOWN:
707 {
708 eventType = wxEVT_COMMAND_TREE_KEY_DOWN;
709 TV_KEYDOWN *info = (TV_KEYDOWN *)lParam;
710 event.m_code = wxCharCodeMSWToWX(info->wVKey);
711 break;
712 }
713 case TVN_SELCHANGED:
714 {
715 eventType = wxEVT_COMMAND_TREE_SEL_CHANGED;
716 NM_TREEVIEW* hdr = (NM_TREEVIEW*)lParam;
717 wxConvertFromMSWTreeItem(event.m_item, hdr->itemNew, (HWND) GetHWND());
718 event.m_oldItem = (long) hdr->itemNew.hItem;
719
720 break;
721 }
722 case TVN_SELCHANGING:
723 {
724 eventType = wxEVT_COMMAND_TREE_SEL_CHANGING;
725 NM_TREEVIEW* hdr = (NM_TREEVIEW*)lParam;
726 wxConvertFromMSWTreeItem(event.m_item, hdr->itemNew, (HWND) GetHWND());
727 event.m_oldItem = (long) hdr->itemNew.hItem;
728 break;
729 }
730 case TVN_SETDISPINFO:
731 {
732 eventType = wxEVT_COMMAND_TREE_SET_INFO;
733 TV_DISPINFO *info = (TV_DISPINFO *)lParam;
734 wxConvertFromMSWTreeItem(event.m_item, info->item, (HWND) GetHWND());
735 break;
736 }
737
738 default :
739 return wxControl::MSWNotify(wParam, lParam);
740 break;
741 }
742
02ce7b72 743 event.SetEventObject(this);
2bda0e17
KB
744 event.SetEventType(eventType);
745
746 if ( !GetEventHandler()->ProcessEvent(event) )
747 return FALSE;
748
749 if (hdr1->code == TVN_GETDISPINFO)
750 {
751 TV_DISPINFO *info = (TV_DISPINFO *)lParam;
752 wxConvertToMSWTreeItem(event.m_item, info->item);
753 }
754
02ce7b72 755 return TRUE;
2bda0e17
KB
756}
757
758// Tree item structure
759wxTreeItem::wxTreeItem(void)
760{
761 m_mask = 0;
762 m_itemId = 0;
763 m_state = 0;
764 m_stateMask = 0;
765 m_image = -1;
766 m_selectedImage = -1;
767 m_children = 0;
768 m_data = 0;
769}
770
771// If getFullInfo is TRUE, we explicitly query for more info if we haven't got it all.
772static void wxConvertFromMSWTreeItem(wxTreeItem& info, TV_ITEM& tvItem, HWND getFullInfo)
773{
774 info.m_data = tvItem.lParam;
775 info.m_mask = 0;
776 info.m_state = 0;
777 info.m_stateMask = 0;
778
779 long oldMask = tvItem.mask;
780
781 bool needText = FALSE;
782 if (getFullInfo != 0)
783 {
784 if ( tvItem.mask & TVIF_TEXT )
785 needText = FALSE;
786 else
787 needText = TRUE;
788
789 if ( needText )
790 {
791 tvItem.pszText = new char[513];
792 tvItem.cchTextMax = 512;
793 }
794 tvItem.mask |= TVIF_HANDLE | TVIF_STATE | TVIF_TEXT | TVIF_IMAGE | TVIF_SELECTEDIMAGE | TVIF_CHILDREN | TVIF_PARAM ;
795 ::SendMessage(getFullInfo, TVM_GETITEM, 0, (LPARAM)& tvItem) ;
796 }
797
798 if ( tvItem.mask & TVIF_HANDLE )
799 {
800 info.m_mask |= wxTREE_MASK_HANDLE;
801 info.m_itemId = (long) tvItem.hItem;
802 }
803 if ( tvItem.mask & TVIF_STATE )
804 {
805 info.m_mask |= wxTREE_MASK_STATE;
806 if ( tvItem.stateMask & TVIS_BOLD)
807 {
808 info.m_stateMask |= wxTREE_STATE_BOLD ;
809 if ( tvItem.state & TVIS_BOLD )
810 info.m_state |= wxTREE_STATE_BOLD ;
811 }
812
813 if ( tvItem.stateMask & TVIS_CUT)
814 {
815 info.m_stateMask |= wxTREE_STATE_CUT ;
816 if ( tvItem.state & TVIS_CUT )
817 info.m_state |= wxTREE_STATE_CUT ;
818 }
819
820 if ( tvItem.stateMask & TVIS_DROPHILITED)
821 {
822 info.m_stateMask |= wxTREE_STATE_DROPHILITED ;
823 if ( tvItem.state & TVIS_DROPHILITED )
824 info.m_state |= wxTREE_STATE_DROPHILITED ;
825 }
826 if ( tvItem.stateMask & TVIS_EXPANDED)
827 {
828 info.m_stateMask |= wxTREE_STATE_EXPANDED ;
829 if ( tvItem.state & TVIS_EXPANDED )
830 info.m_state |= wxTREE_STATE_EXPANDED ;
831 }
832 if ( tvItem.stateMask & TVIS_EXPANDEDONCE)
833 {
834 info.m_stateMask |= wxTREE_STATE_EXPANDEDONCE ;
835 if ( tvItem.state & TVIS_EXPANDEDONCE )
836 info.m_state |= wxTREE_STATE_EXPANDEDONCE ;
837 }
838 if ( tvItem.stateMask & TVIS_FOCUSED)
839 {
840 info.m_stateMask |= wxTREE_STATE_FOCUSED ;
841 if ( tvItem.state & TVIS_FOCUSED )
842 info.m_state |= wxTREE_STATE_FOCUSED ;
843 }
844 if ( tvItem.stateMask & TVIS_SELECTED)
845 {
846 info.m_stateMask |= wxTREE_STATE_SELECTED ;
847 if ( tvItem.state & TVIS_SELECTED )
848 info.m_state |= wxTREE_STATE_SELECTED ;
849 }
850 }
851
852 if ( tvItem.mask & TVIF_TEXT )
853 {
854 info.m_mask |= wxTREE_MASK_TEXT;
855 info.m_text = tvItem.pszText;
856 }
857 if ( tvItem.mask & TVIF_IMAGE )
858 {
859 info.m_mask |= wxTREE_MASK_IMAGE;
860 info.m_image = tvItem.iImage;
861 }
862 if ( tvItem.mask & TVIF_SELECTEDIMAGE )
863 {
864 info.m_mask |= wxTREE_MASK_SELECTED_IMAGE;
865 info.m_selectedImage = tvItem.iSelectedImage;
866 }
867 if ( tvItem.mask & TVIF_CHILDREN )
868 {
869 info.m_mask |= wxTREE_MASK_CHILDREN;
870 info.m_children = tvItem.cChildren;
871 }
872 if ( tvItem.mask & TVIF_PARAM )
873 info.m_mask |= wxTREE_MASK_DATA;
874
875 if (needText)
876 {
877 if (tvItem.pszText)
878 delete[] tvItem.pszText;
879 }
880 tvItem.mask = oldMask ;
881}
882
883static void wxConvertToMSWTreeItem(wxTreeItem& info, TV_ITEM& tvItem)
884{
885 tvItem.hItem = (HTREEITEM) info.m_itemId ;
886
887 tvItem.iImage = info.m_image ;
888 tvItem.iSelectedImage = info.m_selectedImage;
889 tvItem.cChildren = info.m_children;
890 tvItem.lParam = info.m_data;
891 tvItem.mask = 0;
892 tvItem.stateMask = 0;
893 tvItem.state = 0;
894
895 if (info.m_mask & wxTREE_MASK_HANDLE)
896 tvItem.mask |= TVIF_HANDLE ;
897 if (info.m_mask & wxTREE_MASK_STATE)
898 tvItem.mask |= TVIF_STATE ;
899 if (info.m_mask & wxTREE_MASK_TEXT)
900 {
901 tvItem.mask |= TVIF_TEXT ;
902 tvItem.pszText = (char *) (const char *)info.m_text ;
903 if ( tvItem.pszText )
904 tvItem.cchTextMax = info.m_text.Length();
905 else
906 tvItem.cchTextMax = 0;
907 }
908 if (info.m_mask & wxTREE_MASK_IMAGE)
909 tvItem.mask |= TVIF_IMAGE ;
910 if (info.m_mask & wxTREE_MASK_SELECTED_IMAGE)
911 tvItem.mask |= TVIF_SELECTEDIMAGE ;
912 if (info.m_mask & wxTREE_MASK_CHILDREN)
913 tvItem.mask |= TVIF_CHILDREN ;
914 if (info.m_mask & wxTREE_MASK_DATA)
915 tvItem.mask |= TVIF_PARAM ;
916
917 if (info.m_stateMask & wxTREE_STATE_BOLD)
918 {
919 tvItem.stateMask |= TVIS_BOLD ;
920 tvItem.state |= TVIS_BOLD;
921 }
922 if (info.m_stateMask & wxTREE_STATE_CUT)
923 {
924 tvItem.stateMask |= TVIS_CUT ;
925 if ( info.m_state & wxTREE_STATE_CUT )
926 tvItem.state |= TVIS_CUT;
927 }
928 if (info.m_stateMask & wxTREE_STATE_DROPHILITED)
929 {
930 tvItem.stateMask |= TVIS_DROPHILITED;
931 if ( info.m_state & wxTREE_STATE_DROPHILITED )
932 tvItem.state |= TVIS_DROPHILITED;
933 }
934 if (info.m_stateMask & wxTREE_STATE_EXPANDED)
935 {
936 tvItem.stateMask |= TVIS_EXPANDED;
937 if ( info.m_state & wxTREE_STATE_EXPANDED )
938 tvItem.state |= TVIS_EXPANDED;
939 }
940 if (info.m_stateMask & wxTREE_STATE_EXPANDEDONCE)
941 {
942 tvItem.stateMask |= TVIS_EXPANDEDONCE;
943 if ( info.m_state & wxTREE_STATE_EXPANDEDONCE )
944 tvItem.state |= TVIS_EXPANDEDONCE;
945 }
946 if (info.m_stateMask & wxTREE_STATE_FOCUSED)
947 {
948 tvItem.stateMask |= TVIS_FOCUSED;
949 if ( info.m_state & wxTREE_STATE_FOCUSED )
950 tvItem.state |= TVIS_FOCUSED;
951 }
952 if (info.m_stateMask & wxTREE_STATE_SELECTED)
953 {
954 tvItem.stateMask |= TVIS_SELECTED;
955 if ( info.m_state & wxTREE_STATE_SELECTED )
956 tvItem.state |= TVIS_SELECTED;
957 }
958}
959
960// Tree event
961IMPLEMENT_DYNAMIC_CLASS(wxTreeEvent, wxCommandEvent)
962
7798a18e 963wxTreeEvent::wxTreeEvent(wxEventType commandType, int id):
2bda0e17
KB
964 wxCommandEvent(commandType, id)
965{
966 m_code = 0;
967 m_oldItem = 0;
968}
969
970#endif
971