如何更改MFC中复选框的背景颜色? [英] How do I change the background colour of a checkbox in MFC?

查看:847
本文介绍了如何更改MFC中复选框的背景颜色?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在设计一个使用复选框的GUI。我需要chechbox的颜色,即黑色标记出现的区域,在选中框时更改。



我尝试过的方法:



我读到了各种在线接触,建议使用 WM_CTLCOLOR 消息并使用 OnCtlColor 函数,但这会在初始化时立即改变颜色。所以我做的是尝试在选中框时更改颜色,如下所示:



I am designing a GUI that makes use of a checkbox. I need the colour of the chechbox, i.e. the area where the black tick appears, to change when the box is checked.

What I have tried:

I read about various approached online which suggest using the WM_CTLCOLOR message and using the OnCtlColor function, but this changes the colour immediately on initialisation. So what I did was to try and change the colour when the box is checked as follows:

void CMyAppDlg::OnBnClickedCheckTxpow()
{
	if (m_chkTxPow.GetState() == 9)
	{
		CDC *pDC;
		CWnd *pWnd;

		//pWnd->SetDlgCtrlID(IDC_CHECK_TXPOW);
		pDC = m_chkTxPow.GetDC();
		pDC->SetBkColor(RGB(0,255,0));
	}	
}





m_chkTxPow 是一个控件分配给复选框的变量。我试图尽可能地模拟在线提供的 OnCtlColor 功能。但是这不起作用。

我也不认为改变背景颜色会影响盒子里面的颜色。有人可以帮我吗?



m_chkTxPow is a control variable assigned to the check box. I was trying to emulate the OnCtlColor functions available online as closely as possible. But this does not work.
Also I don't think changing the background colour affects the colour inside the box. Could anyone help me here?

推荐答案

没有简单的方法可以更改复选框的背景颜色。原因是MFC复选框是系统控件,它不提供更改箭头区域背景颜色的选项,并且该区域不透明。



唯一选项这样做是派生一个使用所有者绘图的 CButton 类。在那里,您可以使用系统功能绘制未选中的框。对于选中的框,然后填充背景并手动绘制箭头。



这可以使用 CDC :: DrawFrameControl对经典复选框进行,用 CDC :: FillSolidRect 填充背景(使用 InflateRect(-2,-2)使用复选框大小)并绘制箭头。



但是应用程序现在不使用经典风格。然后你必须使用 DrawThemeBackground ,使用 CDC :: GradientFill 填充背景,并绘制阴影箭头。但这看起来与系统绘制的复选框完全不同。



There is no simple method to change the background colour of check boxes. The reason is that MFC check boxes are system controls which do not provide options to change the background colour for the arrow area and that area is not transparent.

The only option to do this is deriving a CButton class that uses owner drawing. There you can draw an unchecked box using system functions. For checked boxes fill then the background and draw the arrow manually.

This can be done for classic check boxes using CDC::DrawFrameControl, filling the background with CDC::FillSolidRect (use InflateRect(-2, -2) with the check box size) and drawing the arrow.

But applications do not use the classic style nowadays. Then you have to use DrawThemeBackground, fill the background using CDC::GradientFill, and draw the arrow shaded too. But that will not look exactly like the system drawn check boxes.

// Draw default sized check box.
// Classic        Themed
//
// LLLLLLLLLLLLW  BBBBBBBBBBBBB
// LGGGGGGGGGGSW  B           B
// LG         SW  B           B
// LG       K SW  B        G  B
// LG      KK SW  B       GG  B
// LG K   KKK SW  B  G	 GGG  B
// LG KK KKK  SW  B  GG GGG   B
// LG KKKKK   SW  B  GGGGG    B
// LG  KKK    SW  B   GGG     B
// LG   K     SW  B    G      B
// LSSSSSSSSSSSW  B           B
// WWWWWWWWWWWWW  BBBBBBBBBBBBB
// 
// L = light gray, G = dark gray, S =very light gray, B/K = black, W = white
//
// rcBox:  Rect containing the check box
// clrBk:  Background colour
// clrArr: Colour for arrow (COLOR_BTNSHADOW if disabled; else COLOR_WINDOWTEXT)

// save bk color; is changed by drawing functions
int nBkClr = pDC->GetBkColor(); 

#if 1
// Add aditional states (inactive, pushed) as required
pDC->DrawFrameControl(rcBox, DFC_BUTTON, DFCS_BUTTONCHECK);
#else
// Themed (set nThemedState accordingly):
DrawThemeBackground(m_hTheme, 
    lpDrawItemStruct->hDC, 
    BP_CHECKBOX, nThemedState, 
    &rcBox, NULL);
#endif

CRect rcBk(rcBox);
// Use -3 when themed and CBS_UNCHECKEDHOT
rcBk.InflateRect(-2, -2);
#if 1
pDC->FillSolidRect(&rcBk, clrBk);
#else
// Themed:
// Two triangles: upper left and lower right
static GRADIENT_TRIANGLE TriG[2] = { { 0, 1, 3 }, { 0, 3, 2} };
#define GetR(rgb)   ((int)((rgb) & 0xFF)) // extract R/G/B values fro COLORREF
#define GetG(rgb)   ((int)(((rgb) >> 8) & 0xFF))
#define GetB(rgb)   ((int)(((rgb) >> 16) & 0xFF))
#define Darken(a)   ((a) - ((a) >> 1)) // make R/G/B part darker
#define Brighten(a) ((a) + ((0xFF - (a)) >> 1))	// make R/G/B part brighter
#define Col16(c)    ((COLOR16)((c) << 8)) // convert R/G/B part to COLOR16 value
#define Bright16(a) (Col16(Brighten(a)))
TRIVERTEX TriV[4] = {
{rc.left, rc.top, Col16(GetR(clr)), Col16(GetG(clr)), Col16(GetB(clr)), 0},
{rc.right, rc.top, Bright16(GetR(clr)), Bright16(GetG(clr)), Bright16(GetB(clr)), 0},
{rc.left, rc.bottom, Bright16(GetR(clr)), Bright16(GetG(clr)), Bright16(GetB(clr)), 0},
{rc.right, rc.bottom, 0xff00, 0xff00, 0xff00, 0}
};
pDC->GradientFill(TriV, 4, TriG, 2, GRADIENT_FILL_TRIANGLE);
#endif

// Themed: clrArr = RGB(76, 97, 152); // not shaded!
CRect rcArr(rcBox.left + 3, // left start position
    rcBox.top + 5, // top start position
    rcBox.left + 4, // width 1 pixel
    rcBox.top + 8); // height 3 pixels
for (int i = 0; i < 7; i++) 
{
    pDC->FillSolidRect(&rcArr, clrArr);
    rcArr.OffsetRect(1, (i < 2) ? 1 : -1);
}

pDC->SetBkColor(nBkClr); // restore bk color


这篇关于如何更改MFC中复选框的背景颜色?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆