在MFC控件中更改背景和标题的颜色 [英] Change color of background and title in MFC Control
问题描述
我想为MFC应用程序中的编辑控件",静态控件"和按钮控件"更改文本颜色和背景颜色.该控件处于CDialogEx
对话框中.
我尝试添加OnCtlColor(使用Visual Studio中的向导,在WM_CTLCOLR消息上),但是我无法设置may静态控件和按钮控件的颜色.
我还在IF构造中的OnCtlColor
函数中也设置了一个断点,但是我什么也没收到.
我还尝试使用SetTextColor
函数从GetDlgItem
检索控件的句柄,但是我无法根据需要更改颜色.
请帮助我.
我可以断言我曾尝试在CDialog
中的OnCtlColor
中使用它,并且它适用于静态控件和编辑控件.
所有您需要做的是:
-
要更改背景色,您需要创建一个在该功能之外仍然存在的画笔,并使用
返回它的 HBRUSH
.return (HBRUSH) m_brush.GetSafeHandle();
因此,您必须创建一个成员或静态变量(此代码中为
m_brush
)(我建议使用第一个变量),并且在对话框初始化中必须创建所需的画笔.我认为也许某些控件对此不起作用,而对于那些我也做到了
pDC->SetBkColor(RGB(0,0,255));
但是似乎什么也没做;它在安全代码中.
-
为了改变文字颜色,我做了
pDC->SetTextColor(RGB(255,0,0));
这些体验对于编辑和静态操作效果很好,但对于组框却根本不起作用!
Groupbox在MFC中是一个奇怪的实体,有点像platyplus:它们是带有BS_GROUPBOX
的CButton
,但是在此功能中,它的nCtlColor
是CTLCOLOR_STATIC
而不是CTLCOLOR_BTN
!我为他们做了
UINT nStyle = (UINT)(pWnd->GetStyle() & 0x0F);
if(nStyle == BS_GROUPBOX)
{
return (HBRUSH) m_brush2.GetSafeHandle();
}
绘制的是组框标题后面的小矩形!
我无法更改组框的文本颜色!
如果您有组框,并且更改其标题的文本颜色确实很重要,则可以从 http://social.msdn.microsoft.com/Forums/vstudio/zh-CN/53f47162-078a-418f-8067-ee61a81ceeac/checkbox- transparent-color-not-working-in-vs2008?forum = vcgeneral ,我做了自己的Groupbox类,现在就像:
class CMyGroupBox: public CButton
{
protected:
virtual void PreSubclassWindow()
{
SetWindowTheme(*this, _T(""), _T(""));
#pragma comment(lib, "UxTheme.lib")
}
};
我刚刚声明了其中一个,并使用了其各自的控件ID进行了DDX_Control
的操作,现在我可以看到提供给SetTextColor
的颜色的文本了.如果您为此控件返回HBRUSH,则绘制的是围绕组框标题绘制的未填充矩形.
更新2:我只是将CMyGroupBox
概括为CMyButton
,因为它不仅在组框中,还在复选框和按钮中都使用了PreSubClassWindow
方法.在复选框中效果很好,在按钮中效果很好,我对此不太满意.
更新3:我试图消除对文本呈现的一些怪异效果,而我只是评论了pDC->SetBkColor(RGB(0,0,255));
行;结果是在文本:(之后出现一个难看的矩形矩形.然后我用pDC->SetBkMode(TRANSPARENT);
替换了它,我也看到了奇怪的效果:(
更新4:为了避免不得不将我的所有复选框,组框和按钮声明为包含PreSubClassWindow方法的类,我研究并发现不需要这样做.代码
SetThemeAppProperties(0);
#pragma comment(lib, "UxTheme.lib")
AfxGetMainWnd()->SendMessage(WM_THEMECHANGED, 0U, 0L);
在整个应用程序级别禁用所有控件的主题设置.
I want to change text color and background color for my EDIT CONTROL, STATIC CONTROL and BUTTON CONTROL in MFC application. The control is in a CDialogEx
dialogue .
I try to add the OnCtlColor (with wizard in visual studio, on the WM_CTLCOLR message) but I can't set the color of may static control and button control.
I put also a break point in the OnCtlColor
function (in the IF construct), but I don't receive anything.
I also tried to use the SetTextColor
function retrieving the handle of the control from GetDlgItem
, but I can't change the color as I want.
Pleas help me.
I can assert that I tried to use in OnCtlColor
in a CDialog
and it worked for the static and for the edit controls.
All you have to do is:
For changing background color, you need to create a brush that still exists outside that function and return its
HBRUSH
withreturn (HBRUSH) m_brush.GetSafeHandle();
So you have to make a variable (
m_brush
in this code) that is member or a static (I recommend the first), and in the dialog initialization you have to create the brush you want.I thought maybe some controls will not work with this, and for those I also did
pDC->SetBkColor(RGB(0,0,255));
But seems to do nothing; it is in the code for safety.
For changing the text color,I did
pDC->SetTextColor(RGB(255,0,0));
These experiences worked well for edits and statics, but did not work at all for groupboxes!
Groupboxes are a strange entity in MFC, some kind of a platyplus: they are a CButton
with the BS_GROUPBOX
, but in this function, its nCtlColor
is CTLCOLOR_STATIC
instead of CTLCOLOR_BTN
! I did this for them
UINT nStyle = (UINT)(pWnd->GetStyle() & 0x0F);
if(nStyle == BS_GROUPBOX)
{
return (HBRUSH) m_brush2.GetSafeHandle();
}
and what got painted was the little rectangle behind the groupbox title!
I could not get the text colour of groupboxes changed!
If you have groupboxes and it is really important to change their titles' text color, you can get the one from http://www.codeproject.com/Articles/29016/XGroupBox-an-MFC-groupbox-control-to-display-text and get its essential code parts: to be derived from CStatic
, the OnPaint()
and DrawItem()
methods. Do not forget also the ON_WM_PAINT()
on the message map. I don't know if the OnEraseBkgnd()
and its is ON_WM_ERASEBKGND()
message mapping are so essential.
It is also needed to change them to be Static text controls in the resources, declare a XGroupBox
variable and do a DDX_Control
of it.
I tested it and it really works.
For buttons, with CButtons it did not work. But, for each button, I simply declared a CMFCButton
variable in the class and did a DDX_Control
of each one. After, I had two choices:
Set its
m_bTransparent
property toTRUE
in the form constructor (search this variable on afxbutton.cpp file for reference) for the ones I wanted to have the same color as the form (I also painted the form; in my case I was implementing themes on an application)Set the Background color with
SetFaceColor()
and set the Text Color withSetTextColor()
in form initialization.
When the CMFCButton
does not have these things set, it got its color from theme blending of the currently selected CMFCVisualManager
.
Note: I also replaced my CSpinButton
entities with CMFCSpinButon
ones, because I wanted colors from the selected theme.
In the OnCtlColor
, the nCtlColor
variable is important because it will allow you to personalize different colors to different types, without testing dynamic_cast
success or failure for every control.
Do not forget to add ON_WM_CTLCOLOR()
to your message map.
UPDATE 1: After following the advice of the accepted answer on http://social.msdn.microsoft.com/Forums/vstudio/en-US/53f47162-078a-418f-8067-ee61a81ceeac/checkbox-transparent-color-not-working-in-vs2008?forum=vcgeneral , I did my own Groupbox class, and now it is like:
class CMyGroupBox: public CButton
{
protected:
virtual void PreSubclassWindow()
{
SetWindowTheme(*this, _T(""), _T(""));
#pragma comment(lib, "UxTheme.lib")
}
};
I just declared one of this, and did DDX_Control
with its respective control ID, and now I can see the text in the color I supplied to SetTextColor
. If you return a HBRUSH for this control, what gets painted is a non-filled rectangle drawn around the groupbox's title.
UPDATE 2: I just generalized the CMyGroupBox
to be CMyButton
, for using its PreSubClassWindow
method not only in groupboxes, but also in checkboxes and buttons. In checkboxes it works well, in buttons, I am not so satisfied with the results.
UPDATE 3: I was trying to remove some weird effect on the rendering of the text and I just commented the pDC->SetBkColor(RGB(0,0,255));
line; the result was an ugly while rectangle behind the text :( . Then I replaced it with pDC->SetBkMode(TRANSPARENT);
and I also see tht weird effect :(
UPDATE 4: In order to avoid to have to declare all my checkboxes, groupboxes and buttons as the class that contains the PreSubClassWindow method, I researched and discovered that it is not needed to do it. The code
SetThemeAppProperties(0);
#pragma comment(lib, "UxTheme.lib")
AfxGetMainWnd()->SendMessage(WM_THEMECHANGED, 0U, 0L);
disables theming for all controls at the whole application level.
这篇关于在MFC控件中更改背景和标题的颜色的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!