2015-01-13 4 views
1

windows xp에서 listcontrol 열의 헤더 체크 박스를 만들고 싶습니다. 매우 성공적으로 체크 박스를 만들 수 있지만 문제가 있습니다. 여기 정렬은 listcontrol과 하나 이상의 확인란의 체크 박스가 맞지 않습니다 문제는 테마가 으로 변경되면 확인란의 크기가 커지고 있습니다. 여기에 OnInitDialog()에서 사용중인 코드가 있습니다.listcontrol 열의 머리글 확인란을 항목 확인란에 완벽하게 맞출 수있게 만드는 방법은 무엇입니까?

BOOL CCheckLCDemoDlg::OnInitDialog() 
{ 
    CDialog::OnInitDialog(); 

    pcHeaderCtrl->Attach (m_listCtrl.GetHeaderCtrl()->GetSafeHwnd()); 
    pcHeaderCtrl->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 < 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)->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()->GetSafeHdc(), 16, GetSysColor(COLOR_WINDOW), TRUE); 

    m_checkImgList.Attach(hil); 
    pcHeaderCtrl->SetImageList(&m_checkImgList); 

    HDITEM hdItem; 
    hdItem.mask = HDI_IMAGE | HDI_FORMAT; 
    pcHeaderCtrl->GetItem(0, &hdItem); 
    hdItem.iImage = 1; 
    hdItem.fmt |= HDF_IMAGE; 

    pcHeaderCtrl->SetItem(0, &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 > 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 > 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(&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(&dc)) 
       { 
        // create dc for one 16x16 image 
        CBitmap bmpImage; 
        bmpImage.CreateCompatibleBitmap(&dc, 16, 16); 
        //bmpImage.CreateCompatibleBitmap(&dc, 13, 13); 
        CDC dcImage; 
        dcImage.CreateCompatibleDC(&dc); 
        HBITMAP hOldImage = (HBITMAP) dcImage.SelectObject(bmpImage); 
        RECT rectImage1 = { 0,0,15,15 }; 


        // open theme for checkbox 
        HTHEME hTheme = NULL; 
        hTheme = (bUseVisualThemes && 
           IsThemeActive() && 
           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, &rectImage1, 
            NULL); 
           DrawThemeEdge(hTheme, dcImage, 
            BP_CHECKBOX, cbdd[i].nStateId, &rectImage1, 0, BF_ADJUST|BF_RECT, 
            NULL); 
          } 
          else 
          { 
           dcImage.DrawFrameControl(&rectImage1, DFC_BUTTON, 
            cbdd[i].nState); 
          } 

          // size checkbox as requested 
          dcMem.StretchBlt((rectImage.left-(2)), 0, nSize, nSize, 
           &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; 
} 

} 

그리고 내가 16으로 n 크기를 통과 흔적 및 오류하여 ListControl의 헤더 체크 박스는 다음과 같다 응용 프로그램, enter image description here

를 실행할 때는, 어떤 크기의 것은 동적하지해야하는 통과해야 통계적?

테마가 Windows classic으로 변경되면 다음과 같습니다. enter image description here

누구든지 테마 확인란이 변경 될 때와 동일한 항목과 정확하게 일치해야하는 확인란을 만들기위한 매개 변수로 전달할 크기를 알려주십시오.

답변

0

확인란의 정렬이 표준 크기가 아니기 때문에 원하는대로 할 수 없습니다. 헤더 컨트롤의 확인란을 직접 그려서 시뮬레이트하고 있으므로 가장 좋은 옵션은 지원하려는 다양한 테마로 테스트 한 다음 CreateCheckboxImageList() 메서드에서 오프셋을 조정하여 확인란의 오프셋과 일치시키는 것입니다 목록 컨트롤이 그려집니다.

관련 문제