X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/0cf5b09998e7d4606387975a56b6a954a98fd7b7..7d0180d415f3cce126abebed2ef1d0fde00bcc61:/src/msw/listctrl.cpp?ds=sidebyside diff --git a/src/msw/listctrl.cpp b/src/msw/listctrl.cpp index 91284a31d6..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 // ---------------------------------------------------------------------------- @@ -1612,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; @@ -1645,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; @@ -1902,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(); @@ -2339,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);