X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/40ff126ac4ff57ab4aa22a5c7c7ce621479e8739..0a95d3369e08206a43032472418693f7726591e5:/src/msw/listctrl.cpp diff --git a/src/msw/listctrl.cpp b/src/msw/listctrl.cpp index 64051935b0..6f3a70e136 100644 --- a/src/msw/listctrl.cpp +++ b/src/msw/listctrl.cpp @@ -2,7 +2,7 @@ // Name: src/msw/listctrl.cpp // Purpose: wxListCtrl // Author: Julian Smart -// Modified by: +// Modified by: Agron Selimaj // Created: 04/01/98 // RCS-ID: $Id$ // Copyright: (c) Julian Smart @@ -26,17 +26,19 @@ #if wxUSE_LISTCTRL +#include "wx/listctrl.h" + #ifndef WX_PRECOMP + #include "wx/msw/wrapcctl.h" // include "properly" #include "wx/app.h" #include "wx/intl.h" #include "wx/log.h" #include "wx/settings.h" + #include "wx/dcclient.h" + #include "wx/textctrl.h" #endif -#include "wx/textctrl.h" #include "wx/imaglist.h" -#include "wx/listctrl.h" -#include "wx/dcclient.h" #include "wx/msw/private.h" @@ -48,9 +50,6 @@ #endif #endif -// 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. // @@ -218,35 +217,6 @@ static wxListItemAttr *wxGetInternalDataAttr(const wxListCtrl *ctl, long itemId) static void wxDeleteInternalData(wxListCtrl* ctl, long itemId); -// ---------------------------------------------------------------------------- -// events -// ---------------------------------------------------------------------------- - -DEFINE_EVENT_TYPE(wxEVT_COMMAND_LIST_BEGIN_DRAG) -DEFINE_EVENT_TYPE(wxEVT_COMMAND_LIST_BEGIN_RDRAG) -DEFINE_EVENT_TYPE(wxEVT_COMMAND_LIST_BEGIN_LABEL_EDIT) -DEFINE_EVENT_TYPE(wxEVT_COMMAND_LIST_END_LABEL_EDIT) -DEFINE_EVENT_TYPE(wxEVT_COMMAND_LIST_DELETE_ITEM) -DEFINE_EVENT_TYPE(wxEVT_COMMAND_LIST_DELETE_ALL_ITEMS) -#if WXWIN_COMPATIBILITY_2_4 -DEFINE_EVENT_TYPE(wxEVT_COMMAND_LIST_GET_INFO) -DEFINE_EVENT_TYPE(wxEVT_COMMAND_LIST_SET_INFO) -#endif -DEFINE_EVENT_TYPE(wxEVT_COMMAND_LIST_ITEM_SELECTED) -DEFINE_EVENT_TYPE(wxEVT_COMMAND_LIST_ITEM_DESELECTED) -DEFINE_EVENT_TYPE(wxEVT_COMMAND_LIST_KEY_DOWN) -DEFINE_EVENT_TYPE(wxEVT_COMMAND_LIST_INSERT_ITEM) -DEFINE_EVENT_TYPE(wxEVT_COMMAND_LIST_COL_CLICK) -DEFINE_EVENT_TYPE(wxEVT_COMMAND_LIST_COL_RIGHT_CLICK) -DEFINE_EVENT_TYPE(wxEVT_COMMAND_LIST_COL_BEGIN_DRAG) -DEFINE_EVENT_TYPE(wxEVT_COMMAND_LIST_COL_DRAGGING) -DEFINE_EVENT_TYPE(wxEVT_COMMAND_LIST_COL_END_DRAG) -DEFINE_EVENT_TYPE(wxEVT_COMMAND_LIST_ITEM_RIGHT_CLICK) -DEFINE_EVENT_TYPE(wxEVT_COMMAND_LIST_ITEM_MIDDLE_CLICK) -DEFINE_EVENT_TYPE(wxEVT_COMMAND_LIST_ITEM_ACTIVATED) -DEFINE_EVENT_TYPE(wxEVT_COMMAND_LIST_ITEM_FOCUSED) -DEFINE_EVENT_TYPE(wxEVT_COMMAND_LIST_CACHE_HINT) - #if wxUSE_EXTENDED_RTTI WX_DEFINE_FLAGS( wxListCtrlStyle ) @@ -761,6 +731,10 @@ bool wxListCtrl::GetItem(wxListItem& info) const // Sets information about the item bool wxListCtrl::SetItem(wxListItem& info) { + const long id = info.GetId(); + wxCHECK_MSG( id >= 0 && id < GetItemCount(), false, + _T("invalid item index in SetItem") ); + LV_ITEM item; wxConvertToMSWListItem(this, info, item); @@ -773,7 +747,7 @@ bool wxListCtrl::SetItem(wxListItem& info) { // get internal item data // perhaps a cache here ? - wxListItemInternalData *data = wxGetInternalData(this, info.m_itemId); + wxListItemInternalData *data = wxGetInternalData(this, id); if (! data) { @@ -1006,6 +980,24 @@ wxRect wxListCtrl::GetViewRect() const // Gets the item rectangle bool wxListCtrl::GetItemRect(long item, wxRect& rect, int code) const +{ + return GetSubItemRect( item, wxLIST_GETSUBITEMRECT_WHOLEITEM, rect, code) ; +} + +/*! + * Retrieve coordinates and size of a specified subitem of a listview control. + * This function only works if the listview control is in the report mode. + * + * @param item : Item number + * @param subItem : Subitem or column number, use -1 for the whole row including + * all columns or subitems + * @param rect : A pointer to an allocated wxRect object + * @param code : Specify the part of the subitem coordinates you need. Choices are + * wxLIST_RECT_BOUNDS, wxLIST_RECT_ICON, wxLIST_RECT_LABEL + * + * @return bool : True if successful. + */ +bool wxListCtrl::GetSubItemRect(long item, long subItem, wxRect& rect, int code) const { RECT rectWin; @@ -1018,12 +1010,24 @@ bool wxListCtrl::GetItemRect(long item, wxRect& rect, int code) const codeWin = LVIR_LABEL; else { - wxFAIL_MSG( _T("incorrect code in GetItemRect()") ); - + wxFAIL_MSG( _T("incorrect code in GetItemRect() / GetSubItemRect()") ); codeWin = LVIR_BOUNDS; } - bool success = ListView_GetItemRect(GetHwnd(), (int) item, &rectWin, codeWin) != 0; + bool success; + if( subItem == wxLIST_GETSUBITEMRECT_WHOLEITEM) + { + success = ListView_GetItemRect(GetHwnd(), (int) item, &rectWin, codeWin) != 0; + } + else if( subItem >= 0) + { + success = ListView_GetSubItemRect( GetHwnd(), (int) item, (int) subItem, codeWin, &rectWin) != 0; + } + else + { + wxFAIL_MSG( _T("incorrect subItem number in GetSubItemRect()") ); + return false; + } rect.x = rectWin.left; rect.y = rectWin.top; @@ -1033,6 +1037,9 @@ bool wxListCtrl::GetItemRect(long item, wxRect& rect, int code) const return success; } + + + // Gets the item position bool wxListCtrl::GetItemPosition(long item, wxPoint& pos) const { @@ -1387,21 +1394,19 @@ bool wxListCtrl::EndEditLabel(bool cancel) { // m_textCtrl is not always ready, ie. in EVT_LIST_BEGIN_LABEL_EDIT HWND hwnd = ListView_GetEditControl(GetHwnd()); - bool b = (hwnd != NULL); - if (b) - { - if (cancel) - ::SetWindowText(hwnd, wxEmptyString); // dubious but better than nothing - if (m_textCtrl) - { - m_textCtrl->UnsubclassWin(); - m_textCtrl->SetHWND(0); - delete m_textCtrl; - m_textCtrl = NULL; - } - ::DestroyWindow(hwnd); - } - return b; + 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); + + return true; } // Ensures this item is visible @@ -1474,13 +1479,25 @@ long wxListCtrl::FindItem(long start, const wxPoint& pt, int direction) // Determines which item (if any) is at the specified point, // giving details in 'flags' (see wxLIST_HITTEST_... flags above) -long wxListCtrl::HitTest(const wxPoint& point, int& flags) +long +wxListCtrl::HitTest(const wxPoint& point, int& flags, long *ptrSubItem) const { LV_HITTESTINFO hitTestInfo; hitTestInfo.pt.x = (int) point.x; hitTestInfo.pt.y = (int) point.y; - ListView_HitTest(GetHwnd(), & hitTestInfo); + long item; +#ifdef LVM_SUBITEMHITTEST + if ( ptrSubItem && wxApp::GetComCtl32Version() >= 470 ) + { + item = ListView_SubItemHitTest(GetHwnd(), &hitTestInfo); + *ptrSubItem = hitTestInfo.iSubItem; + } + else +#endif // LVM_SUBITEMHITTEST + { + item = ListView_HitTest(GetHwnd(), &hitTestInfo); + } flags = 0; @@ -1515,9 +1532,10 @@ long wxListCtrl::HitTest(const wxPoint& point, int& flags) flags |= wxLIST_HITTEST_ONITEMSTATEICON; } - return (long) hitTestInfo.iItem; + return item; } + // Inserts an item, returning the index of the new item if successful, // -1 otherwise. long wxListCtrl::InsertItem(const wxListItem& info) @@ -1713,6 +1731,20 @@ bool wxListCtrl::SortItems(wxListCtrlCompare fn, long data) // message processing // ---------------------------------------------------------------------------- +bool wxListCtrl::MSWShouldPreProcessMessage(WXMSG* msg) +{ + if ( msg->message == WM_KEYDOWN ) + { + if ( msg->wParam == VK_RETURN ) + { + // we need VK_RETURN to generate wxEVT_COMMAND_LIST_ITEM_ACTIVATED + return false; + } + } + + return wxControl::MSWShouldPreProcessMessage(msg); +} + bool wxListCtrl::MSWCommand(WXUINT cmd, WXWORD id) { if (cmd == EN_UPDATE) @@ -1861,7 +1893,7 @@ bool wxListCtrl::MSWOnNotify(int idCtrl, WXLPARAM lParam, WXLPARAM *result) } else #endif // defined(HDN_BEGINTRACKA) - if ( nmhdr->hwndFrom == GetHwnd() ) + if ( nmhdr->hwndFrom == GetHwnd() ) { // almost all messages use NM_LISTVIEW NM_LISTVIEW *nmLV = (NM_LISTVIEW *)nmhdr; @@ -2284,10 +2316,13 @@ bool wxListCtrl::MSWOnNotify(int idCtrl, WXLPARAM lParam, WXLPARAM *result) } #endif // NM_CUSTOMDRAW - // a little dose of healthy paranoia: as we never use - // LVM_SETCALLBACKMASK we're not supposed to get these ones - wxASSERT_MSG( !(lvi.mask & LVIF_STATE), - _T("we don't support state callbacks yet!") ); + // even though we never use LVM_SETCALLBACKMASK, we still + // can get messages with LVIF_STATE in lvi.mask under Vista + if ( lvi.mask & LVIF_STATE ) + { + // we don't have anything to return from here... + lvi.stateMask = 0; + } return true; } @@ -3053,7 +3088,7 @@ static void wxConvertToMSWListCol(HWND hwndList, #ifdef NM_CUSTOMDRAW // _WIN32_IE >= 0x0300 if ( item.m_mask & wxLIST_MASK_IMAGE ) { - if ( wxTheApp->GetComCtl32Version() >= 470 ) + if ( wxApp::GetComCtl32Version() >= 470 ) { lvCol.mask |= LVCF_IMAGE;