X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/2d33aec94c9217b94ada107fbd125db4c51c22ab..6d9022fe3bb50a75b9b5eaf5cf32558e518ba310:/src/msw/listctrl.cpp diff --git a/src/msw/listctrl.cpp b/src/msw/listctrl.cpp index bdab497417..e95f417a95 100644 --- a/src/msw/listctrl.cpp +++ b/src/msw/listctrl.cpp @@ -68,6 +68,14 @@ #define LVS_OWNERDATA 0x1000 #endif +#ifndef LVM_FIRST + #define LVM_FIRST 0x1000 +#endif + +#ifndef HDM_FIRST + #define HDM_FIRST 0x1200 +#endif + // mingw32/cygwin don't have declarations for comctl32.dll 4.70+ stuff #ifndef NM_CACHEHINT typedef struct tagNMLVCACHEHINT @@ -109,6 +117,44 @@ #define LVCFMT_BITMAP_ON_RIGHT 0x1000 #endif +#if defined(__GNUWIN32__) && !defined(LV_ITEM) \ + && !wxCHECK_W32API_VERSION( 0, 5 ) +typedef struct _LVITEMW { + UINT mask; + int iItem; + int iSubItem; + UINT state; + UINT stateMask; + LPWSTR pszText; + int cchTextMax; + int iImage; + LPARAM lParam; +#if (_WIN32_IE >= 0x0300) + int iIndent; +#endif +} LV_ITEMW; +typedef LV_ITEM LV_ITEMA; +#endif + +#if defined(__GNUWIN32__) && !wxCHECK_W32API_VERSION( 0, 5 ) +#ifndef LV_DISPINFOA +typedef struct tagNMLVDISPINFOA { + NMHDR hdr; + LV_ITEMA item; +} NMLVDISPINFOA, FAR *LPNMLVDISPINFOA; +#define _LV_DISPINFOA tagNMLVDISPINFOA +#define LV_DISPINFOA NMLVDISPINFOA +#endif +#ifndef LV_DISPINFOW +typedef struct tagNMLVDISPINFOW { + NMHDR hdr; + LV_ITEMW item; +} NMLVDISPINFOW, FAR *LPNMLVDISPINFOW; +#define _LV_DISPINFOW tagNMLVDISPINFOW +#define LV_DISPINFOW NMLVDISPINFOW +#endif +#endif + // ---------------------------------------------------------------------------- // private functions // ---------------------------------------------------------------------------- @@ -129,6 +175,57 @@ static void wxConvertFromMSWListItem(HWND hwndListCtrl, static void wxConvertToMSWListCol(int col, const wxListItem& item, LV_COLUMN& lvCol); +// ---------------------------------------------------------------------------- +// private helper classes +// ---------------------------------------------------------------------------- + +// We have to handle both fooW and fooA notifications in several cases +// because of broken commctl.dll and/or unicows.dll. This class is used to +// convert LV_ITEMA and LV_ITEMW to LV_ITEM (which is either LV_ITEMA or +// LV_ITEMW depending on wxUSE_UNICODE setting), so that it can be processed +// by wxConvertToMSWListItem(). +class wxLV_ITEM +{ +public: + ~wxLV_ITEM() { delete m_buf; } + operator LV_ITEM&() const { return *m_item; } + +#if wxUSE_UNICODE + wxLV_ITEM(LV_ITEMW &item) : m_buf(NULL), m_item(&item) {} + wxLV_ITEM(LV_ITEMA &item) + { + m_item = new LV_ITEM((LV_ITEM&)item); + if ( (item.mask & LVIF_TEXT) && item.pszText ) + { + m_buf = new wxMB2WXbuf(wxConvLocal.cMB2WX(item.pszText)); + m_item->pszText = (wxChar*)m_buf->data(); + } + else + m_buf = NULL; + } +private: + wxMB2WXbuf *m_buf; + +#else + wxLV_ITEM(LV_ITEMW &item) + { + m_item = new LV_ITEM((LV_ITEM&)item); + if ( (item.mask & LVIF_TEXT) && item.pszText ) + { + m_buf = new wxWC2WXbuf(wxConvLocal.cWC2WX(item.pszText)); + m_item->pszText = (wxChar*)m_buf->data(); + } + else + m_buf = NULL; + } + wxLV_ITEM(LV_ITEMA &item) : m_buf(NULL), m_item(&item) {} +private: + wxWC2WXbuf *m_buf; +#endif + + LV_ITEM *m_item; +}; + // ---------------------------------------------------------------------------- // events // ---------------------------------------------------------------------------- @@ -280,7 +377,7 @@ bool wxListCtrl::DoCreateControl(int x, int y, int w, int h) 0, LVS_EX_FULLROWSELECT); } - SetBackgroundColour(wxSystemSettings::GetSystemColour(wxSYS_COLOUR_WINDOW)); + SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW)); SetForegroundColour(GetParent()->GetForegroundColour()); SubclassWin(m_hWnd); @@ -752,8 +849,9 @@ bool wxListCtrl::SetItemState(long item, long state, long stateMask) wxConvertToMSWFlags(state, stateMask, lvItem); // for the virtual list controls we need to refresh the previously focused - // item manually when changing focus programmatically because otherwise it - // keeps its focus rectangle until next repaint (yet another comctl32 bug) + // item manually when changing focus without changing selection + // programmatically because otherwise it keeps its focus rectangle until + // next repaint (yet another comctl32 bug) long focusOld; if ( IsVirtual() && (stateMask & wxLIST_STATE_FOCUSED) && @@ -776,7 +874,13 @@ bool wxListCtrl::SetItemState(long item, long state, long stateMask) if ( focusOld != -1 ) { - RefreshItem(focusOld); + // no need to refresh the item if it was previously selected, it would + // only result in annoying flicker + if ( !(GetItemState(focusOld, + wxLIST_STATE_SELECTED) & wxLIST_STATE_SELECTED) ) + { + RefreshItem(focusOld); + } } return TRUE; @@ -1494,7 +1598,7 @@ bool wxListCtrl::MSWOnNotify(int idCtrl, WXLPARAM lParam, WXLPARAM *result) // if your compiler is as broken as this, you should really change it: this // code is needed for normal operation! #ifdef below is only useful for // automatic rebuilds which are done with a very old compiler version -#ifdef LVM_FIRST +#ifdef HDN_BEGINTRACKA // check for messages from the header (in report view) HWND hwndHdr = ListView_GetHeader(GetHwnd()); @@ -1502,7 +1606,8 @@ bool wxListCtrl::MSWOnNotify(int idCtrl, WXLPARAM lParam, WXLPARAM *result) // is it a message from the header? if ( nmhdr->hwndFrom == hwndHdr ) { - NMHEADER *nmHDR = (NMHEADER *)nmhdr; + HD_NOTIFY *nmHDR = (HD_NOTIFY *)nmhdr; + event.m_itemIndex = -1; switch ( nmhdr->code ) @@ -1578,7 +1683,7 @@ bool wxListCtrl::MSWOnNotify(int idCtrl, WXLPARAM lParam, WXLPARAM *result) } } else -#endif // defined(LVM_FIRST) +#endif // defined(HDN_BEGINTRACKA) if ( nmhdr->hwndFrom == GetHwnd() ) { // almost all messages use NM_LISTVIEW @@ -1604,11 +1709,46 @@ bool wxListCtrl::MSWOnNotify(int idCtrl, WXLPARAM lParam, WXLPARAM *result) event.m_pointDrag.y = nmLV->ptAction.y; break; - case LVN_BEGINLABELEDIT: + // NB: we have to handle both *A and *W versions here because some + // versions of comctl32.dll send ANSI message to an Unicode app + case LVN_BEGINLABELEDITA: { eventType = wxEVT_COMMAND_LIST_BEGIN_LABEL_EDIT; - LV_DISPINFO *info = (LV_DISPINFO *)lParam; - wxConvertFromMSWListItem(GetHwnd(), event.m_item, info->item); + wxLV_ITEM item(((LV_DISPINFOA *)lParam)->item); + wxConvertFromMSWListItem(GetHwnd(), event.m_item, item); + event.m_itemIndex = event.m_item.m_itemId; + } + break; + case LVN_BEGINLABELEDITW: + { + eventType = wxEVT_COMMAND_LIST_BEGIN_LABEL_EDIT; + wxLV_ITEM item(((LV_DISPINFOW *)lParam)->item); + wxConvertFromMSWListItem(GetHwnd(), event.m_item, item); + event.m_itemIndex = event.m_item.m_itemId; + } + break; + + case LVN_ENDLABELEDITA: + { + eventType = wxEVT_COMMAND_LIST_END_LABEL_EDIT; + wxLV_ITEM item(((LV_DISPINFOA *)lParam)->item); + wxConvertFromMSWListItem(NULL, event.m_item, item); + if ( ((LV_ITEM)item).pszText == NULL || + ((LV_ITEM)item).iItem == -1 ) + return FALSE; + + event.m_itemIndex = event.m_item.m_itemId; + } + break; + case LVN_ENDLABELEDITW: + { + eventType = wxEVT_COMMAND_LIST_END_LABEL_EDIT; + wxLV_ITEM item(((LV_DISPINFOW *)lParam)->item); + wxConvertFromMSWListItem(NULL, event.m_item, item); + if ( ((LV_ITEM)item).pszText == NULL || + ((LV_ITEM)item).iItem == -1 ) + return FALSE; + event.m_itemIndex = event.m_item.m_itemId; } break; @@ -1637,18 +1777,6 @@ bool wxListCtrl::MSWOnNotify(int idCtrl, WXLPARAM lParam, WXLPARAM *result) } break; - case LVN_ENDLABELEDIT: - { - eventType = wxEVT_COMMAND_LIST_END_LABEL_EDIT; - LV_DISPINFO *info = (LV_DISPINFO *)lParam; - wxConvertFromMSWListItem(NULL, event.m_item, info->item); - if ( info->item.pszText == NULL || info->item.iItem == -1 ) - return FALSE; - - event.m_itemIndex = event.m_item.m_itemId; - } - break; - case LVN_SETDISPINFO: { eventType = wxEVT_COMMAND_LIST_SET_INFO; @@ -1894,7 +2022,8 @@ bool wxListCtrl::MSWOnNotify(int idCtrl, WXLPARAM lParam, WXLPARAM *result) return TRUE; - case LVN_ENDLABELEDIT: + case LVN_ENDLABELEDITA: + case LVN_ENDLABELEDITW: // logic here is inversed compared to all the other messages *result = event.IsAllowed(); @@ -2014,7 +2143,7 @@ void wxListCtrl::OnPaint(wxPaintEvent& event) if ((GetWindowStyle() & wxLC_REPORT) == 0) return; - wxPen pen(wxSystemSettings::GetSystemColour(wxSYS_COLOUR_3DLIGHT), 1, wxSOLID); + wxPen pen(wxSystemSettings::GetColour(wxSYS_COLOUR_3DLIGHT), 1, wxSOLID); dc.SetPen(pen); dc.SetBrush(* wxTRANSPARENT_BRUSH); @@ -2331,7 +2460,7 @@ static void wxConvertToMSWListItem(const wxListCtrl *ctrl, lvItem.mask |= LVIF_PARAM; } -static void wxConvertToMSWListCol(int col, const wxListItem& item, +static void wxConvertToMSWListCol(int WXUNUSED(col), const wxListItem& item, LV_COLUMN& lvCol) { wxZeroMemory(lvCol);