X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/040b9528d149c2bb2497d47d9175635c03baffe2..713129f9d34e3027d2be46b134d2f4c490ad145f:/src/msw/headerctrl.cpp diff --git a/src/msw/headerctrl.cpp b/src/msw/headerctrl.cpp index ef512e0e74..4983a1dcf4 100644 --- a/src/msw/headerctrl.cpp +++ b/src/msw/headerctrl.cpp @@ -23,7 +23,10 @@ #pragma hdrstop #endif +#if wxUSE_HEADERCTRL + #ifndef WX_PRECOMP + #include "wx/app.h" #include "wx/log.h" #endif // WX_PRECOMP @@ -36,6 +39,15 @@ #include "wx/msw/wrapcctl.h" #include "wx/msw/private.h" +#ifndef HDM_SETBITMAPMARGIN + #define HDM_SETBITMAPMARGIN 0x1234 +#endif + +#ifndef Header_SetBitmapMargin + #define Header_SetBitmapMargin(hwnd, margin) \ + ::SendMessage((hwnd), HDM_SETBITMAPMARGIN, (WPARAM)(margin), 0) +#endif + // from src/msw/listctrl.cpp extern int WXDLLIMPEXP_CORE wxMSWGetColumnClicked(NMHDR *nmhdr, POINT *ptClick); @@ -68,9 +80,19 @@ bool wxHeaderCtrl::Create(wxWindow *parent, if ( !CreateControl(parent, id, pos, size, style, wxDefaultValidator, name) ) return false; - if ( !MSWCreateControl(WC_HEADER, _T(""), pos, size) ) + if ( !MSWCreateControl(WC_HEADER, wxT(""), pos, size) ) return false; + // special hack for margins when using comctl32.dll v6 or later: the + // default margin is too big and results in label truncation when the + // column width is just about right to show it together with the sort + // indicator, so reduce it to a smaller value (in principle we could even + // use 0 here but this starts to look ugly) + if ( wxApp::GetComCtl32Version() >= 600 ) + { + Header_SetBitmapMargin(GetHwnd(), ::GetSystemMetrics(SM_CXEDGE)); + } + return true; } @@ -78,13 +100,15 @@ WXDWORD wxHeaderCtrl::MSWGetStyle(long style, WXDWORD *exstyle) const { WXDWORD msStyle = wxControl::MSWGetStyle(style, exstyle); - if ( style & wxHD_DRAGDROP ) + if ( style & wxHD_ALLOW_REORDER ) msStyle |= HDS_DRAGDROP; // the control looks nicer with these styles and there doesn't seem to be // any reason to not use them so we always do (as for HDS_HORZ it is 0 // anyhow but include it for clarity) - msStyle |= HDS_HORZ | HDS_BUTTONS | HDS_FLAT | HDS_FULLDRAG | HDS_HOTTRACK; + // NOTE: don't use however HDS_FLAT because it makes the control look + // non-native when running WinXP in classic mode + msStyle |= HDS_HORZ | HDS_BUTTONS | HDS_FULLDRAG | HDS_HOTTRACK; return msStyle; } @@ -132,7 +156,7 @@ wxSize wxHeaderCtrl::DoGetBestSize() const HDLAYOUT layout = { &rc, &wpos }; if ( !Header_Layout(GetHwnd(), &layout) ) { - wxLogLastError(_T("Header_Layout")); + wxLogLastError(wxT("Header_Layout")); return wxControl::DoGetBestSize(); } @@ -172,7 +196,7 @@ void wxHeaderCtrl::DoSetCount(unsigned int count) { if ( !Header_DeleteItem(GetHwnd(), 0) ) { - wxLogLastError(_T("Header_DeleteItem")); + wxLogLastError(wxT("Header_DeleteItem")); } } @@ -261,6 +285,7 @@ void wxHeaderCtrl::DoInsertItem(const wxHeaderColumn& col, unsigned int idx) if ( !m_imageList ) { m_imageList = new wxImageList(bmpWidth, bmpHeight); + (void) // suppress mingw32 warning about unused computed value Header_SetImageList(GetHwnd(), GetHimagelistOf(m_imageList)); } else // already have an image list @@ -285,7 +310,7 @@ void wxHeaderCtrl::DoInsertItem(const wxHeaderColumn& col, unsigned int idx) if ( col.GetAlignment() != wxALIGN_NOT ) { - hdi.mask |= HDI_FORMAT; + hdi.mask |= HDI_FORMAT | HDF_LEFT; switch ( col.GetAlignment() ) { case wxALIGN_LEFT: @@ -319,12 +344,12 @@ void wxHeaderCtrl::DoInsertItem(const wxHeaderColumn& col, unsigned int idx) } hdi.mask |= HDI_ORDER; - hdi.iOrder = m_colIndices.Index(idx); + hdi.iOrder = MSWToNativeOrder(m_colIndices.Index(idx)); if ( ::SendMessage(GetHwnd(), HDM_INSERTITEM, MSWToNativeIdx(idx), (LPARAM)&hdi) == -1 ) { - wxLogLastError(_T("Header_InsertItem()")); + wxLogLastError(wxT("Header_InsertItem()")); } } @@ -342,7 +367,7 @@ void wxHeaderCtrl::DoSetColumnsOrder(const wxArrayInt& order) if ( !Header_SetOrderArray(GetHwnd(), orderShown.size(), &orderShown[0]) ) { - wxLogLastError(_T("Header_GetOrderArray")); + wxLogLastError(wxT("Header_GetOrderArray")); } m_colIndices = order; @@ -356,6 +381,10 @@ wxArrayInt wxHeaderCtrl::DoGetColumnsOrder() const return m_colIndices; } +// ---------------------------------------------------------------------------- +// wxHeaderCtrl indexes and positions translation +// ---------------------------------------------------------------------------- + int wxHeaderCtrl::MSWToNativeIdx(int idx) { // don't check for GetColumn(idx).IsShown() as it could have just became @@ -364,13 +393,16 @@ int wxHeaderCtrl::MSWToNativeIdx(int idx) "column must be visible to have an " "index in the native control" ); + int item = idx; for ( int i = 0; i < idx; i++ ) { if ( GetColumn(i).IsHidden() ) - idx--; // one less column the native control knows about + item--; // one less column the native control knows about } - return idx; + wxASSERT_MSG( item >= 0 && item <= GetShownColumnsCount(), "logic error" ); + + return item; } int wxHeaderCtrl::MSWFromNativeIdx(int item) @@ -379,37 +411,59 @@ int wxHeaderCtrl::MSWFromNativeIdx(int item) "column index out of range" ); // reverse the above function - for ( int i = 0; i <= item; i++ ) + + unsigned idx = item; + for ( unsigned n = 0; n < m_numColumns; n++ ) { - if ( GetColumn(i).IsHidden() ) - item++; + if ( n > idx ) + break; + + if ( GetColumn(n).IsHidden() ) + idx++; } - return item; + wxASSERT_MSG( MSWToNativeIdx(idx) == item, "logic error" ); + + return idx; } -int wxHeaderCtrl::MSWFromNativeOrder(int order) +int wxHeaderCtrl::MSWToNativeOrder(int pos) { - wxASSERT_MSG( order >= 0 && order < GetShownColumnsCount(), + wxASSERT_MSG( pos >= 0 && static_cast(pos) < m_numColumns, "column position out of range" ); - // notice that the loop condition is inclusive because if the column - // exactly at position order is hidden we should go to the next one - for ( int pos = 0; pos <= order; pos++ ) + int order = pos; + for ( int n = 0; n < pos; n++ ) { - if ( GetColumn(m_colIndices[pos]).IsHidden() ) - { - // order can't become greater than m_numColumns here because it is - // less than the number of shown columns initially and it is going - // to be incremented at most once for every hidden column and - // m_numColumns is the total columns number - order++; - } + if ( GetColumn(m_colIndices[n]).IsHidden() ) + order--; } + wxASSERT_MSG( order >= 0 && order <= GetShownColumnsCount(), "logic error" ); + return order; } +int wxHeaderCtrl::MSWFromNativeOrder(int order) +{ + wxASSERT_MSG( order >= 0 && order < GetShownColumnsCount(), + "native column position out of range" ); + + unsigned pos = order; + for ( unsigned n = 0; n < m_numColumns; n++ ) + { + if ( n > pos ) + break; + + if ( GetColumn(m_colIndices[n]).IsHidden() ) + pos++; + } + + wxASSERT_MSG( MSWToNativeOrder(pos) == order, "logic error" ); + + return pos; +} + // ---------------------------------------------------------------------------- // wxHeaderCtrl events // ---------------------------------------------------------------------------- @@ -484,7 +538,12 @@ bool wxHeaderCtrl::MSWOnNotify(int idCtrl, WXLPARAM lParam, WXLPARAM *result) if ( idx != wxNOT_FOUND ) { idx = MSWFromNativeIdx(idx); - evtType = GetClickEventType(code == NM_RDBLCLK, 1); + + // due to a bug in mingw32 headers NM_RDBLCLK is signed + // there so we need a cast to avoid warnings about signed/ + // unsigned comparison + evtType = GetClickEventType( + code == static_cast(NM_RDBLCLK), 1); } //else: ignore clicks outside any column } @@ -631,3 +690,5 @@ bool wxHeaderCtrl::MSWOnNotify(int idCtrl, WXLPARAM lParam, WXLPARAM *result) } #endif // wxHAS_GENERIC_HEADERCTRL + +#endif // wxUSE_HEADERCTRL