]> git.saurik.com Git - wxWidgets.git/blobdiff - src/msw/listctrl.cpp
use wxRegEx if available in wxString::Matches
[wxWidgets.git] / src / msw / listctrl.cpp
index 191b98c91a71827c5993e10fb7cdb7399e83c96e..107623555b3fec9692fdacf03d8cab8db682bead 100644 (file)
     #define LVS_EX_FULLROWSELECT 0x00000020
 #endif
 
+#ifndef LVS_OWNERDATA
+    #define LVS_OWNERDATA 0x1000
+#endif
+
 // ----------------------------------------------------------------------------
 // private functions
 // ----------------------------------------------------------------------------
@@ -301,8 +305,8 @@ wxListCtrl::~wxListCtrl()
 
     if ( m_textCtrl )
     {
-        m_textCtrl->UnsubclassWin();
         m_textCtrl->SetHWND(0);
+        m_textCtrl->UnsubclassWin();
         delete m_textCtrl;
         m_textCtrl = NULL;
     }
@@ -452,6 +456,16 @@ long wxListCtrl::ConvertToMSWStyle(long& oldStyle, long style) const
 
     if ( style & wxLC_VIRTUAL )
     {
+        int ver = wxTheApp->GetComCtl32Version();
+        if ( ver < 470 )
+        {
+            wxLogWarning(_("Please install a newer version of comctl32.dll\n"
+                           "(at least version 4.70 is required but you have "
+                           "%d.%02d)\n"
+                           "or this program won't operate correctly."),
+                        ver / 100, ver % 100);
+        }
+
         wstyle |= LVS_OWNERDATA;
     }
 
@@ -1058,8 +1072,8 @@ wxTextCtrl* wxListCtrl::EditLabel(long item, wxClassInfo* textControlClass)
 
     if (m_textCtrl)
     {
-        m_textCtrl->UnsubclassWin();
         m_textCtrl->SetHWND(0);
+        m_textCtrl->UnsubclassWin();
         delete m_textCtrl;
         m_textCtrl = NULL;
     }
@@ -1074,29 +1088,15 @@ wxTextCtrl* wxListCtrl::EditLabel(long item, wxClassInfo* textControlClass)
 // End label editing, optionally cancelling the edit
 bool wxListCtrl::EndEditLabel(bool WXUNUSED(cancel))
 {
-    wxFAIL;
-
-    /* I don't know how to implement this: there's no such macro as ListView_EndEditLabelNow.
-     * ???
-     bool success = (ListView_EndEditLabelNow(GetHwnd(), cancel) != 0);
-
-     if (m_textCtrl)
-     {
-     m_textCtrl->UnsubclassWin();
-     m_textCtrl->SetHWND(0);
-     delete m_textCtrl;
-     m_textCtrl = NULL;
-     }
-     return success;
-     */
+    wxFAIL_MSG( _T("not implemented") );
+
     return FALSE;
 }
 
-
 // Ensures this item is visible
 bool wxListCtrl::EnsureVisible(long item)
 {
-    return (ListView_EnsureVisible(GetHwnd(), (int) item, FALSE) != 0);
+    return ListView_EnsureVisible(GetHwnd(), (int) item, FALSE) != 0;
 }
 
 // Find an item whose label matches this string, starting from the item after 'start'
@@ -1408,6 +1408,7 @@ bool wxListCtrl::MSWOnNotify(int idCtrl, WXLPARAM lParam, WXLPARAM *result)
                 eventType = wxEVT_COMMAND_LIST_BEGIN_LABEL_EDIT;
                 LV_DISPINFO *info = (LV_DISPINFO *)lParam;
                 wxConvertFromMSWListItem(this, event.m_item, info->item, GetHwnd());
+                event.m_itemIndex = event.m_item.m_itemId;
             }
             break;
 
@@ -1442,6 +1443,8 @@ bool wxListCtrl::MSWOnNotify(int idCtrl, WXLPARAM lParam, WXLPARAM *result)
                 wxConvertFromMSWListItem(this, 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;
 
@@ -1495,7 +1498,6 @@ bool wxListCtrl::MSWOnNotify(int idCtrl, WXLPARAM lParam, WXLPARAM *result)
                      !(wxIsShiftDown() || wxIsCtrlDown()) )
                 {
                     eventType = wxEVT_COMMAND_LIST_ITEM_ACTIVATED;
-                    event.m_itemIndex = lItem;
                 }
                 else
                 {
@@ -1503,6 +1505,9 @@ bool wxListCtrl::MSWOnNotify(int idCtrl, WXLPARAM lParam, WXLPARAM *result)
                     event.m_code = wxCharCodeMSWToWX(wVKey);
                 }
 
+                event.m_itemIndex =
+                event.m_item.m_itemId = lItem;
+
                 if ( lItem != -1 )
                 {
                     // fill the other fields too
@@ -1587,85 +1592,9 @@ bool wxListCtrl::MSWOnNotify(int idCtrl, WXLPARAM lParam, WXLPARAM *result)
 
 #if defined(_WIN32_IE) && _WIN32_IE >= 0x300
         case NM_CUSTOMDRAW:
-            {
-                LPNMLVCUSTOMDRAW lplvcd = (LPNMLVCUSTOMDRAW)lParam;
-                NMCUSTOMDRAW& nmcd = lplvcd->nmcd;
-                switch( nmcd.dwDrawStage )
-                {
-                    case CDDS_PREPAINT:
-                        // if we've got any items with non standard attributes,
-                        // notify us before painting each item
-                        *result = m_hasAnyAttr ? CDRF_NOTIFYITEMDRAW
-                                               : CDRF_DODEFAULT;
-                        return TRUE;
-
-                    case CDDS_ITEMPREPAINT:
-                        {
-                            wxListItemAttr *attr =
-                                (wxListItemAttr *)m_attrs.Get(nmcd.dwItemSpec);
-
-                            if ( !attr )
-                            {
-                                // nothing to do for this item
-                                return CDRF_DODEFAULT;
-                            }
-
-                            HFONT hFont;
-                            wxColour colText, colBack;
-                            if ( attr->HasFont() )
-                            {
-                                wxFont font = attr->GetFont();
-                                hFont = (HFONT)font.GetResourceHandle();
-                            }
-                            else
-                            {
-                                hFont = 0;
-                            }
-
-                            if ( attr->HasTextColour() )
-                            {
-                                colText = attr->GetTextColour();
-                            }
-                            else
-                            {
-                                colText = GetTextColour();
-                            }
-
-                            if ( attr->HasBackgroundColour() )
-                            {
-                                colBack = attr->GetBackgroundColour();
-                            }
-                            else
-                            {
-                                colBack = GetBackgroundColour();
-                            }
-
-                            // note that if we wanted to set colours for
-                            // individual columns (subitems), we would have
-                            // returned CDRF_NOTIFYSUBITEMREDRAW from here
-                            if ( hFont )
-                            {
-                                ::SelectObject(nmcd.hdc, hFont);
-
-                                *result = CDRF_NEWFONT;
-                            }
-                            else
-                            {
-                                *result = CDRF_DODEFAULT;
-                            }
-
-                            lplvcd->clrText = wxColourToRGB(colText);
-                            lplvcd->clrTextBk = wxColourToRGB(colBack);
-
-                            return TRUE;
-                        }
-
-                    default:
-                        *result = CDRF_DODEFAULT;
-                        return TRUE;
-                }
-            }
-//            break; // can never be reached
+            *result = OnCustomDraw(lParam);
+
+            return TRUE;
 #endif // _WIN32_IE >= 0x300
 
         case LVN_GETDISPINFO:
@@ -1734,6 +1663,96 @@ bool wxListCtrl::MSWOnNotify(int idCtrl, WXLPARAM lParam, WXLPARAM *result)
     return TRUE;
 }
 
+#if defined(_WIN32_IE) && _WIN32_IE >= 0x300
+
+WXLPARAM wxListCtrl::OnCustomDraw(WXLPARAM lParam)
+{
+    LPNMLVCUSTOMDRAW lplvcd = (LPNMLVCUSTOMDRAW)lParam;
+    NMCUSTOMDRAW& nmcd = lplvcd->nmcd;
+    switch ( nmcd.dwDrawStage )
+    {
+        case CDDS_PREPAINT:
+            // if we've got any items with non standard attributes,
+            // notify us before painting each item
+            //
+            // for virtual controls, always suppose that we have attributes as
+            // there is no way to check for this
+            return IsVirtual() || m_hasAnyAttr ? CDRF_NOTIFYITEMDRAW
+                                               : CDRF_DODEFAULT;
+
+        case CDDS_ITEMPREPAINT:
+            {
+                size_t item = (size_t)nmcd.dwItemSpec;
+                if ( item >= (size_t)GetItemCount() )
+                {
+                    // we get this message with item == 0 for an empty control,
+                    // we must ignore it as calling OnGetItemAttr() would be
+                    // wrong
+                    return CDRF_DODEFAULT;
+                }
+
+                wxListItemAttr *attr =
+                    IsVirtual() ? OnGetItemAttr(item)
+                                : (wxListItemAttr *)m_attrs.Get(item);
+
+                if ( !attr )
+                {
+                    // nothing to do for this item
+                    return CDRF_DODEFAULT;
+                }
+
+                HFONT hFont;
+                wxColour colText, colBack;
+                if ( attr->HasFont() )
+                {
+                    wxFont font = attr->GetFont();
+                    hFont = (HFONT)font.GetResourceHandle();
+                }
+                else
+                {
+                    hFont = 0;
+                }
+
+                if ( attr->HasTextColour() )
+                {
+                    colText = attr->GetTextColour();
+                }
+                else
+                {
+                    colText = GetTextColour();
+                }
+
+                if ( attr->HasBackgroundColour() )
+                {
+                    colBack = attr->GetBackgroundColour();
+                }
+                else
+                {
+                    colBack = GetBackgroundColour();
+                }
+
+                lplvcd->clrText = wxColourToRGB(colText);
+                lplvcd->clrTextBk = wxColourToRGB(colBack);
+
+                // note that if we wanted to set colours for
+                // individual columns (subitems), we would have
+                // returned CDRF_NOTIFYSUBITEMREDRAW from here
+                if ( hFont )
+                {
+                    ::SelectObject(nmcd.hdc, hFont);
+
+                    return CDRF_NEWFONT;
+                }
+            }
+            // fall through to return CDRF_DODEFAULT
+
+        default:
+            return CDRF_DODEFAULT;
+    }
+}
+
+#endif // NM_CUSTOMDRAW supported
+
 // Necessary for drawing hrules and vrules, if specified
 void wxListCtrl::OnPaint(wxPaintEvent& event)
 {
@@ -1820,6 +1839,15 @@ int wxListCtrl::OnGetItemImage(long item) const
     return -1;
 }
 
+wxListItemAttr *wxListCtrl::OnGetItemAttr(long item) const
+{
+    wxASSERT_MSG( item >= 0 && item < GetItemCount(),
+                  _T("invalid item index in OnGetItemAttr()") );
+
+    // no attributes by default
+    return NULL;
+}
+
 void wxListCtrl::SetItemCount(long count)
 {
     wxASSERT_MSG( IsVirtual(), _T("this is for virtual controls only") );
@@ -1830,6 +1858,22 @@ void wxListCtrl::SetItemCount(long count)
     }
 }
 
+void wxListCtrl::RefreshItem(long item)
+{
+    if ( !ListView_Update(GetHwnd(), item) )
+    {
+        wxLogLastError(_T("ListView_Update"));
+    }
+}
+
+void wxListCtrl::RefreshItems(long itemFrom, long itemTo)
+{
+    for ( long item = itemFrom; item <= itemTo; item++ )
+    {
+        RefreshItem(item);
+    }
+}
+
 // ----------------------------------------------------------------------------
 // wxListItem
 // ----------------------------------------------------------------------------