//============================================================================= void CXButtonXP::DrawIcon(CDC *pDC, BOOL bHasText, CRect& rectItem, // from LPDRAWITEMSTRUCT CRect& rectText, BOOL bIsPressed, BOOL bIsThemed, BOOL bIsDisabled) //============================================================================= { if (m_hIcon) { // first get size of icon DWORD dwWidth = 32; // assume 32x32 DWORD dwHeight = 32; ICONINFO iconinfo; if (GetIconInfo(m_hIcon, &iconinfo)) { CBitmap* pBitmap = CBitmap::FromHandle(iconinfo.hbmColor); if (pBitmap) { BITMAP bm; pBitmap->GetBitmap(&bm); dwWidth = bm.bmWidth; dwHeight = bm.bmHeight; } if (iconinfo.hbmColor) ::DeleteObject(iconinfo.hbmColor); if (iconinfo.hbmMask) ::DeleteObject(iconinfo.hbmMask); } CRect rectImage(rectItem); PrepareImageRect(bHasText, rectItem, rectText, bIsPressed, bIsThemed, dwWidth, dwHeight, rectImage); HICON hIcon = m_hIcon; UINT nFlags = bIsDisabled ? DSS_DISABLED : DSS_NORMAL; if (bIsDisabled && m_hGrayIcon) { hIcon = m_hGrayIcon; nFlags = DSS_NORMAL; } nFlags |= DST_ICON; pDC->DrawState(CPoint(rectImage.left, rectImage.top), CSize(rectImage.right - rectImage.left, rectImage.bottom - rectImage.top), hIcon, nFlags, (CBrush *) NULL); } }
//******************************************************************************** void CButtonAppearanceDlg::OnEditImage() { ASSERT (m_pImages != NULL); ASSERT (m_iSelImage >= 0); CSize sizeImage = m_pImages->GetImageSize (); const BOOL bIsAlphaImage = m_pImages->GetBitsPerPixel() == 32; try { CClientDC dc (&m_wndButtonList); CBitmap bitmap; CDC memDC; memDC.CreateCompatibleDC(&dc); if (bIsAlphaImage) { HBITMAP hbmp = CBCGPDrawManager::CreateBitmap_32(sizeImage, NULL); if (hbmp == NULL) { return; } bitmap.Attach(hbmp); } else if (!bitmap.CreateCompatibleBitmap (&dc, sizeImage.cx, sizeImage.cy)) { return; } const COLORREF clrGrayStd = RGB (192, 192, 192); CBitmap* pOldBitmap = memDC.SelectObject (&bitmap); COLORREF clrTransparent = m_pImages->SetTransparentColor (clrGrayStd); memDC.FillSolidRect (CRect (0, 0, sizeImage.cx, sizeImage.cy), clrGrayStd); if (bIsAlphaImage) { CBCGPDrawManager dm(memDC); dm.FillAlpha(CRect (0, 0, sizeImage.cx, sizeImage.cy), 255); } CBCGPDrawState ds; if (!m_pImages->PrepareDrawImage (ds)) { return; } m_pImages->Draw (&memDC, 0, 0, m_iSelImage); m_pImages->EndDrawImage (ds); m_pImages->SetTransparentColor (clrTransparent); memDC.SelectObject (pOldBitmap); BITMAP bmp; ::GetObject (m_pImages->GetImageWell (), sizeof (BITMAP), (LPVOID)&bmp); if (g_pWndCustomize != NULL) { ASSERT_VALID (g_pWndCustomize); if (!g_pWndCustomize->OnEditToolbarMenuImage (this, bitmap, bmp.bmBitsPixel)) { return; } } else { CBCGPImageEditDlg dlg (&bitmap, this, bmp.bmBitsPixel); if (dlg.DoModal () != IDOK) { return; } } if (bIsAlphaImage) { CRect rectImage(0, 0, sizeImage.cx, sizeImage.cy); CBCGPDrawManager::FillAlpha(rectImage, (HBITMAP)bitmap, 255); CBCGPDrawManager::FillTransparentAlpha(rectImage, (HBITMAP)bitmap, clrGrayStd); } m_pImages->UpdateImage (m_iSelImage, (HBITMAP) bitmap); m_wndButtonList.Invalidate (); } catch (...) { CBCGPLocalResource locaRes; AfxMessageBox (IDP_BCGBARRES_INTERLAL_ERROR); } }
void CButtonAppearanceDlg::OnAddImage() { CBCGPLocalResource locaRes; ASSERT (m_pImages != NULL); CSize sizeImage = m_pImages->GetImageSize (); const BOOL bIsAlphaImage = m_pImages->GetBitsPerPixel() == 32; try { CClientDC dc (&m_wndButtonList); CBitmap bitmap; CDC memDC; memDC.CreateCompatibleDC(&dc); if (bIsAlphaImage) { HBITMAP hbmp = CBCGPDrawManager::CreateBitmap_32(sizeImage, NULL); if (hbmp == NULL) { return; } bitmap.Attach(hbmp); } else if (!bitmap.CreateCompatibleBitmap (&dc, sizeImage.cx, sizeImage.cy)) { AfxMessageBox (IDP_BCGBARRES_CANNT_CREATE_IMAGE); return; } CBitmap* pOldBitmap = memDC.SelectObject (&bitmap); CRect rect (0, 0, sizeImage.cx, sizeImage.cy); memDC.FillRect (CRect (0, 0, sizeImage.cx, sizeImage.cy), &globalData.brBtnFace); if (bIsAlphaImage) { CBCGPDrawManager dm(memDC); dm.FillAlpha(CRect (0, 0, sizeImage.cx, sizeImage.cy), 255); } memDC.SelectObject (pOldBitmap); BITMAP bmp; ::GetObject (m_pImages->GetImageWell (), sizeof (BITMAP), (LPVOID)&bmp); if (g_pWndCustomize != NULL) { ASSERT_VALID (g_pWndCustomize); if (!g_pWndCustomize->OnEditToolbarMenuImage (this, bitmap, bmp.bmBitsPixel)) { return; } } else { CBCGPImageEditDlg dlg (&bitmap, this, bmp.bmBitsPixel); if (dlg.DoModal () != IDOK) { return; } } if (bIsAlphaImage) { CRect rectImage(0, 0, sizeImage.cx, sizeImage.cy); CBCGPDrawManager::FillAlpha(rectImage, (HBITMAP)bitmap, 255); CBCGPDrawManager::FillTransparentAlpha(rectImage, (HBITMAP)bitmap, globalData.clrBtnFace); } int iImageIndex = m_pImages->AddImage ((HBITMAP) bitmap); if (iImageIndex < 0) { AfxMessageBox (IDP_BCGBARRES_CANNT_CREATE_IMAGE); return; } RebuildImageList (); m_wndButtonList.SelectButton (iImageIndex); } catch (...) { AfxMessageBox (IDP_BCGBARRES_INTERLAL_ERROR); } }
/////////////////////////////////////////////////////////////////////////////// // // CreateCheckboxImageList() // // Purpose: Create themed checkbox image list // // Parameters: pDC - pointer to device context for drawing // imagelist - image list to create // nSize - height and width of images // crBackground - fill color // // Returns: BOOL - TRUE if image list created OK // BOOL CreateCheckboxImageList(CDC *pDC, CImageList& imagelist, int nSize, COLORREF crBackground) { ASSERT(pDC); ASSERT(nSize > 0); BOOL rc = FALSE; /////////////////////////////////////////////////////////////////////////// // // 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 state = index OR 4. 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, /*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_INACTIVE | DFCS_FLAT, /*0110*/_T("checked disabled"), CBS_CHECKEDDISABLED, DFCS_BUTTONCHECK | DFCS_CHECKED | DFCS_INACTIVE | DFCS_FLAT, /*0111*/_T("tri-state disabled"), CBS_MIXEDDISABLED, DFCS_BUTTON3STATE | DFCS_CHECKED | DFCS_INACTIVE | DFCS_FLAT, // 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_INACTIVE | DFCS_FLAT, /*1110*/_T("checked disabled"), CBS_CHECKEDDISABLED, DFCS_BUTTONCHECK | DFCS_CHECKED | DFCS_INACTIVE | DFCS_FLAT, /*1111*/_T("tri-state disabled"), CBS_MIXEDDISABLED, DFCS_BUTTON3STATE | DFCS_CHECKED | DFCS_INACTIVE | DFCS_FLAT, NULL, 0, 0 // last entry }; if (pDC && (nSize > 0)) { const int nBmpWidth = nSize; const int nBmpHeight = nSize; const int nImages = sizeof(cbdd)/sizeof(cbdd[0]); ASSERT(nImages == 17); if (imagelist.GetSafeHandle()) imagelist.DeleteImageList(); CBitmap bmpCheckboxes; if (bmpCheckboxes.CreateCompatibleBitmap(pDC, nBmpWidth * nImages, nBmpHeight)) { if (imagelist.Create(nBmpWidth, nBmpHeight, ILC_COLOR32 | ILC_MASK, nImages, 1)) { CDC dcMem; if (dcMem.CreateCompatibleDC(pDC)) { HTHEME hTheme = NULL; hTheme = (g_xpStyle.IsThemeActive() && g_xpStyle.IsAppThemed()) ? g_xpStyle.OpenThemeData(NULL, L"BUTTON") : NULL; CBitmap* pOldBmp = 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; CRect rectImage(nImageLeft, nImageTop, nImageLeft+nImageWidth, nImageTop+nImageHeight); for (int i = 0; cbdd[i].pszDesc != NULL; i++) { 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) { g_xpStyle.DrawThemeBackground(hTheme, dcMem, BP_CHECKBOX, cbdd[i].nStateId, &rectImage, NULL); g_xpStyle.DrawThemeEdge(hTheme, dcMem, BP_CHECKBOX, cbdd[i].nStateId, &rectImage, 0, 0, NULL); } else { dcMem.DrawFrameControl(&rectImage, DFC_BUTTON, cbdd[i].nState); } } rectImage.left += nBmpWidth; rectImage.right += nBmpWidth; } if (hTheme) { g_xpStyle.CloseThemeData(hTheme); hTheme = NULL; } dcMem.SelectObject(pOldBmp); imagelist.Add(&bmpCheckboxes, RGB(255,0,255)); if (hTheme) g_xpStyle.CloseThemeData(hTheme); rc = TRUE; } 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 rc; }