X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/2a1f999fafa4312ccd47b7be65c672c2220fea36..4f433feff9251ded00bba26b633f93e660cd44c4:/src/msw/listctrl.cpp?ds=sidebyside diff --git a/src/msw/listctrl.cpp b/src/msw/listctrl.cpp index dd212e951c..3769867501 100644 --- a/src/msw/listctrl.cpp +++ b/src/msw/listctrl.cpp @@ -56,6 +56,15 @@ // include "properly" #include "wx/msw/wrapcctl.h" +// Currently gcc and watcom don't define NMLVFINDITEM, and DMC only defines +// it by its old name NM_FINDTIEM. +// +#if defined(__VISUALC__) || defined(__BORLANDC__) || defined(NMLVFINDITEM) + #define HAVE_NMLVFINDITEM 1 +#elif defined(__DMC__) || defined(NM_FINDITEM) + #define HAVE_NM_FINDITEM 1 +#endif + // ---------------------------------------------------------------------------- // private functions // ---------------------------------------------------------------------------- @@ -166,7 +175,7 @@ private: // // Solution: // Under MSW the only way to associate data with a List -// item independant of its position in the list is to +// item independent of its position in the list is to // store a pointer to it in its lParam attribute. However // user programs are already using this (via the // SetItemData() GetItemData() calls). @@ -357,12 +366,12 @@ bool wxListCtrl::Create(wxWindow *parent, // versions of _some_ messages (notably LVN_GETDISPINFOA) in MSLU build wxSetCCUnicodeFormat(GetHwnd()); - // for comctl32.dll v 4.70+ we want to have this attribute because it's - // prettier (and also because wxGTK does it like this) + // for comctl32.dll v 4.70+ we want to have some non default extended + // styles because it's prettier (and also because wxGTK does it like this) if ( InReportView() && wxApp::GetComCtl32Version() >= 470 ) { ::SendMessage(GetHwnd(), LVM_SETEXTENDEDLISTVIEWSTYLE, - 0, LVS_EX_FULLROWSELECT); + 0, LVS_EX_LABELTIP | LVS_EX_FULLROWSELECT); } return true; @@ -1834,7 +1843,7 @@ bool wxListCtrl::MSWOnNotify(int idCtrl, WXLPARAM lParam, WXLPARAM *result) event.m_item.m_data = internaldata->lParam; } - + bool processed = true; switch ( nmhdr->code ) { case LVN_BEGINRDRAG: @@ -2133,6 +2142,82 @@ bool wxListCtrl::MSWOnNotify(int idCtrl, WXLPARAM lParam, WXLPARAM *result) } break; +#if HAVE_NMLVFINDITEM || HAVE_NM_FINDITEM + case LVN_ODFINDITEM: + // this message is only used with the virtual list control but + // even there we don't want to always use it: in a control with + // sufficiently big number of items (defined as > 1000 here), + // accidentally pressing a key could result in hanging an + // application waiting while it performs linear search + if ( IsVirtual() && GetItemCount() <= 1000 ) + { +#if HAVE_NMLVFINDITEM + NMLVFINDITEM* pFindInfo = (NMLVFINDITEM*)lParam; +#else + NM_FINDITEM* pFindInfo = (NM_FINDITEM*)lParam; +#endif + + // no match by default + *result = -1; + + // we only handle string-based searches here + // + // TODO: what about LVFI_PARTIAL, should we handle this? + if ( !(pFindInfo->lvfi.flags & LVFI_STRING) ) + { + return false; + } + + const wxChar * const searchstr = pFindInfo->lvfi.psz; + const size_t len = wxStrlen(searchstr); + + // this is the first item we should examine, search from it + // wrapping if necessary + const int startPos = pFindInfo->iStart; + const int maxPos = GetItemCount(); + wxCHECK_MSG( startPos <= maxPos, false, + _T("bad starting position in LVN_ODFINDITEM") ); + + int currentPos = startPos; + do + { + // wrap to the beginning if necessary + if ( currentPos == maxPos ) + { + // somewhat surprizingly, LVFI_WRAP isn't set in + // flags but we still should wrap + currentPos = 0; + } + + // does this item begin with searchstr? + if ( wxStrnicmp(searchstr, + GetItemText(currentPos), len) == 0 ) + { + *result = currentPos; + break; + } + } + while ( ++currentPos != startPos ); + + if ( *result == -1 ) + { + // not found + return false; + } + + SetItemState(*result, + wxLIST_STATE_SELECTED | wxLIST_STATE_FOCUSED, + wxLIST_STATE_SELECTED | wxLIST_STATE_FOCUSED); + EnsureVisible(*result); + return true; + } + else + { + processed = false; + } + break; +#endif // HAVE_NMLVFINDITEM || HAVE_NM_FINDITEM + case LVN_GETDISPINFO: if ( IsVirtual() ) { @@ -2165,8 +2250,11 @@ bool wxListCtrl::MSWOnNotify(int idCtrl, WXLPARAM lParam, WXLPARAM *result) // fall through default: - return wxControl::MSWOnNotify(idCtrl, lParam, result); + processed = false; } + + if ( !processed ) + return wxControl::MSWOnNotify(idCtrl, lParam, result); } else { @@ -2202,7 +2290,7 @@ bool wxListCtrl::MSWOnNotify(int idCtrl, WXLPARAM lParam, WXLPARAM *result) case LVN_ENDLABELEDITA: case LVN_ENDLABELEDITW: - // logic here is inversed compared to all the other messages + // logic here is inverted compared to all the other messages *result = event.IsAllowed(); // don't keep a stale wxTextCtrl around