]> git.saurik.com Git - wxWidgets.git/blobdiff - src/msw/listctrl.cpp
Mono bitmap processing updates
[wxWidgets.git] / src / msw / listctrl.cpp
index bdab497417cd78cb47a104aee087da37a449075d..c0a29caeac8c49f9153ad6e3c045ca281bff959e 100644 (file)
     #include <commctrl.h>
 #endif
 
-#ifndef LVHT_ONITEM
-    #define LVHT_ONITEM \
-                (LVHT_ONITEMICON | LVHT_ONITEMLABEL | LVHT_ONITEMSTATEICON)
-#endif
-
-#ifndef LVM_SETEXTENDEDLISTVIEWSTYLE
-    #define LVM_SETEXTENDEDLISTVIEWSTYLE (0x1000 + 54)
-#endif
-
-#ifndef LVS_EX_FULLROWSELECT
-    #define LVS_EX_FULLROWSELECT 0x00000020
-#endif
-
-#ifndef LVS_OWNERDATA
-    #define LVS_OWNERDATA 0x1000
-#endif
-
-// mingw32/cygwin don't have declarations for comctl32.dll 4.70+ stuff
-#ifndef NM_CACHEHINT
-    typedef struct tagNMLVCACHEHINT
-    {
-        NMHDR   hdr;
-        int     iFrom;
-        int     iTo;
-    } NMLVCACHEHINT;
-
-    #define NM_CACHEHINT NMLVCACHEHINT
-#endif
-
-#ifndef LVN_ODCACHEHINT
-    #define LVN_ODCACHEHINT (-113)
-#endif
-
-#ifndef ListView_GetHeader
-    #define ListView_GetHeader(w) (HWND)SendMessage((w),LVM_GETHEADER,0,0)
-#endif
-
-#ifndef LVM_GETHEADER
-    #define LVM_GETHEADER (LVM_FIRST+31)
-#endif
-
-#ifndef Header_GetItemRect
-    #define Header_GetItemRect(w,i,r) \
-            (BOOL)SendMessage((w),HDM_GETITEMRECT,(WPARAM)(i),(LPARAM)(r))
-#endif
-
-#ifndef HDM_GETITEMRECT
-    #define HDM_GETITEMRECT (HDM_FIRST+7)
-#endif
-
-#ifndef LVCF_IMAGE
-    #define LVCF_IMAGE             0x0010
-#endif
-
-#ifndef LVCFMT_BITMAP_ON_RIGHT
-    #define LVCFMT_BITMAP_ON_RIGHT 0x1000
-#endif
+#include "wx/msw/missing.h"
 
 // ----------------------------------------------------------------------------
 // private functions
@@ -129,6 +73,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 +275,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 +747,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 +772,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;
@@ -908,6 +910,38 @@ int wxListCtrl::GetItemSpacing(bool isSmall) const
     return ListView_GetItemSpacing(GetHwnd(), (BOOL) isSmall);
 }
 
+void wxListCtrl::SetItemTextColour( long item, const wxColour &col )
+{
+    wxListItem info;
+    info.m_itemId = item;
+    info.SetTextColour( col );
+    SetItem( info );
+}
+
+wxColour wxListCtrl::GetItemTextColour( long item ) const
+{
+    wxListItem info;
+    info.m_itemId = item;
+    GetItem( info );
+    return info.GetTextColour();
+}
+
+void wxListCtrl::SetItemBackgroundColour( long item, const wxColour &col )
+{
+    wxListItem info;
+    info.m_itemId = item;
+    info.SetBackgroundColour( col );
+    SetItem( info );
+}
+
+wxColour wxListCtrl::GetItemBackgroundColour( long item ) const
+{
+    wxListItem info;
+    info.m_itemId = item;
+    GetItem( info );
+    return info.GetBackgroundColour();
+}
+
 // Gets the number of selected items in the list control
 int wxListCtrl::GetSelectedItemCount() const
 {
@@ -1494,7 +1528,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 +1536,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 +1613,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 +1639,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 +1707,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 +1952,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 +2073,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 +2390,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);
@@ -2380,3 +2439,5 @@ static void wxConvertToMSWListCol(int col, const wxListItem& item,
 }
 
 #endif // wxUSE_LISTCTRL
+
+// vi:sts=4:sw=4:et