]> cygwin.com Git - cygwin-apps/setup.git/commitdiff
Custom draw checkboxes in ListView control
authorJon Turney <jon.turney@dronecode.org.uk>
Wed, 7 Dec 2016 16:17:12 +0000 (16:17 +0000)
committerJon Turney <jon.turney@dronecode.org.uk>
Sat, 13 Oct 2018 17:03:32 +0000 (18:03 +0100)
Future work: What does this look like when a theme is in used? Does the row
size need to be slightly adjusted to ensure it accomodates checkbox height?

v2:
erase to background colour before drawing checkbox

ListView.cc
ListView.h
choose.cc

index 97ee44ca57d71f8e059c2627746ccf9fbdc17282..e3f1e44ef0fd86a6e96110044eabf36160de8af4 100644 (file)
@@ -289,6 +289,69 @@ ListView::OnNotify (NMHDR *pNmHdr, LRESULT *pResult)
       return true;
     }
     break;
+
+  case NM_CUSTOMDRAW:
+    {
+      NMLVCUSTOMDRAW *pNmLvCustomDraw = (NMLVCUSTOMDRAW *)pNmHdr;
+
+      switch(pNmLvCustomDraw->nmcd.dwDrawStage)
+        {
+        case CDDS_PREPAINT:
+          *pResult = CDRF_NOTIFYITEMDRAW;
+          return true;
+        case CDDS_ITEMPREPAINT:
+          *pResult = CDRF_NOTIFYSUBITEMDRAW;
+          return true;
+        case CDDS_SUBITEM | CDDS_ITEMPREPAINT:
+          {
+            LRESULT result = CDRF_DODEFAULT;
+            int iCol = pNmLvCustomDraw->iSubItem;
+            int iRow = pNmLvCustomDraw->nmcd.dwItemSpec;
+
+            switch (headers[iCol].type)
+              {
+              default:
+              case ListView::ControlType::text:
+                result = CDRF_DODEFAULT;
+                break;
+
+              case ListView::ControlType::checkbox:
+                {
+                  // get the subitem text
+                  char buf[3];
+                  ListView_GetItemText(hWndListView, iRow, iCol, buf, _countof(buf));
+
+                  // map the subitem text to a checkbox state
+                  UINT state = DFCS_BUTTONCHECK | DFCS_FLAT;
+                  if (buf[0] == '\0')                           // empty
+                    {
+                      result = CDRF_DODEFAULT;
+                      break;
+                    }
+                  else if (buf[0] == 'y')                       // yes
+                    state |= DFCS_CHECKED;
+                  else if ((buf[0] == 'n') && (buf[1] == 'o'))  // no
+                    state |= 0;
+                  else                                          // n/a
+                    state |= DFCS_INACTIVE;
+
+                  // erase and draw a checkbox
+                  RECT r;
+                  ListView_GetSubItemRect(hWndListView, iRow, iCol, LVIR_BOUNDS, &r);
+                  HBRUSH hBrush = CreateSolidBrush(ListView_GetBkColor(hWndListView));
+                  FillRect(pNmLvCustomDraw->nmcd.hdc, &r, hBrush);
+                  DeleteObject(hBrush);
+                  DrawFrameControl(pNmLvCustomDraw->nmcd.hdc, &r, DFC_BUTTON, state);
+
+                  result = CDRF_SKIPDEFAULT;
+                }
+                break;
+              }
+            *pResult = result;
+            return true;
+          }
+        }
+    }
   }
 
   // We don't care.
index d339011f8de67d7c836a0d6fdbcd169ec4557c6d..3aabc3f5b501c56b0bafb271309e3f73e1c93d6c 100644 (file)
@@ -36,11 +36,18 @@ typedef std::vector<ListViewLine *> ListViewContents;
 class ListView
 {
  public:
+  enum class ControlType
+  {
+    text,
+    checkbox,
+  };
+
   class Header
   {
   public:
     const char *text;
     int fmt;
+    ControlType type;
     int width;
     int hdr_width;
   };
index 23dcdc6ba96a9578a11a5838c25f52f0a38a9064..2b9a724a928bc4a5ad25323d952583e3114f9b0f 100644 (file)
--- a/choose.cc
+++ b/choose.cc
@@ -130,14 +130,14 @@ ChooserPage::~ChooserPage ()
 }
 
 static ListView::Header pkg_headers[] = {
-  {"Package",     LVCFMT_LEFT},
-  {"Current",     LVCFMT_LEFT},
-  {"New",         LVCFMT_LEFT},
-  {"Bin?",        LVCFMT_LEFT},
-  {"Src?",        LVCFMT_LEFT},
-  {"Categories",  LVCFMT_LEFT},
-  {"Size",        LVCFMT_RIGHT},
-  {"Description", LVCFMT_LEFT},
+  {"Package",     LVCFMT_LEFT,  ListView::ControlType::text},
+  {"Current",     LVCFMT_LEFT,  ListView::ControlType::text},
+  {"New",         LVCFMT_LEFT,  ListView::ControlType::text},
+  {"Bin?",        LVCFMT_LEFT,  ListView::ControlType::checkbox},
+  {"Src?",        LVCFMT_LEFT,  ListView::ControlType::checkbox},
+  {"Categories",  LVCFMT_LEFT,  ListView::ControlType::text},
+  {"Size",        LVCFMT_RIGHT, ListView::ControlType::text},
+  {"Description", LVCFMT_LEFT,  ListView::ControlType::text},
   {0}
 };
 
This page took 0.039247 seconds and 5 git commands to generate.