X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/06110b0006f7477a0aca90f75786ffb084d4204f..76d81b4d11617b806d6ab9bd60614c39999cdece:/src/msw/treectrl.cpp diff --git a/src/msw/treectrl.cpp b/src/msw/treectrl.cpp index 5ba4dc839c..a488f9c547 100644 --- a/src/msw/treectrl.cpp +++ b/src/msw/treectrl.cpp @@ -97,7 +97,7 @@ static bool IsItemSelected(HWND hwndTV, HTREEITEM hItem) return (tvi.state & TVIS_SELECTED) != 0; } -static void SelectItem(HWND hwndTV, HTREEITEM hItem, bool select = true) +static bool SelectItem(HWND hwndTV, HTREEITEM hItem, bool select = true) { TV_ITEM tvi; tvi.mask = TVIF_STATE | TVIF_HANDLE; @@ -108,7 +108,10 @@ static void SelectItem(HWND hwndTV, HTREEITEM hItem, bool select = true) if ( TreeView_SetItem(hwndTV, &tvi) == -1 ) { wxLogLastError(wxT("TreeView_SetItem")); + return false; } + + return true; } static inline void UnselectItem(HWND hwndTV, HTREEITEM htItem) @@ -482,7 +485,7 @@ wxBEGIN_FLAGS( wxTreeCtrlStyle ) wxFLAGS_MEMBER(wxBORDER_RAISED) wxFLAGS_MEMBER(wxBORDER_STATIC) wxFLAGS_MEMBER(wxBORDER_NONE) - + // old style border flags wxFLAGS_MEMBER(wxSIMPLE_BORDER) wxFLAGS_MEMBER(wxSUNKEN_BORDER) @@ -521,15 +524,15 @@ wxEND_FLAGS( wxTreeCtrlStyle ) IMPLEMENT_DYNAMIC_CLASS_XTI(wxTreeCtrl, wxControl,"wx/treectrl.h") wxBEGIN_PROPERTIES_TABLE(wxTreeCtrl) - wxEVENT_PROPERTY( TextUpdated , wxEVT_COMMAND_TEXT_UPDATED , wxCommandEvent ) + wxEVENT_PROPERTY( TextUpdated , wxEVT_COMMAND_TEXT_UPDATED , wxCommandEvent ) wxEVENT_RANGE_PROPERTY( TreeEvent , wxEVT_COMMAND_TREE_BEGIN_DRAG , wxEVT_COMMAND_TREE_STATE_IMAGE_CLICK , wxTreeEvent ) - wxPROPERTY_FLAGS( WindowStyle , wxTreeCtrlStyle , long , SetWindowStyleFlag , GetWindowStyleFlag , , 0 /*flags*/ , wxT("Helpstring") , wxT("group")) // style + wxPROPERTY_FLAGS( WindowStyle , wxTreeCtrlStyle , long , SetWindowStyleFlag , GetWindowStyleFlag , EMPTY_MACROVALUE , 0 /*flags*/ , wxT("Helpstring") , wxT("group")) // style wxEND_PROPERTIES_TABLE() wxBEGIN_HANDLERS_TABLE(wxTreeCtrl) wxEND_HANDLERS_TABLE() -wxCONSTRUCTOR_5( wxTreeCtrl , wxWindow* , Parent , wxWindowID , Id , wxPoint , Position , wxSize , Size , long , WindowStyle ) +wxCONSTRUCTOR_5( wxTreeCtrl , wxWindow* , Parent , wxWindowID , Id , wxPoint , Position , wxSize , Size , long , WindowStyle ) #else IMPLEMENT_DYNAMIC_CLASS(wxTreeCtrl, wxControl) #endif @@ -674,6 +677,11 @@ bool wxTreeCtrl::Create(wxWindow *parent, wstyle |= TVS_CHECKBOXES; #endif // wxUSE_CHECKBOXES_IN_MULTI_SEL_TREE +#ifndef __WXWINCE__ + // Need so that TVN_GETINFOTIP messages will be sent + wstyle |= TVS_INFOTIP; +#endif + // Create the tree control. if ( !MSWCreateControl(WC_TREEVIEW, wstyle) ) return false; @@ -749,6 +757,8 @@ bool wxTreeCtrl::Create(wxWindow *parent, SetSize(pos.x, pos.y, size.x, size.y); + wxSetCCUnicodeFormat(GetHwnd()); + return true; } @@ -777,6 +787,18 @@ wxTreeCtrl::~wxTreeCtrl() // accessors // ---------------------------------------------------------------------------- +/* static */ wxVisualAttributes +wxTreeCtrl::GetClassDefaultAttributes(wxWindowVariant variant) +{ + wxVisualAttributes attrs = GetCompositeControlsDefaultAttributes(variant); + + // common controls have their own default font + attrs.font = wxGetCCDefaultFont(); + + return attrs; +} + + // simple wrappers which add error checking in debug mode bool wxTreeCtrl::DoGetItem(wxTreeViewItem* tvItem) const @@ -1859,19 +1881,22 @@ void wxTreeCtrl::UnselectAll() } } -void wxTreeCtrl::SelectItem(const wxTreeItemId& item) +void wxTreeCtrl::SelectItem(const wxTreeItemId& item, bool select) { if ( m_windowStyle & wxTR_MULTIPLE ) { #if wxUSE_CHECKBOXES_IN_MULTI_SEL_TREE // selecting the item means checking it - SetItemCheck(item); + SetItemCheck(item, select); #else // !wxUSE_CHECKBOXES_IN_MULTI_SEL_TREE - ::SelectItem(GetHwnd(), HITEM(item)); + ::SelectItem(GetHwnd(), HITEM(item), select); #endif // wxUSE_CHECKBOXES_IN_MULTI_SEL_TREE/!wxUSE_CHECKBOXES_IN_MULTI_SEL_TREE } else { + wxASSERT_MSG( select, + _T("SelectItem(false) works only for multiselect") ); + // inspite 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 @@ -1887,7 +1912,7 @@ void wxTreeCtrl::SelectItem(const wxTreeItemId& item) { wxLogLastError(wxT("TreeView_SelectItem")); } - else + else // ok { event.SetEventType(wxEVT_COMMAND_TREE_SEL_CHANGED); (void)GetEventHandler()->ProcessEvent(event); @@ -1897,6 +1922,16 @@ void wxTreeCtrl::SelectItem(const wxTreeItemId& item) } } +void wxTreeCtrl::UnselectItem(const wxTreeItemId& item) +{ + SelectItem(item, false); +} + +void wxTreeCtrl::ToggleItemSelection(const wxTreeItemId& item) +{ + SelectItem(item, !IsSelected(item)); +} + void wxTreeCtrl::EnsureVisible(const wxTreeItemId& item) { // no error return @@ -2117,10 +2152,10 @@ bool wxTreeCtrl::MSWCommand(WXUINT cmd, WXWORD id) // only do it during dragging, minimize wxWin overhead (this is important for // WM_MOUSEMOVE as they're a lot of them) by catching Windows messages directly // instead of passing by wxWin events -long wxTreeCtrl::MSWWindowProc(WXUINT nMsg, WXWPARAM wParam, WXLPARAM lParam) +WXLRESULT wxTreeCtrl::MSWWindowProc(WXUINT nMsg, WXWPARAM wParam, WXLPARAM lParam) { bool processed = false; - long rc = 0; + WXLRESULT rc = 0; bool isMultiple = (GetWindowStyle() & wxTR_MULTIPLE) != 0; if ( (nMsg >= WM_MOUSEFIRST) && (nMsg <= WM_MOUSELAST) ) @@ -2157,7 +2192,7 @@ long wxTreeCtrl::MSWWindowProc(WXUINT nMsg, WXWPARAM wParam, WXLPARAM lParam) SetFocus(); // toggle selected state - ToggleItemSelection(GetHwnd(), htItem); + ::ToggleItemSelection(GetHwnd(), htItem); ::SetFocus(GetHwnd(), htItem); @@ -2188,7 +2223,7 @@ long wxTreeCtrl::MSWWindowProc(WXUINT nMsg, WXWPARAM wParam, WXLPARAM lParam) { // avoid doing anything if we click on the only // currently selected item - + wxArrayTreeItemIds selections; size_t count = GetSelections(selections); if ( count == 0 || @@ -2199,7 +2234,7 @@ long wxTreeCtrl::MSWWindowProc(WXUINT nMsg, WXWPARAM wParam, WXLPARAM lParam) // user 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)) { ::SetFocus(GetHwnd(), htItem); @@ -2320,7 +2355,7 @@ long wxTreeCtrl::MSWWindowProc(WXUINT nMsg, WXWPARAM wParam, WXLPARAM lParam) { if ( bCtrl ) { - ToggleItemSelection(GetHwnd(), htSel); + ::ToggleItemSelection(GetHwnd(), htSel); } else { @@ -2459,6 +2494,30 @@ bool wxTreeCtrl::MSWOnNotify(int idCtrl, WXLPARAM lParam, WXLPARAM *result) break; } +#ifndef __WXWINCE__ + // These *must* not be removed or TVN_GETINFOTIP will + // not be processed each time the mouse is moved + // and the tooltip will only ever update once. + case TTN_NEEDTEXTA: + case TTN_NEEDTEXTW: + { + *result = 0; + + break; + } + + case TVN_GETINFOTIP: + { + eventType = wxEVT_COMMAND_TREE_ITEM_GETTOOLTIP; + NMTVGETINFOTIP *info = (NMTVGETINFOTIP*)lParam; + + // Which item are we trying to get a tooltip for? + event.m_item = info->hItem; + + break; + } +#endif + case TVN_GETDISPINFO: eventType = wxEVT_COMMAND_TREE_GET_INFO; // fall through @@ -2549,7 +2608,7 @@ bool wxTreeCtrl::MSWOnNotify(int idCtrl, WXLPARAM lParam, WXLPARAM *result) } break; - // NB: MSLU is broken and sends TVN_SELCHANGEDA instead of + // NB: MSLU is broken and sends TVN_SELCHANGEDA instead of // TVN_SELCHANGEDW in Unicode mode under Win98. Therefore // we have to handle both messages: case TVN_SELCHANGEDA: @@ -2564,7 +2623,7 @@ bool wxTreeCtrl::MSWOnNotify(int idCtrl, WXLPARAM lParam, WXLPARAM *result) eventType = wxEVT_COMMAND_TREE_SEL_CHANGING; //else: already set above - if (hdr->code == TVN_SELCHANGINGW || + if (hdr->code == TVN_SELCHANGINGW || hdr->code == TVN_SELCHANGEDW) { NM_TREEVIEWW* tv = (NM_TREEVIEWW *)lParam; @@ -2610,60 +2669,42 @@ bool wxTreeCtrl::MSWOnNotify(int idCtrl, WXLPARAM lParam, WXLPARAM *result) wxTreeItemAttr * const attr = it->second; - HFONT hFont; - if ( attr->HasFont() ) - { - hFont = GetHfontOf(attr->GetFont()); - } - else - { - hFont = 0; - } - - wxColour colText; - if ( attr->HasTextColour() ) - { - colText = attr->GetTextColour(); - } - else - { - colText = GetForegroundColour(); - } - - // selection colours should override ours - if ( nmcd.uItemState & CDIS_SELECTED ) - { - lptvcd->clrTextBk = - ::GetSysColor(COLOR_HIGHLIGHT); - lptvcd->clrText = - ::GetSysColor(COLOR_HIGHLIGHTTEXT); - } - else // !selected + // selection colours should override ours, + // otherwise it is too confusing ot the user + if ( !(nmcd.uItemState & CDIS_SELECTED) ) { wxColour colBack; if ( attr->HasBackgroundColour() ) { colBack = attr->GetBackgroundColour(); + lptvcd->clrTextBk = wxColourToRGB(colBack); } - else + } + + // but we still want to keep the special foreground + // colour when we don't have focus (we can't keep + // it when we do, it would usually be unreadable on + // the almost inverted bg colour...) + if ( !(nmcd.uItemState & CDIS_SELECTED) || + FindFocus() != this ) + { + wxColour colText; + if ( attr->HasTextColour() ) { - colBack = GetBackgroundColour(); + colText = attr->GetTextColour(); + lptvcd->clrText = wxColourToRGB(colText); } - - lptvcd->clrText = wxColourToRGB(colText); - lptvcd->clrTextBk = wxColourToRGB(colBack); } - // note that if we wanted to set colours for - // individual columns (subitems), we would have - // returned CDRF_NOTIFYSUBITEMREDRAW from here - if ( hFont ) + if ( attr->HasFont() ) { + HFONT hFont = GetHfontOf(attr->GetFont()); + ::SelectObject(nmcd.hdc, hFont); *result = CDRF_NEWFONT; } - else + else // no specific font { *result = CDRF_DODEFAULT; } @@ -2788,7 +2829,7 @@ bool wxTreeCtrl::MSWOnNotify(int idCtrl, WXLPARAM lParam, WXLPARAM *result) HWND hText = TreeView_GetEditControl(GetHwnd()); if(hText != NULL) { - // MBN: if m_textCtrl already has an HWND, it is a stale + // MBN: if m_textCtrl already has an HWND, it is a stale // pointer from a previous edit (because the user // didn't modify the label before dismissing the control, // and TVN_ENDLABELEDIT was not sent), so delete it @@ -2823,6 +2864,18 @@ bool wxTreeCtrl::MSWOnNotify(int idCtrl, WXLPARAM lParam, WXLPARAM *result) DeleteTextCtrl(); break; +#ifndef __WXWINCE__ + case TVN_GETINFOTIP: + { + // If the user permitted a tooltip change, change it + if (event.IsAllowed()) + { + SetToolTip(event.m_label); + } + } + break; +#endif + case TVN_SELCHANGING: case TVN_ITEMEXPANDING: // return true to prevent the action from happening @@ -2899,7 +2952,7 @@ void wxTreeCtrl::SetState(const wxTreeItemId& node, int state) // Select the specified state, or -1 == cycle to the next one. if ( state == -1 ) { - TreeView_GetItem(GetHwnd(), &tvi); + TreeView_GetItem(GetHwnd(), &tvi); state = STATEIMAGEMASKTOINDEX(tvi.state) + 1; if ( state == m_imageListState->GetImageCount() ) @@ -2909,7 +2962,7 @@ void wxTreeCtrl::SetState(const wxTreeItemId& node, int state) wxCHECK_RET( state < m_imageListState->GetImageCount(), _T("wxTreeCtrl::SetState(): item index out of bounds") ); - tvi.state = INDEXTOSTATEIMAGEMASK(state); + tvi.state = INDEXTOSTATEIMAGEMASK(state); TreeView_SetItem(GetHwnd(), &tvi); } @@ -2920,7 +2973,7 @@ int wxTreeCtrl::GetState(const wxTreeItemId& node) tvi.hItem = (HTREEITEM)node.m_pItem; tvi.mask = TVIF_STATE; tvi.stateMask = TVIS_STATEIMAGEMASK; - TreeView_GetItem(GetHwnd(), &tvi); + TreeView_GetItem(GetHwnd(), &tvi); return STATEIMAGEMASKTOINDEX(tvi.state); }