在 MFC 控件中更改背景和标题的颜色
我想在 MFC 应用程序中更改我的 EDIT CONTROL、STATIC CONTROL 和 BUTTON CONTROL 的文本颜色和背景颜色.该控件位于 CDialogEx
对话框中.
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 .
我尝试添加 OnCtlColor(在 Visual Studio 中使用向导,在 WM_CTLCOLR 消息上),但我无法设置可能静态控件和按钮控件的颜色.
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.
我还在 OnCtlColor
函数中(在 IF 构造中)设置了一个断点,但我没有收到任何东西.
I put also a break point in the OnCtlColor
function (in the IF construct), but I don't receive anything.
我也尝试使用 SetTextColor
函数从 GetDlgItem
检索控件的句柄,但我无法随意更改颜色.
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.
请帮帮我.
推荐答案
我可以断言我尝试在 CDialog
中的 OnCtlColor
中使用它并且它适用于静态和编辑控件.
I can assert that I tried to use in OnCtlColor
in a CDialog
and it worked for the static and for the edit controls.
你所要做的就是:
要更改背景颜色,您需要创建一个仍然存在于该函数之外的画笔并返回其
HBRUSH
with
返回 (HBRUSH) m_brush.GetSafeHandle();
所以你必须创建一个成员变量或静态变量(此代码中的 m_brush
)(我推荐第一个),并且在对话框初始化中你必须创建你想要的画笔.
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 在 MFC 中是一个奇怪的实体,有点像 platyplus:它们是带有 BS_GROUPBOX
的 CButton
,但在这个函数中,它的 nCtlColor
是 CTLCOLOR_STATIC
而不是 CTLCOLOR_BTN
!我为他们做了这个
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!
如果您有分组框并且更改其标题的文本颜色非常重要,您可以从 http://www.codeproject.com/Articles/29016/XGroupBox-an-MFC-groupbox-control-to-display-text并获取其基本代码部分:从 CStatic
、OnPaint()
和 DrawItem()
方法派生而来.不要忘记消息映射上的 ON_WM_PAINT()
.我不知道 OnEraseBkgnd()
及其 is ON_WM_ERASEBKGND()
消息映射是否如此重要.还需要将它们更改为资源中的静态文本控件,声明一个XGroupBox
变量并对其进行DDX_Control
.我测试了它,它确实有效.
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.
对于按钮,CButtons 不起作用.但是,对于每个按钮,我只是在类中声明了一个 CMFCButton
变量,并对每个按钮执行了一个 DDX_Control
.之后,我有两个选择:
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:
在表单构造函数中将其
m_bTransparent
属性设置为TRUE
(在 afxbutton.cpp 文件中搜索此变量以供参考)以获得我想要的那些与表单颜色相同(我还绘制了表单;在我的情况下,我正在应用程序上实现主题)
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)
在表单初始化中用SetFaceColor()
设置背景颜色,用SetTextColor()
设置文本颜色.
Set the Background color with SetFaceColor()
and set the Text Color with SetTextColor()
in form initialization.
当 CMFCButton
没有设置这些东西时,它的颜色来自当前选择的 CMFCVisualManager
的主题混合.
When the CMFCButton
does not have these things set, it got its color from theme blending of the currently selected CMFCVisualManager
.
注意:我还将 CSpinButton
实体替换为 CMFCSpinButon
实体,因为我想要所选主题的颜色.
Note: I also replaced my CSpinButton
entities with CMFCSpinButon
ones, because I wanted colors from the selected theme.
在 OnCtlColor
中,nCtlColor
变量很重要,因为它允许您将不同的颜色个性化为不同的类型,而无需测试 dynamic_cast
是否成功或每个控件都失败.
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.
不要忘记将 ON_WM_CTLCOLOR()
添加到您的消息映射中.
Do not forget to add ON_WM_CTLCOLOR()
to your message map.
更新 1:在遵循 http://social.msdn.microsoft.com/Forums/vstudio/en-US/53f47162-078a-418f-8067-ee61a81ceeac/checkbox-transparent-color-not-working-in-vs2008?forum=vcgeneral ,我做了自己的 Groupbox 类,现在是这样的:
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")
}
};
我刚刚声明了其中一个,并使用其各自的控件 ID 执行了 DDX_Control
,现在我可以看到我提供给 SetTextColor
的颜色的文本.如果您为此控件返回 HBRUSH,则绘制的是围绕组框标题绘制的未填充矩形.
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.
更新 2: 我只是将 CMyGroupBox
概括为 CMyButton
,因为使用它的 PreSubClassWindow
方法不仅在组框中,但也在复选框和按钮中.在复选框中效果很好,在按钮中,我对结果不太满意.
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.
更新 3: 我试图消除对文本呈现的一些奇怪影响,我只是评论了 pDC->SetBkColor(RGB(0,0,255));代码>行;结果是文本后面的一个丑陋的矩形:(.然后我用
pDC->SetBkMode(TRANSPARENT);
替换它,我也看到了奇怪的效果:(
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 :(
更新 4: 为了避免必须将我所有的复选框、组框和按钮声明为包含 PreSubClassWindow 方法的类,我研究并发现不需要这样做.代码
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.
相关文章