重绘是获得较好界面的重要手段。今天学习了有关重绘的一些问题,总结如下:
重绘经常要用到的一些函数:
1)CDC::DrawEdge(LPRECT lpRect,UINT nEdge,UINT nFlags);
参数:lpRect指向一个包含矩形逻辑坐标的RECT结构的指针;
nEdge:指定内边和外边的类型,必须是一个内边界标志和外边界标志的组合。可以是下面的一种
EDGE_BUMP:BDR_RASIEDOUTER和BDR_SUNKENINNER的组合
EDGE_ETCHED:BDR_SUNKENOUTER和BDR_RAISEDINNER的组合
EDGE_RASIED:BDR_RAISEDOUTER和BDR_RASIEDINNER的组合
EDGE_SUNKEN:BDR_SUNKENOUTER和BDR_SUNKENINNER的组合
参数nFlags的取值可以是:
BF_RECT:整个边界矩形;BF_LEFT:边界矩形的左边;BF_BOTTOM:边界矩形的底边;等等
2)CDC::DrawFocusRect(LPCRECT lpRect);
画一个说明输入焦点的矩形。
3)CDC::DrawFrameControl(LPRECT lpRect,UINT nType,UINT nState);
参数:lpRect包含矩形逻辑坐标的RECT结构的指针;
nType:指定要画的框架控制的类型.其值可以为:DFC_BUTTON(标准按钮)、DFC_CAPTION(标题条)、DFC_MENU(菜单)、DFC_SCROLL(滚动条)。
nState:指定框架控制的初始状态,可用下列值中的一个或者多个设置要画控制的状态:
DFCS_CHECKED:按钮选中。DFCS_FLAT:按钮有一个平面边界;DFCS_INACTIVE:按钮非活动
DFCS_MONO:按钮有一个单色边界,DFCS_PUSHED按钮按下。等等
4)CDC::FillRect(LPCRECT lpRect,CBrush *pBrush);
用给定的画刷填充指定的矩形,包括左边和上部边界,但不填充右边和底部边界
5)CDC::FrameRect(LPCRECT lpRect,CBrush *pBrush);
用给定的画刷画边框,边框的宽度和高度总是一个逻辑单位
6)CDC::FillSolidRect(LPRECT lpRect,COLORREF clr);
用指定的颜色填充矩形的颜色
7)CDC::FromHandle(HDC hdc);在给予一个设备环境句柄时返回一个CDC对象指针
8)CDC::Attach(HDC hdc);//连接hdc到CDC对象。
9)CDC::Detach();将m_hdc从CDC对象断开,并将m_hdc设置为NULL。
10)CDC::SetBkMode(int nMode);OPAQUE:在绘制文本、阴影画刷或笔风格之前,用当前背景色填充背景
TRANSARENT:在绘制之前不改变背景
下面是一个颜色选择的示例。
类的声明文件为:
#if !defined(AFX_COLORPIKERCB_H__800BAB1C_2EF1_4B12_94F7_3812E05F37D3__INCLUDED_)
#define AFX_COLORPIKERCB_H__800BAB1C_2EF1_4B12_94F7_3812E05F37D3__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
// ColorPikerCB.h : header file
//
#include <string.h>
/
// CColorPikerCB window
#define CCB_MAX_COLOR_NAME 16
#define CCB_MAX_COLORS 16
struct sColorAndName
{
COLORREF m_crColor;
char m_cColor[CCB_MAX_COLOR_NAME];
sColorAndName()
{
ZeroMemory(this,sizeof(sColorAndName));//初始化结构体
};
sColorAndName(COLORREF crColor,PCSTR cpColor)
{
ZeroMemory(this,sizeof(sColorAndName));
m_crColor=crColor; //设置颜色值
strncpy(m_cColor,cpColor,CCB_MAX_COLOR_NAME);//设置颜色名称
};
};
class CColorPikerCB : public CComboBox
{
// Construction
public:
CColorPikerCB();
private:
bool m_bInitialized;
CString m_sColorName;
static sColorAndName m_spColos[CCB_MAX_COLORS];
void Initialized(void);
// Attributes
public:
COLORREF GetSelectedColorValue(void);
CString GetSelectedColorName(void);
void SetSelectedColorValue(COLORREF crClr);
void SetSelectedColorName(PCSTR cpColor);
bool RemoveColor(PCSTR cpColor);
bool RemoveColor(COLORREF crClr);
int AddColor(PCSTR cpName,COLORREF crClr);
// Operations
public:
// Overrides
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CColorPikerCB)
public:
virtual void DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct);
protected:
virtual void PreSubclassWindow();
//}}AFX_VIRTUAL
// Implementation
public:
virtual ~CColorPikerCB();
// Generated message map functions
protected:
//{{AFX_MSG(CColorPikerCB)
afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};
/
//{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
#endif // !defined(AFX_COLORPIKERCB_H__800BAB1C_2EF1_4B12_94F7_3812E05F37D3__INCLUDED_)
类的实现文件为:
// ColorPikerCB.cpp : implementation file
//
#include "stdafx.h"
#include "ColorPick.h"
#include "ColorPikerCB.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/
// CColorPikerCB
CColorPikerCB::CColorPikerCB()
{
m_bInitialized=false;
}
CColorPikerCB::~CColorPikerCB()
{
}
BEGIN_MESSAGE_MAP(CColorPikerCB, CComboBox)
//{{AFX_MSG_MAP(CColorPikerCB)
ON_WM_CREATE()
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/
// CColorPikerCB message handlers
sColorAndName CColorPikerCB::m_spColos[CCB_MAX_COLORS]=
{
sColorAndName(RGB(0,0,0),"Black"),
sColorAndName(RGB(0x80,0,0),"Marnoon"),
sColorAndName(RGB(0,0x80,0),"Green"),
sColorAndName(RGB(0x80,0x80,0),"Olive"),
sColorAndName(RGB(0,0,0x80),"Navy"),
sColorAndName(RGB(0x80,0,0x80),"Purple"),
sColorAndName(RGB(0,0x80,0x80),"Teal"),
sColorAndName(RGB(0x80,0x80,0x80),"Grey"),
sColorAndName(RGB(0xc0,0xc0,0xc0),"Sliver"),
sColorAndName(RGB(0xff,0,0),"Red"),
sColorAndName(RGB(0,0xff,0),"Lime"),
sColorAndName(RGB(0xff,0xff,0x00),"Yellow"),
sColorAndName(RGB(0,0,0xff),"Blue"),
sColorAndName(RGB(0xff,0,0xff),"Fushcia"),
sColorAndName(RGB(0,0xff,0xff),"Aque"),
sColorAndName(RGB(0xff,0xff,0xff),"White"),
};
int CColorPikerCB::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (CComboBox::OnCreate(lpCreateStruct) == -1)
return -1;
return 0;
}
void CColorPikerCB::PreSubclassWindow()
{
// TODO: Add your specialized code here and/or call the base class
Initialized();
//ModifyStyle(0,CBS_DROPDOWNLIST|CBS_OWNERDRAWFIXED|CBS_HASSTRINGS);
CComboBox::PreSubclassWindow();
SetCurSel(0);
}
void CColorPikerCB::Initialized(void)
{
int iAddedItem=-1;
if(m_bInitialized)
return;
for(int iColor=0;iColor<CCB_MAX_COLORS;iColor++)
{
iAddedItem=AddString(m_spColos[iColor].m_cColor);
if(iAddedItem==CB_ERRSPACE)
{
break;
}
else
{
SetItemData(iAddedItem,m_spColos[iColor].m_crColor);
}
m_bInitialized=true;
}
}
COLORREF CColorPikerCB::GetSelectedColorValue(void)
{
int iSelectedItem=GetCurSel();
if(iSelectedItem==CB_ERR)
{
return(RGB(0,0,0));
}
return(GetItemData(iSelectedItem));
}
CString CColorPikerCB::GetSelectedColorName(void)
{
int iSelectItem=GetCurSel();
if(iSelectItem==CB_ERR)
{
return(m_sColorName=afxEmptyString);
}
GetLBText(iSelectItem,m_sColorName);
return(m_sColorName);
}
void CColorPikerCB::SetSelectedColorValue(COLORREF crClr)
{
int iItems=GetCount();
for (int iItem=0;iItem<iItems;iItem++)
{
if(crClr==GetItemData(iItem))
{
SetCurSel(iItem);
}
}
}
void CColorPikerCB::SetSelectedColorName(PCSTR cpColor)
{
int items=GetCount();
CString sColor;
for (int iitem=0;iitem<items;iitem++)
{
GetLBText(iitem,sColor);
if (!sColor.CompareNoCase(cpColor))
{
SetCurSel(iitem);
}
}
}
bool CColorPikerCB::RemoveColor(PCSTR cpColor)
{
int iItems=GetCount();
CString sColor;
bool bRemoved=false;
for (int iItem=0;iItem<iItems;iItem++)
{
GetLBText(iItem,sColor);
if (!sColor.CompareNoCase(cpColor))
{
DeleteString(iItem);
bRemoved=TRUE;
break;
}
}
return bRemoved;
}
bool CColorPikerCB::RemoveColor(COLORREF crClr)
{
int iItems=GetCount();
bool bRemoved=false;
for (int iItem=0;iItem<iItems;iItem++)
{
if (crClr==GetItemData(iItem))
{
DeleteString(iItem);
bRemoved=true;
break;
}
}
return bRemoved;
}
int CColorPikerCB::AddColor(PCSTR cpName,COLORREF crClr)
{
int iItem=-1;
iItem=InsertString(-1,cpName);
if(iItem!=LB_ERR)
SetItemData(iItem,crClr);
return iItem;
}
void CColorPikerCB::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct)
{
// TODO: Add your code to draw the specified item
static CString sColor;
CDC dcContext;
CRect rItemRect(lpDrawItemStruct->rcItem);
CRect rBlockRect(rItemRect);
CRect rTextRect(rBlockRect);
CBrush brFrameBrush;
int iFourthWidth=0;
int iItem=lpDrawItemStruct->itemID;
int iAction=lpDrawItemStruct->itemAction;
int iState=lpDrawItemStruct->itemState;
COLORREF crColor=0;
COLORREF crNormal=GetSysColor(COLOR_WINDOW);
COLORREF crSelected=GetSysColor(COLOR_HIGHLIGHT);
COLORREF crText=GetSysColor(COLOR_WINDOWTEXT);
if(!dcContext.Attach(lpDrawItemStruct->hDC))
return;
iFourthWidth=(rBlockRect.Width()/4);
brFrameBrush.CreateStockObject(BLACK_BRUSH);
if(iState&ODS_SELECTED)
{
dcContext.SetTextColor(0x00FFFFFF&~(crText));
dcContext.SetBkColor(crSelected);
dcContext.FillSolidRect(&rBlockRect,crSelected);
}
else
{
dcContext.SetTextColor(crText);
dcContext.SetBkColor(crNormal);
dcContext.FillSolidRect(&rBlockRect,crNormal);
}
if (iState&ODS_FOCUS)
{
dcContext.DrawFocusRect(&rItemRect);
}
rTextRect.left+=(iFourthWidth+2);
rTextRect.top+=2;
rBlockRect.DeflateRect(CSize(2,2));
rBlockRect.right=iFourthWidth;
if (iItem!=-1)
{
GetLBText(iItem,sColor);
if (iState&ODS_DISABLED)
{
crColor=GetSysColor(COLOR_INACTIVECAPTIONTEXT);
dcContext.SetTextColor(crColor);
}
else
crColor=GetItemData(iItem);
dcContext.SetBkMode(TRANSPARENT);
dcContext.TextOut(rTextRect.left,rTextRect.top,sColor);
dcContext.FillSolidRect(&rBlockRect,crColor);
dcContext.FrameRect(&rBlockRect,&brFrameBrush);
}
dcContext.Detach();
}