X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/b275d3475206c844580427cdee231304a162a285..5778dedc92f6d31435aa1cda6846979a0e9ad35b:/src/msw/listctrl.cpp diff --git a/src/msw/listctrl.cpp b/src/msw/listctrl.cpp index 93eebf755c..484443466f 100644 --- a/src/msw/listctrl.cpp +++ b/src/msw/listctrl.cpp @@ -497,8 +497,7 @@ void wxListCtrl::DeleteEditControl() { m_textCtrl->UnsubclassWin(); m_textCtrl->SetHWND(0); - delete m_textCtrl; - m_textCtrl = NULL; + wxDELETE(m_textCtrl); } } @@ -1031,12 +1030,13 @@ bool wxListCtrl::SetItemColumnImage(long item, long column, int image) } // Gets the item text -wxString wxListCtrl::GetItemText(long item) const +wxString wxListCtrl::GetItemText(long item, int col) const { wxListItem info; info.m_mask = wxLIST_MASK_TEXT; info.m_itemId = item; + info.m_col = col; if (!GetItem(info)) return wxEmptyString; @@ -1183,7 +1183,7 @@ bool wxListCtrl::GetSubItemRect(long item, long subItem, wxRect& rect, int code) // there is no way to retrieve the first sub item bounding rectangle using // wxGetListCtrlSubItemRect() as 0 means the whole item, so we need to // truncate it at first column ourselves - if ( subItem == 0 ) + if ( subItem == 0 && code == wxLIST_RECT_BOUNDS ) rect.width = GetColumnWidth(0); return true; @@ -1538,8 +1538,7 @@ wxTextCtrl* wxListCtrl::EditLabel(long item, wxClassInfo* textControlClass) if ( !hWnd ) { // failed to start editing - delete m_textCtrl; - m_textCtrl = NULL; + wxDELETE(m_textCtrl); return NULL; } @@ -1560,14 +1559,21 @@ bool wxListCtrl::EndEditLabel(bool cancel) if ( !hwnd ) return false; - if ( cancel ) - ::SetWindowText(hwnd, wxEmptyString); // dubious but better than nothing - - // we shouldn't destroy the control ourselves according to MSDN, which - // proposes WM_CANCELMODE to do this, but it doesn't seem to work - // - // posting WM_CLOSE to it does seem to work without any side effects - ::PostMessage(hwnd, WM_CLOSE, 0, 0); + // Newer versions of Windows have a special message for cancelling editing, + // use it if available. +#ifdef ListView_CancelEditLabel + if ( cancel && (wxApp::GetComCtl32Version() >= 600) ) + { + ListView_CancelEditLabel(GetHwnd()); + } + else +#endif // ListView_CancelEditLabel + { + // We shouldn't destroy the control ourselves according to MSDN, which + // proposes WM_CANCELMODE to do this, but it doesn't seem to work so + // emulate the corresponding user action instead. + ::SendMessage(hwnd, WM_KEYDOWN, cancel ? VK_ESCAPE : VK_RETURN, 0); + } return true; } @@ -1753,7 +1759,10 @@ long wxListCtrl::InsertItem(const wxListItem& info) } } - long rv = ListView_InsertItem(GetHwnd(), & item); + const long rv = ListView_InsertItem(GetHwnd(), & item); + + // failing to insert the item is really unexpected + wxCHECK_MSG( rv != -1, rv, "failed to insert an item in wxListCtrl" ); m_count++; wxASSERT_MSG( m_count == ListView_GetItemCount(GetHwnd()), @@ -2026,29 +2035,50 @@ bool wxListCtrl::MSWOnNotify(int idCtrl, WXLPARAM lParam, WXLPARAM *result) event.m_itemIndex = -1; + bool ignore = false; switch ( nmhdr->code ) { // yet another comctl32.dll bug: under NT/W2K it sends Unicode // TRACK messages even to ANSI programs: on my system I get - // HDN_BEGINTRACKW and HDN_ENDTRACKA and no HDN_TRACK at all! + // HDN_BEGINTRACKW and HDN_ENDTRACKA! // // work around is to simply catch both versions and hope that it // works (why should this message exist in ANSI and Unicode is // beyond me as it doesn't deal with strings at all...) // - // note that fr HDN_TRACK another possibility could be to use - // HDN_ITEMCHANGING but it is sent even after HDN_ENDTRACK and when - // something other than the item width changes so we'd have to - // filter out the unwanted events then + // another problem is that HDN_TRACK is not sent at all by header + // with HDS_FULLDRAG style which is used by default by wxListCtrl + // under recent Windows versions (starting from at least XP) so we + // need to use HDN_ITEMCHANGING instead of it case HDN_BEGINTRACKA: case HDN_BEGINTRACKW: eventType = wxEVT_COMMAND_LIST_COL_BEGIN_DRAG; // fall through - case HDN_TRACKA: - case HDN_TRACKW: + case HDN_ITEMCHANGING: if ( eventType == wxEVT_NULL ) + { + if ( !nmHDR->pitem || !(nmHDR->pitem->mask & HDI_WIDTH) ) + { + // something other than the width is being changed, + // ignore it + ignore = true; + break; + } + + // also ignore the events sent when the width didn't really + // change: this is not just an optimization but also gets + // rid of a useless and unexpected DRAGGING event which + // would otherwise be sent after the END_DRAG one as we get + // an HDN_ITEMCHANGING after HDN_ENDTRACK for some reason + if ( nmHDR->pitem->cxy == GetColumnWidth(nmHDR->iItem) ) + { + ignore = true; + break; + } + eventType = wxEVT_COMMAND_LIST_COL_DRAGGING; + } // fall through case HDN_ENDTRACKA: @@ -2086,8 +2116,11 @@ bool wxListCtrl::MSWOnNotify(int idCtrl, WXLPARAM lParam, WXLPARAM *result) return true; default: - return wxControl::MSWOnNotify(idCtrl, lParam, result); + ignore = true; } + + if ( ignore ) + return wxControl::MSWOnNotify(idCtrl, lParam, result); } else #endif // defined(HDN_BEGINTRACKA) @@ -2211,8 +2244,7 @@ bool wxListCtrl::MSWOnNotify(int idCtrl, WXLPARAM lParam, WXLPARAM *result) if ( m_internalData[n] == data ) { m_internalData.erase(m_internalData.begin() + n); - delete data; - data = NULL; + wxDELETE(data); break; } } @@ -2451,7 +2483,7 @@ bool wxListCtrl::MSWOnNotify(int idCtrl, WXLPARAM lParam, WXLPARAM *result) // wrap to the beginning if necessary if ( currentPos == maxPos ) { - // somewhat surprizingly, LVFI_WRAP isn't set in + // somewhat surprisingly, LVFI_WRAP isn't set in // flags but we still should wrap currentPos = 0; }