您的位置:首页 > 其它

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

2011-07-08 21:31 253 查看
以下介绍实现自绘控件,包含两方面
一. 实现自绘列表控件,可以实现列表的不同行显示不同的颜色
二. 实现自绘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);
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: