]> git.saurik.com Git - wxWidgets.git/blame - src/msw/treectrl.cpp
minor fixes
[wxWidgets.git] / src / msw / treectrl.cpp
CommitLineData
b823f5a1
JS
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/////////////////////////////////////////////////////////////////////////////
2bda0e17
KB
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;
bbcdf8bc 56 m_textCtrl = NULL;
2bda0e17
KB
57}
58
debe6624
JS
59bool wxTreeCtrl::Create(wxWindow *parent, wxWindowID id, const wxPoint& pos, const wxSize& size,
60 long style, const wxValidator& validator, const wxString& name)
2bda0e17
KB
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;
bbcdf8bc 71 m_textCtrl = NULL;
2bda0e17
KB
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
7798a18e 95 DWORD wstyle = WS_VISIBLE | WS_CHILD | WS_TABSTOP | TVS_HASLINES;
2bda0e17
KB
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 )
7798a18e 107 wstyle |= TVS_HASBUTTONS;
2bda0e17
KB
108
109 if ( m_windowStyle & wxTR_EDIT_LABELS )
7798a18e
JS
110 wstyle |= TVS_EDITLABELS;
111
112 if ( m_windowStyle & wxTR_LINES_AT_ROOT )
113 wstyle |= TVS_LINESATROOT;
2bda0e17
KB
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
134wxTreeCtrl::~wxTreeCtrl(void)
135{
bbcdf8bc
JS
136 if (m_textCtrl)
137 {
138 m_textCtrl->UnsubclassWin();
139 m_textCtrl->SetHWND((WXHWND) 0);
140 delete m_textCtrl;
141 }
2bda0e17
KB
142}
143
144// Attributes
145int wxTreeCtrl::GetCount(void) const
146{
147 return (int) TreeView_GetCount((HWND) GetHWND());
148}
149
150int wxTreeCtrl::GetIndent(void) const
151{
152 return (int) TreeView_GetIndent((HWND) GetHWND());
153}
154
155void wxTreeCtrl::SetIndent(int indent)
156{
157 TreeView_SetIndent((HWND) GetHWND(), indent);
158}
159
debe6624 160wxImageList *wxTreeCtrl::GetImageList(int which) const
2bda0e17
KB
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
debe6624 173void wxTreeCtrl::SetImageList(wxImageList *imageList, int which)
2bda0e17
KB
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
debe6624 189long wxTreeCtrl::GetNextItem(long item, int code) const
2bda0e17
KB
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
debe6624 231bool wxTreeCtrl::ItemHasChildren(long item) const
2bda0e17
KB
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
debe6624 240long wxTreeCtrl::GetChild(long item) const
2bda0e17
KB
241{
242 return (long) ::SendMessage((HWND) GetHWND(), TVM_GETNEXTITEM, TVGN_CHILD, (LPARAM)item);
243}
244
debe6624 245long wxTreeCtrl::GetParent(long item) const
2bda0e17
KB
246{
247 return (long) ::SendMessage((HWND) GetHWND(), TVM_GETNEXTITEM, TVGN_PARENT, (LPARAM)item);
248}
249
250long wxTreeCtrl::GetFirstVisibleItem(void) const
251{
252 return (long) ::SendMessage((HWND) GetHWND(), TVM_GETNEXTITEM, TVGN_FIRSTVISIBLE, 0);
253}
254
debe6624 255long wxTreeCtrl::GetNextVisibleItem(long item) const
2bda0e17
KB
256{
257 return (long) ::SendMessage((HWND) GetHWND(), TVM_GETNEXTITEM, TVGN_NEXTVISIBLE, (LPARAM)item);
258}
259
260long wxTreeCtrl::GetSelection(void) const
261{
262 return (long) ::SendMessage((HWND) GetHWND(), TVM_GETNEXTITEM, TVGN_CARET, 0);
263}
264
265long wxTreeCtrl::GetRootItem(void) const
266{
267 return (long) ::SendMessage((HWND) GetHWND(), TVM_GETNEXTITEM, TVGN_ROOT, 0);
268}
269
2bda0e17
KB
270bool wxTreeCtrl::GetItem(wxTreeItem& info) const
271{
272 TV_ITEM tvItem;
273 tvItem.hItem = (HTREEITEM)info.m_itemId;
274 tvItem.pszText = NULL;
02ce7b72
VZ
275 tvItem.mask =
276 tvItem.stateMask = 0;
277
278 // TODO: convert other bits in the mask
2bda0e17
KB
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;
02ce7b72
VZ
287 if ( info.m_stateMask & wxTREE_STATE_EXPANDED ) {
288 tvItem.mask |= TVIF_STATE;
289 tvItem.stateMask |= TVIS_EXPANDED;
290 }
2bda0e17
KB
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
312bool 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
02ce7b72 319int wxTreeCtrl::GetItemState(long item, long stateMask) const
2bda0e17
KB
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
debe6624 333bool wxTreeCtrl::SetItemState(long item, long state, long stateMask)
2bda0e17
KB
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
debe6624 345bool wxTreeCtrl::SetItemImage(long item, int image, int selImage)
2bda0e17
KB
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
debe6624 361wxString wxTreeCtrl::GetItemText(long item) const
2bda0e17
KB
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
debe6624 373void wxTreeCtrl::SetItemText(long item, const wxString& str)
2bda0e17
KB
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
debe6624 384long wxTreeCtrl::GetItemData(long item) const
2bda0e17
KB
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
debe6624 396bool wxTreeCtrl::SetItemData(long item, long data)
2bda0e17
KB
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
debe6624 407bool wxTreeCtrl::GetItemRect(long item, wxRectangle& rect, bool textOnly) const
2bda0e17
KB
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
bbcdf8bc 422wxTextCtrl* wxTreeCtrl::GetEditControl(void) const
2bda0e17 423{
bbcdf8bc 424 return m_textCtrl;
2bda0e17
KB
425}
426
427// Operations
debe6624 428bool wxTreeCtrl::DeleteItem(long item)
2bda0e17
KB
429{
430 return (TreeView_DeleteItem((HWND) GetHWND(), (HTREEITEM) item) != 0);
431}
432
debe6624 433bool wxTreeCtrl::ExpandItem(long item, int action)
2bda0e17
KB
434{
435 UINT mswAction = TVE_EXPAND;
436 switch ( action )
437 {
438 case wxTREE_EXPAND_EXPAND:
439 mswAction = TVE_EXPAND;
440 break;
02ce7b72 441
2bda0e17
KB
442 case wxTREE_EXPAND_COLLAPSE:
443 mswAction = TVE_COLLAPSE;
02ce7b72
VZ
444 break;
445
2bda0e17 446 case wxTREE_EXPAND_COLLAPSE_RESET:
02ce7b72
VZ
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.");
2bda0e17 451 mswAction = TVE_COLLAPSERESET;
02ce7b72
VZ
452 break;
453
2bda0e17
KB
454 case wxTREE_EXPAND_TOGGLE:
455 mswAction = TVE_TOGGLE;
456 break;
02ce7b72
VZ
457
458 default:
459 wxFAIL_MSG("unknown action in wxTreeCtrl::ExpandItem");
2bda0e17 460 }
02ce7b72
VZ
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;
2bda0e17
KB
488}
489
debe6624 490long wxTreeCtrl::InsertItem(long parent, wxTreeItem& info, long insertAfter)
2bda0e17
KB
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
debe6624
JS
501long wxTreeCtrl::InsertItem(long parent, const wxString& label, int image, int selImage,
502 long insertAfter)
2bda0e17
KB
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
debe6624 520bool wxTreeCtrl::SelectItem(long item)
2bda0e17
KB
521{
522 return (TreeView_SelectItem((HWND) GetHWND(), (HTREEITEM) item) != 0);
523}
524
debe6624 525bool wxTreeCtrl::ScrollTo(long item)
2bda0e17
KB
526{
527 return (TreeView_SelectSetFirstVisible((HWND) GetHWND(), (HTREEITEM) item) != 0);
528}
529
530bool wxTreeCtrl::DeleteAllItems(void)
531{
532 return (TreeView_DeleteAllItems((HWND) GetHWND()) != 0);
533}
534
bbcdf8bc 535wxTextCtrl* wxTreeCtrl::EditLabel(long item, wxClassInfo* textControlClass)
2bda0e17 536{
bbcdf8bc
JS
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
557bool 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;
2bda0e17
KB
569}
570
571long 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/*
debe6624 607wxImageList *wxTreeCtrl::CreateDragImage(long item)
2bda0e17
KB
608{
609}
610*/
611
debe6624 612bool wxTreeCtrl::SortChildren(long item)
2bda0e17
KB
613{
614 return (TreeView_SortChildren((HWND) GetHWND(), (HTREEITEM) item, 0) != 0);
615}
616
debe6624 617bool wxTreeCtrl::EnsureVisible(long item)
2bda0e17
KB
618{
619 return (TreeView_EnsureVisible((HWND) GetHWND(), (HTREEITEM) item) != 0);
620}
621
debe6624 622bool wxTreeCtrl::MSWCommand(WXUINT cmd, WXWORD id)
2bda0e17
KB
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
debe6624 641bool wxTreeCtrl::MSWNotify(WXWPARAM wParam, WXLPARAM lParam)
2bda0e17 642{
7798a18e
JS
643 wxTreeEvent event(wxEVT_NULL, m_windowId);
644 wxEventType eventType = wxEVT_NULL;
2bda0e17
KB
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 {
2bda0e17
KB
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:
02ce7b72 704 eventType = wxEVT_COMMAND_TREE_ITEM_EXPANDING;
2bda0e17 705 break;
02ce7b72 706
2bda0e17 707 case TVE_COLLAPSE:
02ce7b72
VZ
708 eventType = wxEVT_COMMAND_TREE_ITEM_COLLAPSING;
709 break;
710
2bda0e17 711 case TVE_COLLAPSERESET:
2bda0e17 712 case TVE_TOGGLE:
02ce7b72 713 wxLogDebug("unexpected code in TVN_ITEMEXPANDING message");
2bda0e17
KB
714 break;
715 }
716 break;
717 }
02ce7b72 718
2bda0e17
KB
719 case TVN_ITEMEXPANDED:
720 {
2bda0e17
KB
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:
02ce7b72 726 eventType = wxEVT_COMMAND_TREE_ITEM_EXPANDED;
2bda0e17 727 break;
02ce7b72 728
2bda0e17 729 case TVE_COLLAPSE:
02ce7b72
VZ
730 eventType = wxEVT_COMMAND_TREE_ITEM_COLLAPSED;
731 break;
732
2bda0e17 733 case TVE_COLLAPSERESET:
2bda0e17 734 case TVE_TOGGLE:
02ce7b72 735 wxLogDebug("unexpected code in TVN_ITEMEXPANDED message");
2bda0e17
KB
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
02ce7b72 777 event.SetEventObject(this);
2bda0e17
KB
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
02ce7b72 789 return TRUE;
2bda0e17
KB
790}
791
792// Tree item structure
793wxTreeItem::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.
806static 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
917static 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
995IMPLEMENT_DYNAMIC_CLASS(wxTreeEvent, wxCommandEvent)
996
7798a18e 997wxTreeEvent::wxTreeEvent(wxEventType commandType, int id):
2bda0e17
KB
998 wxCommandEvent(commandType, id)
999{
1000 m_code = 0;
1001 m_oldItem = 0;
1002}
1003
1004#endif
1005