非常诡异的界面显示 OnCtlColor函数

飞檐走壁 2010-07-19 01:36:02
1 我做的是个对话框程序。
2 我先定义了一些颜色。

#define write RGB(255,255,255)
#define yellow RGB(255,255,0)
#define orange RGB(247,148,29)
#define red RGB(255,0,0)

3 我用向导生成了函数OnCtlColor

HBRUSH CMyDlg::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor)
{
HBRUSH hbr = CDialog::OnCtlColor(pDC, pWnd, nCtlColor);

// TODO: Change any attributes of the DC here
switch(pWnd-> GetDlgCtrlID())
{
case IDC_EDIT1:
{
pDC-> SetTextColor(RGB(0,0,0));
pDC-> SetBkMode(TRANSPARENT);
//pDC->SetBkColor(RGB(0,0,0));
HBRUSH b=CreateSolidBrush(write);
return b;
}
case IDC_EDIT2:
{
pDC-> SetTextColor(RGB(0,0,0));
pDC-> SetBkMode(TRANSPARENT);
//pDC->SetBkColor(RGB(0,0,0));
HBRUSH b=CreateSolidBrush(red);
return b;
}
case IDC_EDIT3:
{
pDC-> SetTextColor(RGB(0,0,0));
pDC-> SetBkMode(TRANSPARENT);
//pDC->SetBkColor(RGB(0,0,0));
HBRUSH b=CreateSolidBrush(red);
return b;
}
case IDC_EDIT4:
{
pDC-> SetTextColor(RGB(0,0,0));
pDC-> SetBkMode(TRANSPARENT);
//pDC->SetBkColor(RGB(0,0,0));
HBRUSH b=CreateSolidBrush(orange);
return b;
}
case IDC_EDIT5:
{
pDC-> SetTextColor(RGB(0,0,0));
pDC-> SetBkMode(TRANSPARENT);
//pDC->SetBkColor(RGB(0,0,0));
HBRUSH b=CreateSolidBrush(red);
return b;
}
case IDC_EDIT6:
{
pDC-> SetTextColor(RGB(0,0,0));
pDC-> SetBkMode(TRANSPARENT);
//pDC->SetBkColor(RGB(0,0,0));
HBRUSH b=CreateSolidBrush(red);
return b;
}
case IDC_EDIT7:
{
pDC-> SetTextColor(RGB(0,0,0));
pDC-> SetBkMode(TRANSPARENT);
//pDC->SetBkColor(RGB(0,0,0));
HBRUSH b=CreateSolidBrush(orange);
return b;
}
case IDC_EDIT8:
{
pDC-> SetTextColor(RGB(0,0,0));
pDC-> SetBkMode(TRANSPARENT);
//pDC->SetBkColor(RGB(0,0,0));
HBRUSH b=CreateSolidBrush(red);
return b;
}
default:
return hbr;
}

// TODO: Return a different brush if the default is not desired
return hbr;

}


4 运行程序,结果诡异的事情发生了。
我对话框上所有的combo box控件都和IDC_EDIT2的颜色一样,
IDC_EDIT2的颜色改成什么combo box的颜色就改成什么。
我看了所有combo box的资源,发现都和IDC_EDIT2不一样。
然后我再拖了几个combo box在对话框上 发现背景颜色还是和IDC_EDIT2一样。
...全文
228 23 打赏 收藏 转发到动态 举报
写回复
用AI写文章
23 条回复
切换为时间正序
请发表友善的回复…
发表回复
wltg2001 2010-07-19
  • 打赏
  • 举报
回复
这是我得到的东西
1 是IDOK按钮
2 是IDCANCEL按钮
1000是 combo下拉列表
1001是 combo编辑框
1002
1003
1004是 其他控件ID

有什么不对的吗?
=========
我下午试验时发现弹出的ID不是这些,可能是我试时弄错了什么也有可能,刚才试又正确了,晕!
飞檐走壁 2010-07-19
  • 打赏
  • 举报
回复
没明白,再顶一下。
Icedmilk 2010-07-19
  • 打赏
  • 举报
回复
[Quote=引用 20 楼 wltg2001 的回复:]

引用 17 楼 baihengxiang 的回复:
引用 16 楼 icedmilk 的回复:
呵呵对的

我说的是1000控制的是combo的下拉列表的背景色
而1001控制的是combo的可输入部分的背景色

而直接通过comboID根本无法控制这两个显色

我的1000对combo下拉列表没影响。
看来用这种做法来改变控件的背景似乎不怎么可靠。

根本原因不是这个,……
[/Quote]
0

0

1

0

2

1003

0

1003

0

1001

1000

1000

1001

0

1002

1001

0

1004

1000

0

1004

0

1004

0

1004

0

1

0

1
这是我得到的东西
1 是IDOK按钮
2 是IDCANCEL按钮
1000是 combo下拉列表
1001是 combo编辑框
1002
1003
1004是 其他控件ID

有什么不对的吗?
wltg2001 2010-07-19
  • 打赏
  • 举报
回复
[Quote=引用 17 楼 baihengxiang 的回复:]
引用 16 楼 icedmilk 的回复:
呵呵对的

我说的是1000控制的是combo的下拉列表的背景色
而1001控制的是combo的可输入部分的背景色

而直接通过comboID根本无法控制这两个显色

我的1000对combo下拉列表没影响。
看来用这种做法来改变控件的背景似乎不怎么可靠。
[/Quote]
根本原因不是这个,你可以在switch中用:
CString work;
work.Format(_T("%d"),pWnd->GetDlgCtrlID());将ID打印出来看看,会发现很诡异的现象,打印出来的ID和你在resource.h中定义的ID根本就不同。
在MSDN中对WM_CTLCOLOR的解释中说,这个消息是win16下的消息,在Win32中已经没有这个消息了,而用WM_CTLCOLORBTN 等一系列消息代替的,MFC估计是用了别的方法来模拟了WM_CTLCOLOR的处理,但是在处理过程中出现了问题,造成了这个现象。
BlueMap 2010-07-19
  • 打赏
  • 举报
回复
看样子解决了,等待结贴。。。
Icedmilk 2010-07-19
  • 打赏
  • 举报
回复
Windows 7
Windows xp
VC 2008
VC 6.0
1000都能控制combo的下拉列表的颜色

[Quote=引用 17 楼 baihengxiang 的回复:]
引用 16 楼 icedmilk 的回复:
呵呵对的

我说的是1000控制的是combo的下拉列表的背景色
而1001控制的是combo的可输入部分的背景色

而直接通过comboID根本无法控制这两个显色

我的1000对combo下拉列表没影响。
看来用这种做法来改变控件的背景似乎不怎么可靠。
[/Quote]
飞檐走壁 2010-07-19
  • 打赏
  • 举报
回复
[Quote=引用 16 楼 icedmilk 的回复:]
呵呵对的

我说的是1000控制的是combo的下拉列表的背景色
而1001控制的是combo的可输入部分的背景色

而直接通过comboID根本无法控制这两个显色
[/Quote]
我的1000对combo下拉列表没影响。
看来用这种做法来改变控件的背景似乎不怎么可靠。
Icedmilk 2010-07-19
  • 打赏
  • 举报
回复
呵呵对的

我说的是1000控制的是combo的下拉列表的背景色
而1001控制的是combo的可输入部分的背景色

而直接通过comboID根本无法控制这两个显色
飞檐走壁 2010-07-19
  • 打赏
  • 举报
回复
[Quote=引用 14 楼 icedmilk 的回复:]
我帮你测试了
我拖了个EDIT 拖了个 Combo

结果我设置Edit是啥颜色,Combo列表的背景就是啥颜色

这时那个Edit的ID是1000

我改了一下,改成1003就不会这样了

另外
我在switch代码里加入

C/C++ code

case 1000:
{
pDC-> SetTextColor(RG……
[/Quote]


我combo不是受1000控制,而是受1001控制,太怪了。
我改了资源,IDC_EDIT2 1001改为了1551,然后加了代码
		
case 1001:
{
pDC-> SetTextColor(RGB(0,0,0));
pDC-> SetBkMode(TRANSPARENT);
HBRUSH b=CreateSolidBrush(red);
return b;
}

发现1001控制了所有的combo box
Icedmilk 2010-07-19
  • 打赏
  • 举报
回复
我帮你测试了
我拖了个EDIT 拖了个 Combo

结果我设置Edit是啥颜色,Combo列表的背景就是啥颜色

这时那个Edit的ID是1000

我改了一下,改成1003就不会这样了

另外
我在switch代码里加入

case 1000:
{
pDC-> SetTextColor(RGB(0,0,0));
pDC-> SetBkMode(TRANSPARENT);
HBRUSH b=CreateSolidBrush(yellow);
return b;
}

就可以控制Combo列表背景的颜色

估计1000就是所有Combo列表背景的ID
fangchao918628 2010-07-19
  • 打赏
  • 举报
回复
你将你的pWnd->GetDlgCtrlID()打印出来,好像这样获取到的是combo box EDIT的ID,好像看过,你试验下
飞檐走壁 2010-07-19
  • 打赏
  • 举报
回复
#define WRITE_BRUSH RGB(255,255,255)
#define YELLOW_BRUSH RGB(255,255,0)
#define ORANGE_BRUSH RGB(247,148,29)
#define RED_BRUSH RGB(255,0,0)

HBRUSH m_bBrush[4]; //成员变量

// 对话框的构造函数中初始化
m_bBrush[0] = CreateSolidBrush(WRITE_BRUSH);
m_bBrush[1] = CreateSolidBrush(YELLOW_BRUSH);
m_bBrush[2] = CreateSolidBrush(ORANGE_BRUSH);
m_bBrush[3] = CreateSolidBrush(RED_BRUSH);

// WM_CTLCOLOR消息响应函数
HBRUSH CXXXDlg::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor)
{
HBRUSH hbr = CDialog::OnCtlColor(pDC, pWnd, nCtlColor);

// TODO: Change any attributes of the DC here
switch(pWnd->GetDlgCtrlID())
{
case IDC_EDIT1:
pDC->SetTextColor(WHITE_BRUSH);
pDC->SetBkMode(TRANSPARENT);
return m_bBrush[3];

case IDC_EDIT2:
pDC->SetTextColor(YELLOW_BRUSH);
pDC->SetBkMode(TRANSPARENT);
return m_bBrush[2];

case IDC_EDIT3:
pDC->SetTextColor(ORANGE_BRUSH);
pDC->SetBkMode(TRANSPARENT);
return m_bBrush[1];

case IDC_EDIT4:
pDC->SetTextColor(RED_BRUSH);
pDC->SetBkMode(TRANSPARENT);
return m_bBrush[0];
default:
break;
}
// TODO: Return a different brush if the default is not desired
return hbr;
}



这个办法还是不行啊。
怎么办呢。
飞檐走壁 2010-07-19
  • 打赏
  • 举报
回复
IDC_EDIT2不是最后操作的,顺序和我在前面写的一样。
在switch()之前加上if(nCtlColor == CTLCOLOR_EDIT)我试了。
还是一样的。我把debug删除后再编译执行也不行。
你可以自己建一个工程向我那样去试一下。
我感觉太怪了。
Eleven 2010-07-19
  • 打赏
  • 举报
回复
[Quote=引用 8 楼 liweisdut 的回复:]
引用 7 楼 baihengxiang 的回复:
我重新建了一个对话框工程,在上面拉了几个CEdit控件和几个combo box控件,同样加入了那个函数OnCtlColor,结果还是一样。

对控件的操作顺序是怎样的?是不是最后对IDC_EDIT2操作的?
[/Quote]
和控件操作顺序有个啥关系。。。

#define WRITE_BRUSH RGB(255,255,255)
#define YELLOW_BRUSH RGB(255,255,0)
#define ORANGE_BRUSH RGB(247,148,29)
#define RED_BRUSH RGB(255,0,0)

HBRUSH m_bBrush[4]; //成员变量

// 对话框的构造函数中初始化
m_bBrush[0] = CreateSolidBrush(WRITE_BRUSH);
m_bBrush[1] = CreateSolidBrush(YELLOW_BRUSH);
m_bBrush[2] = CreateSolidBrush(ORANGE_BRUSH);
m_bBrush[3] = CreateSolidBrush(RED_BRUSH);

// WM_CTLCOLOR消息响应函数
HBRUSH CXXXDlg::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor)
{
HBRUSH hbr = CDialog::OnCtlColor(pDC, pWnd, nCtlColor);

// TODO: Change any attributes of the DC here
switch(pWnd->GetDlgCtrlID())
{
case IDC_EDIT1:
pDC->SetTextColor(WHITE_BRUSH);
pDC->SetBkMode(TRANSPARENT);
return m_bBrush[3];

case IDC_EDIT2:
pDC->SetTextColor(YELLOW_BRUSH);
pDC->SetBkMode(TRANSPARENT);
return m_bBrush[2];

case IDC_EDIT3:
pDC->SetTextColor(ORANGE_BRUSH);
pDC->SetBkMode(TRANSPARENT);
return m_bBrush[1];

case IDC_EDIT4:
pDC->SetTextColor(RED_BRUSH);
pDC->SetBkMode(TRANSPARENT);
return m_bBrush[0];
default:
break;
}
// TODO: Return a different brush if the default is not desired
return hbr;
}
liweisdut 2010-07-19
  • 打赏
  • 举报
回复
在switch()之前加上if(nCtlColor == CTLCOLOR_EDIT)//若是编辑框控件,则……
liweisdut 2010-07-19
  • 打赏
  • 举报
回复
[Quote=引用 7 楼 baihengxiang 的回复:]
我重新建了一个对话框工程,在上面拉了几个CEdit控件和几个combo box控件,同样加入了那个函数OnCtlColor,结果还是一样。
[/Quote]
对控件的操作顺序是怎样的?是不是最后对IDC_EDIT2操作的?
飞檐走壁 2010-07-19
  • 打赏
  • 举报
回复
我重新建了一个对话框工程,在上面拉了几个CEdit控件和几个combo box控件,同样加入了那个函数OnCtlColor,结果还是一样。
飞檐走壁 2010-07-19
  • 打赏
  • 举报
回复
[Quote=引用 4 楼 liweisdut 的回复:]
引用 1 楼 visualeleven 的回复:
你的HBRRUSH是局部变量,换成类的成员变量试试

跟HBRRUSH是不是局部变量有关系吗?
我认为是与你每个case后的返回值有关,当代码执行了case:IDC_EDIT2,返回的刷子会将整个界面都刷成这个刷子颜色。
[/Quote]

界面上还有IDC_EDIT9 IDC_EDIT10 IDC_EDIT11 IDC_EDIT12等都是正常的,对话框背景都正常,其他的控件都正常,就只有combo box不正常。
liweisdut 2010-07-19
  • 打赏
  • 举报
回复
[Quote=引用 4 楼 liweisdut 的回复:]
引用 1 楼 visualeleven 的回复:
你的HBRRUSH是局部变量,换成类的成员变量试试

跟HBRRUSH是不是局部变量有关系吗?
我认为是与你每个case后的返回值有关,当代码执行了case:IDC_EDIT2,返回的刷子会将整个界面都刷成这个刷子颜色。
[/Quote]
所有控件的底色。对话框背景色都被刷成同一颜色
liweisdut 2010-07-19
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 visualeleven 的回复:]
你的HBRRUSH是局部变量,换成类的成员变量试试
[/Quote]
跟HBRRUSH是不是局部变量有关系吗?
我认为是与你每个case后的返回值有关,当代码执行了case:IDC_EDIT2,返回的刷子会将整个界面都刷成这个刷子颜色。
加载更多回复(3)

15,980

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 界面
社区管理员
  • 界面
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧