title: How to make the header checkbox of the listcontrol column to be aligned perfectly in respective to the item check boxes?
body: <p>I want to create a header checkbox for the listcontrol column in windows xp.And I am able to create a checkbox very successfully but the problem
  here is the alignment is of checkbox is not proper to the checkboxes in the listcontrol and one more problem is when the theme
  is changed the size of checkbox is becoming bigger.Here is the code I am using in the OnInitDialog().</p>
  
  <pre><code>BOOL CCheckLCDemoDlg::OnInitDialog()
  {
      CDialog::OnInitDialog();
  
      pcHeaderCtrl-&gt;Attach (m_listCtrl.GetHeaderCtrl()-&gt;GetSafeHwnd());
      pcHeaderCtrl-&gt;SetDlgCtrlID(IDC_LISTVIEWCONTROL_HEADER);
      m_ListView_HeaderCtrlID = (*pcHeaderCtrl).GetDlgCtrlID();
  
      CRect rect;
      m_listCtrl.GetClientRect(rect);
      m_listCtrl.InsertColumn(0, _T(""), LVCFMT_LEFT, 80);
      m_listCtrl.InsertColumn(1, _T("Name"), LVCFMT_LEFT, 150);
      m_listCtrl.InsertColumn(2, _T("Country"), LVCFMT_LEFT, rect.Width() - 230);
  
      CString cs(_T(""));
      for(int i = 0; i &lt; 5; i++)
      {
          cs.Format(_T("%d"), i+1);
          m_listCtrl.InsertItem(i, cs);
          cs.Format(_T("It's the %d item"), i+1);
          m_listCtrl.SetItemText(i, 2, cs);
      }
  
      m_listCtrl.SetExtendedStyle( m_listCtrl.GetExtendedStyle() | LVS_EX_CHECKBOXES);
      //Header Checkbox is being created in this method.
      Init();
  
  
      return TRUE;  // return TRUE  unless you set the focus to a control
  }
  BOOL CCheckLCDemoDlg::Init()
  {
      if (m_blInited)
          return TRUE;
  
      HWND HeaderCtrl = GetDlgItem(IDC_LISTVIEWCONTROL_HEADER)-&gt;GetSafeHwnd();
      //Everything is being done in this function "CreateCheckboxImageList"
      //Function Prototype HIMAGELIST CreateCheckboxImageList(HWND hWnd,HDC hDC,int nSize,COLORREF crBackground,BOOL bUseVisualThemes)
      //nSize- refers the size of the checkbox to be created.
      HIMAGELIST hil = HDCheckboxImageList::CreateCheckboxImageList(HeaderCtrl,GetDC()-&gt;GetSafeHdc(), 16, GetSysColor(COLOR_WINDOW), TRUE);
  
      m_checkImgList.Attach(hil);
      pcHeaderCtrl-&gt;SetImageList(&amp;m_checkImgList);
  
      HDITEM hdItem;
      hdItem.mask = HDI_IMAGE | HDI_FORMAT;
      pcHeaderCtrl-&gt;GetItem(0, &amp;hdItem);
      hdItem.iImage = 1;
      hdItem.fmt |= HDF_IMAGE;
  
      pcHeaderCtrl-&gt;SetItem(0, &amp;hdItem);
  
      m_blInited = TRUE;
  
      ::DeleteObject(hil);
      return TRUE;
  }
  HIMAGELIST CreateCheckboxImageList(HWND hWnd,HDC hDC,
                                     int nSize, 
                                     COLORREF crBackground,
                                     BOOL bUseVisualThemes)
  {
      TRACE(_T("in CreateCheckboxImageList:  nSize=%d\n"), nSize);
  
      _ASSERTE(hDC);
      _ASSERTE(nSize &gt; 0);
  
      HIMAGELIST hImageList = 0;
  
  
      //=========================================================================
      //
      // CHECKBOX IMAGES
      //
      // From MSDN:  "To indicate that the item has no state image, set the
      //             index to zero. This convention means that image zero in 
      //             the state image list cannot be used as a state image."
      //
      // Note that comparable 
      //                      hot image = cold image index OR 8.
      //                      disabled image = index OR 4.
      //
      //=========================================================================
  
      static struct CHECKBOXDRAWDATA
      {
          TCHAR * pszDesc;    // description for debugging
          int nStateId;       // for DrawThemeBackground
          UINT nState;        // for DrawFrameControl
      } 
      cbdd[] =
      {
          // cold -----------------------------------------------------------------------------------
  /*0000*/_T("unused"),               0,                      0,
  /*0001*/_T("unchecked normal"),     CBS_UNCHECKEDNORMAL,    DFCS_BUTTONCHECK | DFCS_FLAT,
  /*0010*/_T("checked normal"),       CBS_CHECKEDNORMAL,      DFCS_BUTTONCHECK | DFCS_CHECKED | DFCS_FLAT,
  
  #if 0
  /*0011*/_T("tri-state normal"),     CBS_MIXEDNORMAL,        DFCS_BUTTON3STATE | DFCS_CHECKED | DFCS_FLAT,
  /*0100*/_T("unused"),               0,                      0,
  /*0101*/_T("unchecked disabled"),   CBS_UNCHECKEDDISABLED,  DFCS_BUTTONCHECK | DFCS_FLAT | DFCS_INACTIVE,
  /*0110*/_T("checked disabled"),     CBS_CHECKEDDISABLED,    DFCS_BUTTONCHECK | DFCS_CHECKED | DFCS_FLAT | DFCS_INACTIVE,
  /*0111*/_T("tri-state disabled"),   CBS_MIXEDDISABLED,      DFCS_BUTTON3STATE | DFCS_CHECKED | DFCS_FLAT | DFCS_INACTIVE,
  
          // hot ------------------------------------------------------------------------------------
  /*1000*/_T("unused"),               0,                      0,
  /*1001*/_T("unchecked normal"),     CBS_UNCHECKEDHOT,       DFCS_BUTTONCHECK | DFCS_FLAT,
  /*1010*/_T("checked normal"),       CBS_CHECKEDHOT,         DFCS_BUTTONCHECK | DFCS_CHECKED | DFCS_FLAT,
  /*1011*/_T("tri-state normal"),     CBS_MIXEDHOT,           DFCS_BUTTON3STATE | DFCS_CHECKED | DFCS_FLAT,
  /*1100*/_T("unused"),               0,                      0,
  /*1101*/_T("unchecked disabled"),   CBS_UNCHECKEDDISABLED,  DFCS_BUTTONCHECK | DFCS_FLAT | DFCS_INACTIVE,
  /*1110*/_T("checked disabled"),     CBS_CHECKEDDISABLED,    DFCS_BUTTONCHECK | DFCS_CHECKED | DFCS_FLAT | DFCS_INACTIVE,
  /*1111*/_T("tri-state disabled"),   CBS_MIXEDDISABLED,      DFCS_BUTTON3STATE | DFCS_CHECKED | DFCS_FLAT | DFCS_INACTIVE,
  #endif
          NULL, 0, 0      // last entry
      };
  
  
      if (nSize &gt; 0)
      {
          const int nBmpWidth = nSize;
          const int nBmpHeight = nSize;
          const int nImages = sizeof(cbdd)/sizeof(cbdd[0]) - 1;
          _ASSERTE(nImages == 3);
  
          CDC dc;
          dc.Attach(hDC);
          CBitmap bmpCheckboxes;
  
          // create bitmap with requested size
          if (bmpCheckboxes.CreateCompatibleBitmap(&amp;dc, nBmpWidth * nImages, nBmpHeight))
          {
              // create imagelist for 16 images
              hImageList = ImageList_Create(nBmpWidth, nBmpHeight, ILC_COLOR32, nImages, 1);
              _ASSERTE(hImageList);
  
              if (hImageList)
              {
                  // create dc for imagelist bitmap
                  CDC dcMem;
                  if (dcMem.CreateCompatibleDC(&amp;dc))
                  {
                      // create dc for one 16x16 image
                      CBitmap bmpImage;
                      bmpImage.CreateCompatibleBitmap(&amp;dc, 16, 16);
                      //bmpImage.CreateCompatibleBitmap(&amp;dc, 13, 13);
                      CDC dcImage;
                      dcImage.CreateCompatibleDC(&amp;dc);
                      HBITMAP hOldImage = (HBITMAP) dcImage.SelectObject(bmpImage);
                      RECT rectImage1 = { 0,0,15,15 };
  
  
                      // open theme for checkbox
                      HTHEME hTheme = NULL;
                      hTheme = (bUseVisualThemes &amp;&amp;
                                IsThemeActive() &amp;&amp; 
                                IsAppThemed()) ? 
                                OpenThemeData(NULL, L"BUTTON") : NULL;
  
                      // initialize imagelist bitmap
                      HBITMAP hOldBmp = (HBITMAP) dcMem.SelectObject(bmpCheckboxes);
                      dcMem.FillSolidRect(0, 0, nBmpWidth*nImages, nBmpHeight, 
                          crBackground);
  
                      int nImageWidth  = nBmpWidth - 2;       // allow 2 for border
                      int nImageHeight = nBmpHeight - 2;
                      int nImageLeft   = (nBmpWidth - nImageWidth) / 2;
                      int nImageTop    = (nBmpHeight - nImageHeight) / 2;
  
                      RECT rectImage = { nImageLeft, 
                                         nImageTop, 
                                         nImageLeft+nImageWidth, 
                                         nImageTop+nImageHeight };
                      //TRACERECT(rectImage);
  
                      // loop thru checkboxes
                      for (int i = 0; cbdd[i].pszDesc != NULL; i++)
                      {
                          //dcImage.FillSolidRect(0, 0, 16, 16, crBackground);
                          dcImage.FillSolidRect(0, 0, 16, 16, crBackground);
  
                          if (_tcscmp(cbdd[i].pszDesc, _T("unused")) == 0)
                          {
                              // unused image slot
                              // note that we skip the first image - they are 1-based
                          }
                          else
                          {
                              if (hTheme)
                              {
                                  DrawThemeBackground(hTheme, dcImage, 
                                      BP_CHECKBOX, cbdd[i].nStateId, &amp;rectImage1, 
                                      NULL);
                                  DrawThemeEdge(hTheme, dcImage, 
                                      BP_CHECKBOX, cbdd[i].nStateId, &amp;rectImage1, 0, BF_ADJUST|BF_RECT, 
                                      NULL);
                              }
                              else
                              {
                                  dcImage.DrawFrameControl(&amp;rectImage1, DFC_BUTTON, 
                                      cbdd[i].nState);
                              }
  
                              // size checkbox as requested
                              dcMem.StretchBlt((rectImage.left-(2)), 0, nSize, nSize, 
                                  &amp;dcImage, 0, 0, 16, 16, SRCCOPY);
                          }
  
                          rectImage.left  += nBmpWidth;
                          rectImage.right += nBmpWidth;
                          //TRACERECT(rectImage);
                      }
  
                      if (hTheme)
                      {
                          CloseThemeData(hTheme);
                          hTheme = NULL;
                      }
  
                      dcImage.SelectObject(hOldImage);
                      dcMem.SelectObject(hOldBmp);
                      BOOL bDelDcRet = dcMem.DeleteDC();
                      BOOL bDelImageDcRet = dcImage.DeleteDC();
  
                      // add imagelist bitmap (16 checkboxes) to imagelist
                      ImageList_Add(hImageList, bmpCheckboxes, 0);
  
                  }
                  else
                  {
                      TRACE(_T("ERROR - failed to create DC\n"));
                  }
              }
              else
              {
                  TRACE(_T("ERROR - failed to create image list\n"));
              }
          }
          else
          {
              TRACE(_T("ERROR - failed to create bitmap\n"));
          }
      }
      else
      {
          TRACE(_T("ERROR - bad parameters\n"));
      }
  
      return hImageList;
  }
  
  }
  </code></pre>
  
  <p>And the when I run the application the listcontrol header checkbox is as follows,
  <img src="https://i.stack.imgur.com/hBN6t.png" alt="enter image description here"></p>
  
  <p>For a trail and error I passed nSize as 16 ,What size needs to be passed which should be dynamical not statical?</p>
  
  <p>When theme changed to windows classic it is as follows.
  <img src="https://i.stack.imgur.com/VdCeO.png" alt="enter image description here"></p>
  
  <p>Can anyone please help me what is the size to be passed as parameter for creating the checkbox which should exactly match with the item checkbox and same thing when theme is changed.</p>