]> git.saurik.com Git - wxWidgets.git/blobdiff - src/msw/listctrl.cpp
added wxRESERVE_SPACE_EVEN_IF_HIDDEN sizer flag that prevents the sizer from changing...
[wxWidgets.git] / src / msw / listctrl.cpp
index 1ba0251cdf195fb76f1b1c5b3b0307ce33ffcf04..a0d60fea2ea88fbe29aea7642a0939bc4228c016 100644 (file)
@@ -279,7 +279,7 @@ wxEND_HANDLERS_TABLE()
 wxCONSTRUCTOR_5( wxListCtrl , wxWindow* , Parent , wxWindowID , Id , wxPoint , Position , wxSize , Size , long , WindowStyle )
 
 /*
- TODO : Expose more information of a list's layout etc. via appropriate objects (à la NotebookPageInfo)
+ TODO : Expose more information of a list's layout etc. via appropriate objects (a la NotebookPageInfo)
 */
 #else
 IMPLEMENT_DYNAMIC_CLASS(wxListCtrl, wxControl)
@@ -338,14 +338,26 @@ bool wxListCtrl::Create(wxWindow *parent,
     // GetTextColour will always return black
     SetTextColour(GetDefaultAttributes().colFg);
 
+    if ( InReportView() )
+        MSWSetExListStyles();
+
+    return true;
+}
+
+void wxListCtrl::MSWSetExListStyles()
+{
     // 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 )
+    if ( wxApp::GetComCtl32Version() >= 470 )
     {
         ::SendMessage
         (
             GetHwnd(), LVM_SETEXTENDEDLISTVIEWSTYLE, 0,
+            // LVS_EX_LABELTIP shouldn't be used under Windows CE where it's
+            // not defined in the SDK headers
+#ifdef LVS_EX_LABELTIP
             LVS_EX_LABELTIP |
+#endif
             LVS_EX_FULLROWSELECT |
             LVS_EX_SUBITEMIMAGES |
             // normally this should be governed by a style as it's probably not
@@ -354,8 +366,6 @@ bool wxListCtrl::Create(wxWindow *parent,
             LVS_EX_HEADERDRAGDROP
         );
     }
-
-    return true;
 }
 
 WXDWORD wxListCtrl::MSWGetStyle(long style, WXDWORD *exstyle) const
@@ -454,6 +464,11 @@ void wxListCtrl::UpdateStyle()
         if ( dwStyleOld != dwStyleNew )
         {
             ::SetWindowLong(GetHwnd(), GWL_STYLE, dwStyleNew);
+
+            // if we switched to the report view, set the extended styles for
+            // it too
+            if ( !(dwStyleOld & LVS_REPORT) && (dwStyleNew & LVS_REPORT) )
+                MSWSetExListStyles();
         }
     }
 }
@@ -923,14 +938,15 @@ bool wxListCtrl::SetItemState(long item, long state, long stateMask)
 
     wxConvertToMSWFlags(state, stateMask, lvItem);
 
+    const bool changingFocus = (stateMask & wxLIST_STATE_FOCUSED) &&
+                                    (state & wxLIST_STATE_FOCUSED);
+
     // for the virtual list controls we need to refresh the previously focused
     // 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) &&
-         (state & wxLIST_STATE_FOCUSED) )
+    if ( IsVirtual() && changingFocus )
     {
         focusOld = GetNextItem(-1, wxLIST_NEXT_ALL, wxLIST_STATE_FOCUSED);
     }
@@ -958,6 +974,16 @@ bool wxListCtrl::SetItemState(long item, long state, long stateMask)
         }
     }
 
+    // we expect the selection anchor, i.e. the item from which multiple
+    // selection (such as performed with e.g. Shift-arrows) starts, to be the
+    // same as the currently focused item but the native control doesn't update
+    // it when we change focus and leaves at the last item it set itself focus
+    // to, so do it explicitly
+    if ( changingFocus && !HasFlag(wxLC_SINGLE_SEL) )
+    {
+        ListView_SetSelectionMark(GetHwnd(), item);
+    }
+
     return true;
 }
 
@@ -1841,15 +1867,12 @@ bool wxListCtrl::MSWCommand(WXUINT cmd, WXWORD id_)
 // utility used by wxListCtrl::MSWOnNotify and by wxDataViewHeaderWindowMSW::MSWOnNotify
 int WXDLLIMPEXP_CORE wxMSWGetColumnClicked(NMHDR *nmhdr, POINT *ptClick)
 {
-    wxASSERT(nmhdr && ptClick);
-
-    // find the column clicked: we have to search for it
-    // ourselves as the notification message doesn't provide
-    // this info
+    // find the column clicked: we have to search for it ourselves as the
+    // notification message doesn't provide this info
 
     // where did the click occur?
 #if defined(__WXWINCE__) && !defined(__HANDHELDPC__) && _WIN32_WCE < 400
-    if (nmhdr->code == GN_CONTEXTMENU)
+    if ( nmhdr->code == GN_CONTEXTMENU )
     {
         *ptClick = ((NMRGINFO*)nmhdr)->ptAction;
     }
@@ -1860,19 +1883,27 @@ int WXDLLIMPEXP_CORE wxMSWGetColumnClicked(NMHDR *nmhdr, POINT *ptClick)
         wxLogLastError(_T("GetCursorPos"));
     }
 
-    if ( !::ScreenToClient(nmhdr->hwndFrom, ptClick) )
+    // we need to use listctrl coordinates for the event point so this is what
+    // we return in ptClick, but for comparison with Header_GetItemRect()
+    // result below we need to use header window coordinates
+    POINT ptClickHeader = *ptClick;
+    if ( !::ScreenToClient(nmhdr->hwndFrom, &ptClickHeader) )
     {
-        wxLogLastError(_T("ScreenToClient(header)"));
+        wxLogLastError(_T("ScreenToClient(listctrl header)"));
     }
 
-    int colCount = Header_GetItemCount(nmhdr->hwndFrom);
+    if ( !::ScreenToClient(::GetParent(nmhdr->hwndFrom), ptClick) )
+    {
+        wxLogLastError(_T("ScreenToClient(listctrl)"));
+    }
 
-    RECT rect;
+    const int colCount = Header_GetItemCount(nmhdr->hwndFrom);
     for ( int col = 0; col < colCount; col++ )
     {
+        RECT rect;
         if ( Header_GetItemRect(nmhdr->hwndFrom, col, &rect) )
         {
-            if ( ::PtInRect(&rect, *ptClick) )
+            if ( ::PtInRect(&rect, ptClickHeader) )
             {
                 return col;
             }