在MFC类库提供了CWnd::OnCtlColor函数,在工作框架的子窗口被重画时将调用该成员函数.因此可以重载WM_CTLCOLOR消息的响应函数.此函数的原型:
afx_msg HBRUSH OnCtlColor(CDC *pDC,CWnd *pWnd,UINT nCtlColor);
NCtlColor 包含了下列值,指定了控件的类型:
CTLCOLOR_BTN 按钮控件
· CTLCOLOR_DLG 对话框
· CTLCOLOR_EDIT 编辑控件
· CTLCOLOR_LISTBOX 列表框控件
· CTLCOLOR_MSGBOX 消息框
· CTLCOLOR_SCROLLBAR 滚动条控件
· CTLCOLOR_STATIC 静态控件。
把索引号为nIndex的数据放到rString变量中. 与其对应的GetLBTextLen(int nIndex)函数就是得到索引号为nIndex中数据的长度。
上代码:
HBRUSH MyComboBox::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor)
{
HBRUSH hbr = CComboBox::OnCtlColor(pDC, pWnd, nCtlColor);
switch (nCtlColor)
{
case CTLCOLOR_EDIT:
break;
case CTLCOLOR_LISTBOX:
int iItemNum = CComboBox::GetCount();
int iWidth = 0;
CString strItem;
CClientDC dc(this);
int iSaveDC = dc.SaveDC();
dc.SelectObject(GetFont());
int iVSWidth = ::GetSystemMetrics(SM_CXVSCROLL);
for (int i = 0; i < iItemNum; i++)
{
GetLBText(i, strItem);
int iWholeWidth = dc.GetTextExtent(strItem).cx + iVSWidth;
iWidth = max(iWidth, iWholeWidth);
}
iWidth += dc.GetTextExtent(L"a").cx;
dc.RestoreDC(iSaveDC);
if (iWidth > 0)
{
CRect rc;
pWnd->GetWindowRect(&rc);
if (rc.Width() != iWidth)
{
rc.right = rc.left + iWidth;
pWnd->MoveWindow(&rc);
}
}
break;
}
// TODO: 在此更改 DC 的任何特性
// TODO: 如果默认的不是所需画笔,则返回另一个画笔
return hbr;
}
在这里,注意下,上述代码,是在自己新建的一个类中写的代码,这个类基于CComboBox类,在主对话框类中,你需要引入我们新建的类的头文件,就能调用新建类了。
代码实现:
其实,上述代码还有很多巧妙之处,有几句代码值得你好好看看,研究研究。并没有我写的这篇文章这样简单,只是我没有讲些许代码分开来讲,刚开始我研究这些代码的时候,也是一句一句代码钻,越钻越发现不简单。我之所以不写出那些我研究过的代码,是希望你自己研究看看,只有这样,我们才能进步。