现在的位置: 首页 > 综合 > 正文

自绘WTL的CComboBox控件

2013年09月07日 ⁄ 综合 ⁄ 共 2167字 ⁄ 字号 评论关闭

这次自绘这个CComboBox控件,真是费了很长的时间,网上没找着一个合适的例子,不过还好总算给弄出来了,下面总结一下:

1,依然是继承CComboBox 和COwnerDraw两个类.然后和其他的OwnerDraw的用法基本一样
(1)在父窗口的MSG_MAP中 添加REFLECT_NOTIFICATIONS() 
(2)在自己的新类的MSG_MAP中添加
     CHAIN_MSG_MAP_ALT(COwnerDraw, 1)
      DEFAULT_REFLECTION_HANDLER()
  并重载DrawItem函数
  你在DrawItem函数中写的重绘代码,做好这些以后呢,运行程序,你发现CComboBox并没有变样(假设要做的DropDown风格的CComboBox而且其他的属性为你都设置好了,并做好了子类化了).只有在你点击下拉按扭的时候在触发了DRAWITEM消息.
在这里要补充一点
   程序设计中组合框使用相当多,但对于组合框的结构,大部分程序设计者只知其大概,即一般的组合框是由 Edit框+ListBox框组合而成。实际情况是这样吗? 如果上面观点正确,那么就能够通过Edit指针和ListBox指针直接操做CComboBox控件了,可如何获得组合框的Edit指针和ListBox指针呢.当然情况不是这么简单的,CComboBox有三种风格Simple DropDown,DropList,我们常用的是后两种形态,其区别就是Dropdown的编辑区为可编辑控件,而droplist为静态控件.也就是说DropDown风格中包含一个Edit,而DropList风格中包含的是Static,  顺便说一下,组合框中的ListBox是在下拉时,也就是弹出ListBox时(即DropDown时)才创建的,等Listbox合起来时销毁的。
   有上面看来,我要自绘这个控件就必须分成两大块,在DrawItem 函数中绘制
ListBox,而要在父窗口的CTLCOLOREDIT消息处理函数中绘制Edit了(同样Static 要在相应的消息处理函数中绘制).再顺便说一下,你已经将CComboBox的属性设置为OwnerDraw Fixed了,你在使用CComboBox的成员函数AddString(),InSertString 添加的item就不会自动显示出来了,你必须要自己动手在DrawItem函数处理了这些item的位置和其他属性了,如果你发现显示的是乱码,可能是的ComboBox的has String 的属性你没有设置.
   CTLCOLOREDIT消息处理函数要注意的是,这里还要分为两部分来处理,一个是CComboBox 的绘制,还有就是它的子控件的绘制,下面贴了我写的代码,仅供参考
LRESULT CLoginDlg::OnCtlColorEdit(UINT , WPARAM wParam, LPARAM lParam, BOOL& )
{
 HDC hdcEdit   = (HDC)  wParam;
 HWND hwndEdit = (HWND) lParam;
    if(hwndEdit == m_ComboBox.GetWindow(GW_CHILD).m_hWnd)
 {
  //绘制Edit,这里我在只是改变了背景色
  HBRUSH m_hBrush = NULL;
  m_hBrush = ::CreateSolidBrush(RGB(216,216,216));
  SetBkMode(hdcEdit, TRANSPARENT);
  //SetBkColor(hdcEdit, m_UserName.Bkcol); //设置为透明,这句就没用了
  SetTextColor(hdcEdit, RGB(0,20,245));
  return ((LRESULT) m_hBrush);
 }
 else if(hwndEdit==m_ComboBox.m_hWnd)
 { 
  //绘制ComboBox
  HBRUSH m_hBrush = NULL;
  m_hBrush = ::CreateSolidBrush(RGB(216,216,216));
  CDCHandle dc = hdcEdit;
  CDC dcMem;
  dcMem.CreateCompatibleDC(dc);
  dc.SaveDC();
  dcMem.SaveDC();
  dcMem.SelectBitmap (m_DropDown);
  CRect rect;
  ::GetClientRect(hwndEdit,&rect);
  dc.FillSolidRect(&rect, RGB(216,216,216));
  //绘制下拉按钮
  dc.BitBlt( rect.right-19,2, 16, 17, dcMem, 0, 0, SRCCOPY); 
  return ((LRESULT) m_hBrush); 
 }
 return 0;
}
你如果少处理edit的,你可以试一下,你会发现 Edit周围让你绘制好了,就是那个可编辑的区域还是白色了.下面是程序的截图:
 自绘WTL的CComboBox控件
 
这张图片是从网上找来的,如果不妥的地方,请给我发邮件通知我,我核实后立即删除
Cedit控件的绘制,就和ComboBox中处理Edit一样,
Check控件,我是用button 来代替的.

抱歉!评论已关闭.