2007-11-26 13:06
1、背景
在工作中,我需要将一些关于控件的信息记录在xml文件中,这些信息包含控件的位置,大小以及一些颜色信息等,这些颜色属性定义成color="#ffaabbcc"的格式,在此主要讨论这个16进制标识的颜色与VC中的COLORREF之间的转换。
2、实现思路
考虑到color属性的特殊性——"#ffaabbcc",在此不关心它的前几位,只在意最后六位,两位两位地分别对应颜色值R,G,B。从这个16进制的颜色表示中要获得RGB三个颜色分量的值,可以考虑按位&,如将ffaabbcc & 0xff0000,得到R的值;fffaabbcc & 0x00ff00得到G的值;同理也可以将ffaabbcc & 0x0000ff得到B的值。在这个过程中,还要注意移位的问题,如取得R的值时就要右移16位,G的值要右移8位,B的值不移动,这样才能得到正确的RGB分量值——RGB(170,187,204)。
3、实现过程
为了阐述以上实现思想,笔者创建一个基于对话框的MFC应用程序,建立如图所示的界面。控件与其属性如下表所示:
表1.控件ID与属性设置
控件ID | READONLY属性 | 关联变量 |
IDC_HEXSTRING | FALSE | CString m_hex |
IDC_RGB | TRUE | CString m_rgb |
IDC_R | TRUE | CString m_r |
IDC_G | TRUE | CString m_g |
IDC_B | TRUE | CString m_b |
IDC_BTN_TRANS | Caption:转换 | Command:OnBtnTrans() |
为IDC_BTN_TRANS添加事件,编辑代码:
void CStringToRGBDlg::OnBtnTrans()
{
UpdateData();
m_hex.TrimLeft();
m_hex.TrimRight();
if
m_hex
==
""
)
{
MessageBox( "
请输入十六进制颜色值!
"
);
return
;
}
//
判断长度
int
length
=
m_hex.GetLength();
if
length!
=
9
//在此为了简便,将字符串的长度规定为9位
{
MessageBox( "
输入的十六进制位数不对,请参照示例重新输入!
"
,
"
十六进制与RGB转换
"
,MB_OK);
((CEdit *
)GetDlgItem(IDC_HEXSTRING))
->
SetSel(
0
,
9
,
TRUE
);
GetDlgItem(IDC_HEXSTRING) ->
SetFocus();
return
;
}
// 判断是否含有非法字符
// ......
CString strTemp;
strTemp=m_hex.Mid(3,length);
if (
-
1
!
=
strTemp.FindOneOf("~!@#$%^&*()_+|-=/{}[]:;'<>?,./ghijklmnopqrstuvwxyzGHIJKLMNOPQRSTUVWXYZ")) //过滤非法字符
{
MessageBox( " 字符串中包含有非法字符!请确定是否输入了十六进制之外的字符 "
);
((CEdit*)GetDlgItem(IDC_HEXSTRING))->SetSel(0,9,TRUE);
GetDlgItem(IDC_HEXSTRING)->SetFocus();
return ;
}
// 合法,则进行转换。程序的主要代码,如果要用到这个转换,则将下面这部分代码拷贝做一点小修改即可
long longTemp = strtol(strTemp.GetBuffer(
100
),NULL,
16
); //先将有用的字符串转换成长整型赋给变量 int R = longTemp &
0xFF0000 )
>>
16
; //先取出表示颜色分量R,移位得到真实的颜色分量值
int G = longTemp &
0x00FF00 )
>>
8
;
int B = longTemp &
0x0000FF;
m_r.Format("%d",R);
m_g.Format("%d",G);
m_b.Format("%d",B);
m_rgb.Format( " RGB(%d,%d,%d) " ,R,G,B);
UpdateData( FALSE );
}