现在的位置: 首页 > 自动控制 > 工业·编程 > 正文

clistbox 和Cbutton的自绘

2013-08-24 23:44 工业·编程 ⁄ 共 2509字 ⁄ 字号 暂无评论

1.自绘了CListBox:简记如下:

在DrawItem中自绘,必须设定属性:LBS_OWNERDRAWFIXED |LBS_HASSTRINGS;

如果不设定LBS_HASSTRINGS,那么GetText取得的将是乱码:

三个难点,一是自绘属性加上LBS_OWNERDRAWFIXED后,必须同时重载DrawItem和MeasureItem,我第一次只重载了DrawItem,发现出现堆栈错误。
二是自绘属性中必须有LBS_HASSTRINGS,不然GetText取得的将是乱码.
三是自绘中 dc.Attach(lpDIS->hDC);必须有对应的dc.Detach();,我第一次没有加dc.Detach();结果发现只能显示一项

listbox自绘非常简单:直接贴代码:
void CListBoxEx::DrawItem(LPDRAWITEMSTRUCT lpDIS) 

  CDC dc ; 
  dc.Attach(lpDIS->hDC); 
  CRect rcItem = lpDIS->rcItem ; 
  CString text; 
  GetText(lpDIS->itemID, text); 
  dc.SetBkMode(TRANSPARENT); 
  dc.SetTextColor(RGB(0,255,0)); 
  if ((lpDIS->itemState & ODS_SELECTED)) 
     dc.FillSolidRect(&rcItem,RGB(255,0,0)); 
  else 
      dc.FillSolidRect(&rcItem,RGB(255,255,255)); 
  dc.TextOut(rcItem.left,rcItem.top,text); 
  dc.Detach();//不分离的话就只能显示一项,其他的要点击后才出来 

2.自绘的button有三种状态,选中,停留,离开:

绘制也很简单:

一个难点:WM_MOUSELEAVE和WM_MOUSEHOVER不是标准的Windows消息函数,解决方法:可通过_TrackMouseEvent()函数来触发.具体可参看MSDN有详细说明

1.在.h中加入:
bool m_bHover;//悬停 
bool m_bSelected;//按下 
bool m_bTracking;//跟踪 

2.重载DrawItem和PreSubclassWindow;

3.三个消息:
afx_msg void OnMouseMove(UINT nFlags, CPoint point);
afx_msg LRESULT OnMouseHover(WPARAM wParam,LPARAM lParam);
afx_msg LRESULT OnMouseLeave(WPARAM wParam,LPARAM lParam);

[cpp] view plaincopy
void CSkinButton::OnMouseMove(UINT nFlags, CPoint point) 

    if (!m_bTracking) 
    { 
    TRACKMOUSEEVENT tme; 
    tme.cbSize=sizeof(tme); 
    tme.dwFlags=TME_HOVER|TME_LEAVE;//发送WM_MOUSEHOVER和WM_MOUSELEAVE 
    tme.hwndTrack=m_hWnd;////指定要追踪的窗口 
    tme.dwHoverTime=10;//鼠标在按钮上停留超过10ms,才认为状态为HOVER 
    m_bTracking=_TrackMouseEvent(&tme);//开启Windows的WM_MOUSELEAVEWM_MOUSEHOVER事件支持 
    } 
    CButton::OnMouseMove(nFlags, point); 

LRESULT  CSkinButton::OnMouseLeave(WPARAM wParam,LPARAM lParam) 

    m_bHover=false; 
    m_bTracking=false;////若已经离开,则停止追踪 
    return true; 

LRESULT  CSkinButton::OnMouseHover(WPARAM wParam,LPARAM lParam) 

    m_bHover=true; 
    InvalidateRect(NULL);//一定要调用刷新 
    return true; 

4.在PreSubclassWindow初始化各种变量,如
void CSkinButton::PreSubclassWindow() 

     m_bHover=false; 
     m_bSelected=false; 
     m_bTracking=false; 
     ModifyStyle(0,BS_OWNERDRAW); 
     CButton::PreSubclassWindow(); 

5.在DrawItem中加入最后的自绘代码:
void CSkinButton::DrawItem(LPDRAWITEMSTRUCT lpdi) 

  CDC  dc; 
  dc.Attach(lpdi->hDC); 
  CRect  rc(lpdi->rcItem); 
  CString  szText; 
  GetWindowText(szText); //获得文本 
  if (lpdi->itemState & ODS_SELECTED) 
  { 
      m_bSelected=true; 
  } 
  else 
  { 
      m_bSelected=false; 
  } 
   if (m_bSelected)//按下时绘制 
   { 
       //dc.DrawText(....); 
   } 
   else if (m_bHover)//停留时绘制 
   { 
      //dc.DrawText(....); 
   } 
   else 
   { 
     //dc.DrawText(....); 
   } 
   dc.Detach(); 

给我留言

留言无头像?