自绘列表控件list control和botton控件(surface 程序)

来源:互联网 发布:有深度的书 知乎 编辑:程序博客网 时间:2024/05/17 23:31

以下介绍实现自绘控件,包含两方面

一.  实现自绘列表控件,可以实现列表的不同行显示不同的颜色   

二.  实现自绘botton控件,可以实现按钮选中时和未选中时显示不同的文本内容和按钮背景           

 

 

                一.自绘list control,行设置为不同颜色
先把列表控件的风格改为owner draw fixed(所有需要自毁的控件都要这样,这样才会调用OnDrawItem,发生自绘)
第一步:先自己添加一个list control类,即 CmyListCtrl,基类是CListCtrl.
第二步:给自定义列表控件类添加虚函数 virtual void DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct);
     此函数的实现代码如下:
void CMyListCtrl::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct)
{
 ASSERT(lpDrawItemStruct->CtlType == ODT_LISTVIEW); 
 CDC dc;  
 dc.Attach(lpDrawItemStruct->hDC); 
 ASSERT(NULL != dc.GetSafeHdc()); 
 
 // Save these value to restore them when done drawing. 
 COLORREF crOldTextColor = dc.GetTextColor(); 
 COLORREF crOldBkColor = dc.GetBkColor(); 
   
 // 1. 自绘seleteed 的行,设置为系统的选中色
 //If this item is selected, set the background color  
 // and the text color to appropriate values. Also, erase 
 // rect by filling it with the background color. 
 if ( (lpDrawItemStruct->itemAction | ODA_SELECT) && 
      (lpDrawItemStruct->itemState & ODS_SELECTED)) 
 { 
     dc.SetTextColor(::GetSysColor(COLOR_HIGHLIGHTTEXT)); 
     dc.SetBkColor(::GetSysColor(COLOR_HIGHLIGHT)); 
     dc.FillSolidRect(&lpDrawItemStruct->rcItem,  
  ::GetSysColor(COLOR_HIGHLIGHT)); 
 }
 
 //2. 自绘偶数行和奇数行,设置为不同的颜色
 else  
 { 
     if(lpDrawItemStruct->itemID%2) //偶数行 
  dc.FillSolidRect(&lpDrawItemStruct->rcItem, RGB(255,255,132)); 
     else        //奇数行
  dc.FillSolidRect(&lpDrawItemStruct->rcItem, RGB(255,187,255)); 
 } 
   
 //3.  自绘设置焦点的行,画一个红色框选中
 //If this item has the focus, draw a red frame around the 
 // item's rect. 
 if ((lpDrawItemStruct->itemAction | ODA_FOCUS) && 
     (lpDrawItemStruct->itemState & ODS_FOCUS)) 
 { 
     CBrush br(RGB(255, 0, 0)); 
     dc.FrameRect(&lpDrawItemStruct->rcItem, &br); 
 } 
   
 //4.  重绘文本,文本内容需要重绘一遍 ;否则文本显示不出来
 //Draw the text.
 CString strText(_T("")); 
 CRect rcItem; 
 for(int i=0; i<GetHeaderCtrl()->GetItemCount(); i++) 
 { 
     strText = GetItemText(lpDrawItemStruct->itemID, i); 
     GetSubItemRect(lpDrawItemStruct->itemID, i, LVIR_LABEL, rcItem); 
     rcItem.left += 5; 
     dc.DrawText( 
  strText, 
  strText.GetLength(), 
  &rcItem, 
  DT_LEFT|DT_SINGLELINE|DT_VCENTER); 
 } 
     
 // Reset the background color and the text color back to their 
 // original values. 
 dc.SetTextColor(crOldTextColor); 
 dc.SetBkColor(crOldBkColor); 
 dc.Detach(); 
   
   

}

第三步:在View类的OnDrawItem()中调用它.
        IDC_LIST_TOP是list control 的ID号.
        if(nIDCtl==IDC_LIST_TOP)
           m_my_list.DrawItem(lpDrawItemStruct);

 

                      二.自绘botton
第一步:先把botton属性设置为owner draw;
第二步:新添加类CMybotton,基类是CBotton;
第三步:给自定义控件类添加虚函数DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct);
        实现代码如下:
void CMyButton::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct)
{
 CDC ButtonDC; 
 CBitmap bitmapTrans; 
 BITMAP bmp; 
 CDC memDC;    
 CRect rect;    
   
 //得到用于绘制按钮的DC  
 ButtonDC.Attach(lpDrawItemStruct->hDC);   
 //准备用于向按钮区域传输位图 
 memDC.CreateCompatibleDC(&ButtonDC); 
 //获取按钮所占的矩形大小 
 rect=lpDrawItemStruct->rcItem; 
   
 //获取按钮目前所处的状态,根据不同的状态绘制不同的按钮 
 UINT state = lpDrawItemStruct->itemState; 
 //如果按钮已经得到焦点,绘制选中状态下的按钮 
 if(state&ODS_FOCUS) 
 {   
     bitmapTrans.LoadBitmap(IDB_BITMAP1); 
     bitmapTrans.GetBitmap(&bmp); 
     CBitmap *oldMap=memDC.SelectObject(&bitmapTrans); 
    
     //向按钮所在位置传输位图    
     //使用StretcnBlt的目的是为了让位图随按钮的大小而改变    
     ButtonDC.StretchBlt(rect.left,rect.top,rect.right,rect.bottom,&memDC,0,0,bmp.bmWidth,bmp.bmHeight,SRCCOPY); 
     //设置文字背景为透明 
     ButtonDC.SetBkMode(TRANSPARENT); 
     ButtonDC.DrawText("已选中",&rect,DT_CENTER|DT_VCENTER|DT_SINGLELINE);
     memDC.SelectObject(oldMap); 
     bitmapTrans.DeleteObject(); 
    
    
 } 
 else
 { 
    
     bitmapTrans.LoadBitmap(IDB_BITMAP2); 
     CBitmap *old2 = memDC.SelectObject(&bitmapTrans); 
     bitmapTrans.GetBitmap(&bmp); 
     CBitmap *old=memDC.SelectObject(&bitmapTrans); 
     ButtonDC.StretchBlt(rect.left,rect.top,rect.right,rect.bottom,&memDC,0,0,bmp.bmWidth,bmp.bmHeight,SRCCOPY); 
    
     ButtonDC.SetBkMode(TRANSPARENT); 
     ButtonDC.DrawText("未选中",&rect,DT_CENTER|DT_VCENTER|DT_SINGLELINE); 
     memDC.SelectObject(old2); 
     bitmapTrans.DeleteObject(); 
 }
}

第四步:在view类的OnDrawItem()中调用
        if(nIDCtl==IDC_MYBOTTON)//自绘按钮
              m_my_botton.DrawItem(lpDrawItemStruct);
     

 

 

 

 

原创粉丝点击