X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/47e105413fda3097f4ff5a3d9a224b8123aa5501..7fbff8020342123aa6d2e5a01ac21cc3caeb1fe3:/src/msw/treectrl.cpp diff --git a/src/msw/treectrl.cpp b/src/msw/treectrl.cpp index 0f04abe833..9464bec90b 100644 --- a/src/msw/treectrl.cpp +++ b/src/msw/treectrl.cpp @@ -106,6 +106,30 @@ private: HTREEITEM TreeItemUnlocker::ms_unlockedItem = NULL; +// another helper class: set the variable to true during its lifetime and reset +// it to false when it is destroyed +// +// it is currently always used with wxTreeCtrl::m_changingSelection +class TempSetter +{ +public: + TempSetter(bool& var) : m_var(var) + { + wxASSERT_MSG( !m_var, "variable shouldn't be already set" ); + m_var = true; + } + + ~TempSetter() + { + m_var = false; + } + +private: + bool& m_var; + + wxDECLARE_NO_COPY_CLASS(TempSetter); +}; + // ---------------------------------------------------------------------------- // private functions // ---------------------------------------------------------------------------- @@ -407,7 +431,7 @@ public: break; default: - wxFAIL_MSG( _T("unsupported wxTreeItemIcon value") ); + wxFAIL_MSG( wxT("unsupported wxTreeItemIcon value") ); } } @@ -724,7 +748,9 @@ void wxTreeCtrl::Init() m_pVirtualRoot = NULL; m_dragStarted = false; m_focusLost = true; + m_changingSelection = false; m_triggerStateImageClick = false; + m_mouseUpDeselect = false; // initialize the global array of events now as it can't be done statically // with the wxEVT_XXX values being allocated during run-time only @@ -841,7 +867,7 @@ wxTreeCtrl::GetClassDefaultAttributes(wxWindowVariant variant) bool wxTreeCtrl::DoGetItem(wxTreeViewItem *tvItem) const { wxCHECK_MSG( tvItem->hItem != TVI_ROOT, false, - _T("can't retrieve virtual root item") ); + wxT("can't retrieve virtual root item") ); if ( !TreeView_GetItem(GetHwnd(), tvItem) ) { @@ -1329,6 +1355,11 @@ wxTreeItemId wxTreeCtrl::GetSelection() const wxCHECK_MSG( !HasFlag(wxTR_MULTIPLE), wxTreeItemId(), wxT("this only works with single selection controls") ); + return GetFocusedItem(); +} + +wxTreeItemId wxTreeCtrl::GetFocusedItem() const +{ return wxTreeItemId(TreeView_GetSelection(GetHwnd())); } @@ -1473,7 +1504,7 @@ wxTreeItemId wxTreeCtrl::DoInsertAfter(const wxTreeItemId& parent, { wxCHECK_MSG( parent.IsOk() || !TreeView_GetRoot(GetHwnd()), wxTreeItemId(), - _T("can't have more than one root in the tree") ); + wxT("can't have more than one root in the tree") ); TV_INSERTSTRUCT tvIns; tvIns.hParent = HITEM(parent); @@ -1554,7 +1585,7 @@ wxTreeItemId wxTreeCtrl::AddRoot(const wxString& text, { if ( HasFlag(wxTR_HIDE_ROOT) ) { - wxASSERT_MSG( !m_pVirtualRoot, _T("tree can have only a single root") ); + wxASSERT_MSG( !m_pVirtualRoot, wxT("tree can have only a single root") ); // create a virtual root item, the parent for all the others wxTreeItemParam *param = new wxTreeItemParam; @@ -1595,7 +1626,7 @@ wxTreeItemId wxTreeCtrl::DoInsertItem(const wxTreeItemId& parent, // assert, not check: if the index is invalid, we will append the item // to the end - wxASSERT_MSG( index == 0, _T("bad index in wxTreeCtrl::InsertItem") ); + wxASSERT_MSG( index == 0, wxT("bad index in wxTreeCtrl::InsertItem") ); } return DoInsertAfter(parent, idPrev, text, image, selectedImage, data); @@ -1622,10 +1653,13 @@ void wxTreeCtrl::Delete(const wxTreeItemId& item) } } - if ( !TreeView_DeleteItem(GetHwnd(), HITEM(item)) ) { - wxLogLastError(wxT("TreeView_DeleteItem")); - return; + TempSetter set(m_changingSelection); + if ( !TreeView_DeleteItem(GetHwnd(), HITEM(item)) ) + { + wxLogLastError(wxT("TreeView_DeleteItem")); + return; + } } if ( !selected ) @@ -1633,6 +1667,12 @@ void wxTreeCtrl::Delete(const wxTreeItemId& item) return; } + if ( item == m_htSelStart ) + m_htSelStart.Unset(); + + if ( item == m_htClickedItem ) + m_htClickedItem.Unset(); + if ( next.IsOk() ) { wxTreeEvent changingEvent(wxEVT_COMMAND_TREE_SEL_CHANGING, this, next); @@ -1644,8 +1684,8 @@ void wxTreeCtrl::Delete(const wxTreeItemId& item) } else { - ::SelectItem(GetHwnd(), HITEM(next), false); - TreeView_SelectItem(GetHwnd(), 0); + DoUnselectItem(next); + ClearFocusedItem(); } } } @@ -1687,6 +1727,10 @@ void wxTreeCtrl::DeleteAllItems() // unlock tree selections on vista for the duration of this call TreeItemUnlocker unlock_all; + // invalidate all the items we store as they're going to become invalid + m_htSelStart = + m_htClickedItem = wxTreeItemId(); + // delete the "virtual" root item. if ( GET_VIRTUAL_ROOT() ) { @@ -1787,7 +1831,7 @@ void wxTreeCtrl::Unselect() if ( IsTreeEventAllowed(changingEvent) ) { - TreeView_SelectItem(GetHwnd(), 0); + ClearFocusedItem(); wxTreeEvent changedEvent(wxEVT_COMMAND_TREE_SEL_CHANGED, this, wxTreeItemId()); @@ -1797,7 +1841,7 @@ void wxTreeCtrl::Unselect() } else { - TreeView_SelectItem(GetHwnd(), 0); + ClearFocusedItem(); } } @@ -1808,7 +1852,7 @@ void wxTreeCtrl::DoUnselectAll() for ( size_t n = 0; n < count; n++ ) { - ::UnselectItem(GetHwnd(), HITEM(selections[n])); + DoUnselectItem(selections[n]); } m_htSelStart.Unset(); @@ -1827,7 +1871,6 @@ void wxTreeCtrl::UnselectAll() if ( IsTreeEventAllowed(changingEvent) ) { DoUnselectAll(); - TreeView_SelectItem(GetHwnd(), 0); wxTreeEvent changedEvent(wxEVT_COMMAND_TREE_SEL_CHANGED, this); changedEvent.m_itemOld = htFocus; @@ -1840,12 +1883,53 @@ void wxTreeCtrl::UnselectAll() } } +void wxTreeCtrl::DoSelectChildren(const wxTreeItemId& parent) +{ + DoUnselectAll(); + + wxTreeItemIdValue cookie; + wxTreeItemId child = GetFirstChild(parent, cookie); + while ( child.IsOk() ) + { + DoSelectItem(child, true); + child = GetNextChild(child, cookie); + } +} + +void wxTreeCtrl::SelectChildren(const wxTreeItemId& parent) +{ + wxCHECK_RET( HasFlag(wxTR_MULTIPLE), + "this only works with multiple selection controls" ); + + HTREEITEM htFocus = (HTREEITEM)TreeView_GetSelection(GetHwnd()); + + wxTreeEvent changingEvent(wxEVT_COMMAND_TREE_SEL_CHANGING, this); + changingEvent.m_itemOld = htFocus; + + if ( IsTreeEventAllowed(changingEvent) ) + { + DoSelectChildren(parent); + + wxTreeEvent changedEvent(wxEVT_COMMAND_TREE_SEL_CHANGED, this); + changedEvent.m_itemOld = htFocus; + (void)HandleTreeEvent(changedEvent); + } +} + +void wxTreeCtrl::DoSelectItem(const wxTreeItemId& item, bool select) +{ + TempSetter set(m_changingSelection); + + ::SelectItem(GetHwnd(), HITEM(item), select); +} + void wxTreeCtrl::SelectItem(const wxTreeItemId& item, bool select) { - wxCHECK_RET( !IsHiddenRoot(item), _T("can't select hidden root item") ); + wxCHECK_RET( !IsHiddenRoot(item), wxT("can't select hidden root item") ); - if ( IsSelected(item) == select ) + if ( select == IsSelected(item) ) { + // nothing to do, the item is already in the requested state return; } @@ -1856,11 +1940,11 @@ void wxTreeCtrl::SelectItem(const wxTreeItemId& item, bool select) if ( IsTreeEventAllowed(changingEvent) ) { HTREEITEM htFocus = (HTREEITEM)TreeView_GetSelection(GetHwnd()); - ::SelectItem(GetHwnd(), HITEM(item), select); + DoSelectItem(item, select); if ( !htFocus ) { - ::SetFocus(GetHwnd(), HITEM(item)); + SetFocusedItem(item); } wxTreeEvent changedEvent(wxEVT_COMMAND_TREE_SEL_CHANGED, @@ -1868,29 +1952,41 @@ void wxTreeCtrl::SelectItem(const wxTreeItemId& item, bool select) (void)HandleTreeEvent(changedEvent); } } - else + else // single selection { - wxASSERT_MSG( select, - _T("SelectItem(false) works only for multiselect") ); + wxTreeItemId itemOld, itemNew; + if ( select ) + { + itemOld = GetSelection(); + itemNew = item; + } + else // deselecting the currently selected item + { + itemOld = item; + // leave itemNew invalid + } // in spite of the docs (MSDN Jan 99 edition), we don't seem to receive // the notification from the control (i.e. TVN_SELCHANG{ED|ING}), so // send them ourselves - wxTreeEvent changingEvent(wxEVT_COMMAND_TREE_SEL_CHANGING, this, item); + wxTreeEvent + changingEvent(wxEVT_COMMAND_TREE_SEL_CHANGING, this, itemNew); + changingEvent.SetOldItem(itemOld); if ( IsTreeEventAllowed(changingEvent) ) { - if ( !TreeView_SelectItem(GetHwnd(), HITEM(item)) ) + if ( !TreeView_SelectItem(GetHwnd(), HITEM(itemNew)) ) { wxLogLastError(wxT("TreeView_SelectItem")); } else // ok { - ::SetFocus(GetHwnd(), HITEM(item)); + SetFocusedItem(item); wxTreeEvent changedEvent(wxEVT_COMMAND_TREE_SEL_CHANGED, - this, item); + this, itemNew); + changedEvent.SetOldItem(itemOld); (void)HandleTreeEvent(changedEvent); } } @@ -1900,7 +1996,7 @@ void wxTreeCtrl::SelectItem(const wxTreeItemId& item, bool select) void wxTreeCtrl::EnsureVisible(const wxTreeItemId& item) { - wxCHECK_RET( !IsHiddenRoot(item), _T("can't show hidden root item") ); + wxCHECK_RET( !IsHiddenRoot(item), wxT("can't show hidden root item") ); // no error return TreeView_EnsureVisible(GetHwnd(), HITEM(item)); @@ -2029,6 +2125,37 @@ bool wxTreeCtrl::GetBoundingRect(const wxTreeItemId& item, } } +void wxTreeCtrl::ClearFocusedItem() +{ + TempSetter set(m_changingSelection); + + if ( !TreeView_SelectItem(GetHwnd(), 0) ) + { + wxLogLastError(wxT("TreeView_SelectItem")); + } +} + +void wxTreeCtrl::SetFocusedItem(const wxTreeItemId& item) +{ + TempSetter set(m_changingSelection); + + ::SetFocus(GetHwnd(), HITEM(item)); +} + +void wxTreeCtrl::DoUnselectItem(const wxTreeItemId& item) +{ + TempSetter set(m_changingSelection); + + ::UnselectItem(GetHwnd(), HITEM(item)); +} + +void wxTreeCtrl::DoToggleItemSelection(const wxTreeItemId& item) +{ + TempSetter set(m_changingSelection); + + ::ToggleItemSelection(GetHwnd(), HITEM(item)); +} + // ---------------------------------------------------------------------------- // sorting stuff // ---------------------------------------------------------------------------- @@ -2131,6 +2258,15 @@ bool wxTreeCtrl::MSWCommand(WXUINT cmd, WXWORD id_) return true; } +bool wxTreeCtrl::MSWIsOnItem(unsigned flags) const +{ + unsigned mask = TVHT_ONITEM; + if ( HasFlag(wxTR_FULL_ROW_HIGHLIGHT) ) + mask |= TVHT_ONITEMINDENT | TVHT_ONITEMRIGHT; + + return (flags & mask) != 0; +} + bool wxTreeCtrl::MSWHandleSelectionKey(unsigned vkey) { const bool bCtrl = wxIsCtrlDown(); @@ -2152,7 +2288,7 @@ bool wxTreeCtrl::MSWHandleSelectionKey(unsigned vkey) if ( IsTreeEventAllowed(changingEvent) ) { - ::ToggleItemSelection(GetHwnd(), htSel); + DoToggleItemSelection(wxTreeItemId(htSel)); wxTreeEvent changedEvent(wxEVT_COMMAND_TREE_SEL_CHANGED, this, htSel); @@ -2174,7 +2310,7 @@ bool wxTreeCtrl::MSWHandleSelectionKey(unsigned vkey) if ( IsTreeEventAllowed(changingEvent) ) { DoUnselectAll(); - ::SelectItem(GetHwnd(), htSel); + DoSelectItem(wxTreeItemId(htSel)); wxTreeEvent changedEvent(wxEVT_COMMAND_TREE_SEL_CHANGED, this, htSel); @@ -2190,10 +2326,9 @@ bool wxTreeCtrl::MSWHandleSelectionKey(unsigned vkey) if ( !bCtrl && !bShift ) { wxArrayTreeItemIds selections; - size_t count = GetSelections(selections); wxTreeItemId next; - if ( htSel && count > 0 ) + if ( htSel ) { next = vkey == VK_UP ? TreeView_GetPrevVisible(GetHwnd(), htSel) @@ -2205,14 +2340,6 @@ bool wxTreeCtrl::MSWHandleSelectionKey(unsigned vkey) if ( IsHiddenRoot(next) ) next = TreeView_GetChild(GetHwnd(), HITEM(next)); - - if ( vkey == VK_DOWN ) - { - wxTreeItemId next2 = TreeView_GetNextVisible( - GetHwnd(), HITEM(next)); - if ( next2 ) - next = next2; - } } if ( !next.IsOk() ) @@ -2227,8 +2354,8 @@ bool wxTreeCtrl::MSWHandleSelectionKey(unsigned vkey) if ( IsTreeEventAllowed(changingEvent) ) { DoUnselectAll(); - ::SelectItem(GetHwnd(), HITEM(next)); - ::SetFocus(GetHwnd(), HITEM(next)); + DoSelectItem(next); + SetFocusedItem(next); wxTreeEvent changedEvent(wxEVT_COMMAND_TREE_SEL_CHANGED, this, next); @@ -2269,7 +2396,7 @@ bool wxTreeCtrl::MSWHandleSelectionKey(unsigned vkey) } } - ::SetFocus(GetHwnd(), HITEM(next)); + SetFocusedItem(next); } break; @@ -2291,8 +2418,8 @@ bool wxTreeCtrl::MSWHandleSelectionKey(unsigned vkey) if ( IsTreeEventAllowed(changingEvent) ) { DoUnselectAll(); - ::SelectItem(GetHwnd(), HITEM(next)); - ::SetFocus(GetHwnd(), HITEM(next)); + DoSelectItem(next); + SetFocusedItem(next); wxTreeEvent changedEvent(wxEVT_COMMAND_TREE_SEL_CHANGED, this, next); @@ -2326,8 +2453,8 @@ bool wxTreeCtrl::MSWHandleSelectionKey(unsigned vkey) if ( IsTreeEventAllowed(changingEvent) ) { DoUnselectAll(); - ::SelectItem(GetHwnd(), HITEM(next)); - ::SetFocus(GetHwnd(), HITEM(next)); + DoSelectItem(next); + SetFocusedItem(next); wxTreeEvent changedEvent(wxEVT_COMMAND_TREE_SEL_CHANGED, this, next); changedEvent.m_itemOld = htSel; @@ -2386,7 +2513,7 @@ bool wxTreeCtrl::MSWHandleSelectionKey(unsigned vkey) SelectRange(GetHwnd(), HITEM(m_htSelStart), HITEM(next), SR_UNSELECT_OTHERS); - ::SetFocus(GetHwnd(), HITEM(next)); + SetFocusedItem(next); wxTreeEvent changedEvent(wxEVT_COMMAND_TREE_SEL_CHANGED, this, next); @@ -2404,8 +2531,8 @@ bool wxTreeCtrl::MSWHandleSelectionKey(unsigned vkey) if ( IsTreeEventAllowed(changingEvent) ) { DoUnselectAll(); - ::SelectItem(GetHwnd(), HITEM(next)); - ::SetFocus(GetHwnd(), HITEM(next)); + DoSelectItem(next); + SetFocusedItem(next); wxTreeEvent changedEvent(wxEVT_COMMAND_TREE_SEL_CHANGED, this, next); @@ -2507,8 +2634,8 @@ bool wxTreeCtrl::MSWHandleSelectionKey(unsigned vkey) { DoUnselectAll(); m_htSelStart.Unset(); - ::SelectItem(GetHwnd(), HITEM(next)); - ::SetFocus(GetHwnd(), HITEM(next)); + DoSelectItem(next); + SetFocusedItem(next); wxTreeEvent changedEvent(wxEVT_COMMAND_TREE_SEL_CHANGED, this, next); @@ -2639,14 +2766,21 @@ wxTreeCtrl::MSWWindowProc(WXUINT nMsg, WXWPARAM wParam, WXLPARAM lParam) if ( !isMultiple ) break; - processed = true; m_htClickedItem.Unset(); - if ( !(tvht.flags & TVHT_ONITEM) ) + if ( !MSWIsOnItem(tvht.flags) ) { - if ( !HandleMouseEvent(nMsg, x, y, wParam) ) + if ( tvht.flags & TVHT_ONITEMBUTTON ) { - if ( tvht.flags & TVHT_ONITEMBUTTON ) + // either it's going to be handled by user code or + // we're going to use it ourselves to toggle the + // branch, in either case don't pass it to the base + // class which would generate another mouse click event + // for it even though it's already handled here + processed = true; + SetFocus(); + + if ( !HandleMouseEvent(nMsg, x, y, wParam) ) { if ( !IsExpanded(htItem) ) { @@ -2659,9 +2793,11 @@ wxTreeCtrl::MSWWindowProc(WXUINT nMsg, WXWPARAM wParam, WXLPARAM lParam) } } + m_focusLost = false; break; } + processed = true; SetFocus(); m_htClickedItem = (WXHTREEITEM) htItem; m_ptClick = wxPoint(x, y); @@ -2681,9 +2817,9 @@ wxTreeCtrl::MSWWindowProc(WXUINT nMsg, WXWPARAM wParam, WXLPARAM lParam) if ( IsTreeEventAllowed(changingEvent) ) { // toggle selected state - ::ToggleItemSelection(GetHwnd(), htItem); + DoToggleItemSelection(wxTreeItemId(htItem)); - ::SetFocus(GetHwnd(), htItem); + SetFocusedItem(wxTreeItemId(htItem)); // reset on any click without Shift m_htSelStart.Unset(); @@ -2738,10 +2874,10 @@ wxTreeCtrl::MSWWindowProc(WXUINT nMsg, WXWPARAM wParam, WXLPARAM lParam) } else { - ::SelectItem(GetHwnd(), htItem); + DoSelectItem(wxTreeItemId(htItem)); } - ::SetFocus(GetHwnd(), htItem); + SetFocusedItem(wxTreeItemId(htItem)); wxTreeEvent changedEvent(wxEVT_COMMAND_TREE_SEL_CHANGED, this, htItem); @@ -2772,7 +2908,6 @@ wxTreeCtrl::MSWWindowProc(WXUINT nMsg, WXWPARAM wParam, WXLPARAM lParam) // clicked outside of the present selection, otherwise, // perform the deselection on mouse-up, this allows // multiple drag and drop to work. - if ( !IsItemSelected(GetHwnd(), htItem)) { wxTreeEvent changingEvent(wxEVT_COMMAND_TREE_SEL_CHANGING, @@ -2782,8 +2917,8 @@ wxTreeCtrl::MSWWindowProc(WXUINT nMsg, WXWPARAM wParam, WXLPARAM lParam) if ( IsTreeEventAllowed(changingEvent) ) { DoUnselectAll(); - ::SelectItem(GetHwnd(), htItem); - ::SetFocus(GetHwnd(), htItem); + DoSelectItem(wxTreeItemId(htItem)); + SetFocusedItem(wxTreeItemId(htItem)); wxTreeEvent changedEvent(wxEVT_COMMAND_TREE_SEL_CHANGED, this, htItem); @@ -2793,7 +2928,8 @@ wxTreeCtrl::MSWWindowProc(WXUINT nMsg, WXWPARAM wParam, WXLPARAM lParam) } else { - ::SetFocus(GetHwnd(), htItem); + SetFocusedItem(wxTreeItemId(htItem)); + m_mouseUpDeselect = true; } } else // click on a single selected item @@ -2808,11 +2944,14 @@ wxTreeCtrl::MSWWindowProc(WXUINT nMsg, WXWPARAM wParam, WXLPARAM lParam) // since previous click if ( m_focusLost ) { - TreeView_SelectItem(GetHwnd(), 0); - ::SelectItem(GetHwnd(), htItem); + ClearFocusedItem(); + DoSelectItem(wxTreeItemId(htItem)); + SetFocusedItem(wxTreeItemId(htItem)); + } + else + { + processed = false; } - - processed = false; } // reset on any click without Shift @@ -2860,8 +2999,8 @@ wxTreeCtrl::MSWWindowProc(WXUINT nMsg, WXWPARAM wParam, WXLPARAM lParam) if ( IsTreeEventAllowed(changingEvent) ) { DoUnselectAll(); - ::SelectItem(GetHwnd(), htItem); - ::SetFocus(GetHwnd(), htItem); + DoSelectItem(wxTreeItemId(htItem)); + SetFocusedItem(wxTreeItemId(htItem)); wxTreeEvent changedEvent(wxEVT_COMMAND_TREE_SEL_CHANGED, this, htItem); @@ -2940,16 +3079,13 @@ wxTreeCtrl::MSWWindowProc(WXUINT nMsg, WXWPARAM wParam, WXLPARAM lParam) case WM_LBUTTONUP: if ( isMultiple ) { - // deselect other items if multiple items selected + // deselect other items if needed if ( htItem ) { - wxArrayTreeItemIds selections; - size_t count = GetSelections(selections); - - if ( count > 1 && - !(wParam & MK_CONTROL) && - !(wParam & MK_SHIFT) ) + if ( m_mouseUpDeselect ) { + m_mouseUpDeselect = false; + wxTreeEvent changingEvent(wxEVT_COMMAND_TREE_SEL_CHANGING, this, htItem); changingEvent.m_itemOld = htOldItem; @@ -2957,8 +3093,8 @@ wxTreeCtrl::MSWWindowProc(WXUINT nMsg, WXWPARAM wParam, WXLPARAM lParam) if ( IsTreeEventAllowed(changingEvent) ) { DoUnselectAll(); - ::SelectItem(GetHwnd(), htItem); - ::SetFocus(GetHwnd(), htItem); + DoSelectItem(wxTreeItemId(htItem)); + SetFocusedItem(wxTreeItemId(htItem)); wxTreeEvent changedEvent(wxEVT_COMMAND_TREE_SEL_CHANGED, this, htItem); @@ -2983,10 +3119,7 @@ wxTreeCtrl::MSWWindowProc(WXUINT nMsg, WXWPARAM wParam, WXLPARAM lParam) } } - if ( !m_dragStarted && - (tvht.flags & TVHT_ONITEMSTATEICON || - tvht.flags & TVHT_ONITEMICON || - tvht.flags & TVHT_ONITEM) ) + if ( !m_dragStarted && MSWIsOnItem(tvht.flags) ) { processed = true; } @@ -3077,17 +3210,18 @@ wxTreeCtrl::MSWWindowProc(WXUINT nMsg, WXWPARAM wParam, WXLPARAM lParam) case VK_END: case VK_PRIOR: case VK_NEXT: - if ( !MSWHandleTreeKeyDownEvent(wParam, lParam) ) + if ( !HandleKeyDown(wParam, lParam) && + !MSWHandleTreeKeyDownEvent(wParam, lParam) ) { // use the key to update the selection if it was left // unprocessed MSWHandleSelectionKey(wParam); - - // pretend that we did process it in any case as we already - // generated an event for it - processed = true; } + // pretend that we did process it in any case as we already + // generated an event for it + processed = true; + //default: for all the other keys leave processed as false so that // the tree control generates a TVN_KEYDOWN for us } @@ -3311,7 +3445,6 @@ bool wxTreeCtrl::MSWOnNotify(int idCtrl, WXLPARAM lParam, WXLPARAM *result) return MSWHandleTreeKeyDownEvent( info->wVKey, (wxIsAltDown() ? KF_ALTDOWN : 0) << 16); } - break; // Vista's tree control has introduced some problems with our @@ -3349,7 +3482,7 @@ bool wxTreeCtrl::MSWOnNotify(int idCtrl, WXLPARAM lParam, WXLPARAM *result) // we have to handle both messages: case TVN_SELCHANGEDA: case TVN_SELCHANGEDW: - if ( !HasFlag(wxTR_MULTIPLE) ) + if ( !HasFlag(wxTR_MULTIPLE) || !m_changingSelection ) { eventType = wxEVT_COMMAND_TREE_SEL_CHANGED; } @@ -3357,7 +3490,7 @@ bool wxTreeCtrl::MSWOnNotify(int idCtrl, WXLPARAM lParam, WXLPARAM *result) case TVN_SELCHANGINGA: case TVN_SELCHANGINGW: - if ( !HasFlag(wxTR_MULTIPLE) ) + if ( !HasFlag(wxTR_MULTIPLE) || !m_changingSelection ) { if ( eventType == wxEVT_NULL ) eventType = wxEVT_COMMAND_TREE_SEL_CHANGING; @@ -3421,7 +3554,7 @@ bool wxTreeCtrl::MSWOnNotify(int idCtrl, WXLPARAM lParam, WXLPARAM *result) if ( !loaded ) { - wxLoadedDLL dllComCtl32(_T("comctl32.dll")); + wxLoadedDLL dllComCtl32(wxT("comctl32.dll")); if ( dllComCtl32.IsLoaded() ) wxDL_INIT_FUNC(s_pfn, ImageList_Copy, dllComCtl32); } @@ -3569,7 +3702,7 @@ bool wxTreeCtrl::MSWOnNotify(int idCtrl, WXLPARAM lParam, WXLPARAM *result) ::ScreenToClient(GetHwnd(), &tvhti.pt); if ( TreeView_HitTest(GetHwnd(), &tvhti) ) { - if ( tvhti.flags & TVHT_ONITEM ) + if ( MSWIsOnItem(tvhti.flags) ) { event.m_item = tvhti.hItem; eventType = (int)hdr->code == NM_DBLCLK @@ -3623,7 +3756,7 @@ bool wxTreeCtrl::MSWOnNotify(int idCtrl, WXLPARAM lParam, WXLPARAM *result) { // normally this is impossible because the m_dragImage is // deleted once the drag operation is over - wxASSERT_MSG( !m_dragImage, _T("starting to drag once again?") ); + wxASSERT_MSG( !m_dragImage, wxT("starting to drag once again?") ); m_dragImage = new wxDragImage(*this, event.m_item); m_dragImage->BeginDrag(wxPoint(0,0), this);