MFC自绘控件
一、MFC自绘控件
要了解Windows下的绘图操作,实现界面的美化,就必须了解MFC封装的设备环境类 和 图形对象类。
1.1 设备环境类
MFC中的CDC类封装了Windwos API中的大部分的画图函数。CDC的常用的操作函数包括:
*颜色和颜色调色板函数
绘图属性函数
映射函数
坐标函数
*区域函数
剪切函数
线输出函数
简单绘图函数
椭圆和多边形函数
*位图函数
文本函数
*字体函数
打印机跳离函数
滚动函数
注意:其中的标注*项会用到 相应的图形对象类!
1.2 图形对象类
设备环境类 不足以包含绘图功能所需的所有绘图特征,windows还有一些图像对象用来储存绘图特征:这些附件的功能包括从划线的宽度 和 颜色,到画文本时所用的字体。图形对象类封装了所有6个图形对象:
MFC类(6个图形对象) |
图形对象句柄 |
图形对象的目的 |
CBitmap |
HBITMAP |
内存中的位图 |
CBrush |
HBRUSH |
画刷特性:填充某个图形时所使用的颜色和模式 |
CFont |
HFONT |
字体特性:写文本时所使用的字体 |
CPalette |
HPALETTE |
调色板颜色 |
CPen |
HPEN |
画笔特性:画轮廓时所使用的的线的粗细 |
CRgn |
HRGN |
区域特效:包括定义它的点 |
例、定义一个单文档程序
BOOL CTestButtonView::PreCreateWindow(CREATESTRUCT& cs)
{
// TODO: Modify the Window class or styles here by modifying
// the CREATESTRUCT cs
//设置画刷颜色
m_backBrush.CreateSolidBrush(RGB(100,100,100));
//当主窗口不是由CFrameWnd派生而来,而是由CWnd派生而来的时候,
//在创建窗口的时候,必须注册自己的窗口类WNDCLASS
cs.lpszClass = AfxRegisterWndClass(0,0,m_backBrush,0);
return CView::PreCreateWindow(cs);
}
int CTestButtonView::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (CView::OnCreate(lpCreateStruct) == -1)
return -1;
// TODO: Add your specialized creation code here
//创建字体
m_font.CreatePointFont(240,_T("Impact"));//字体高度,字体名称
return 0;
}
void CTestButtonView::OnDraw(CDC* pDC)
{
CTestButtonDoc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
if (!pDoc)
return;
// TODO: add draw code for native data here
//绘制按钮框架
pDC->DrawFrameControl(CRect(50,50,250,250), DFC_BUTTON, DFCS_BUTTONPUSH);
pDC->SelectObject(&m_font);
//输出文字
pDC->SetBkColor(RGB(200,200,200));
pDC->TextOut(100,100,_T("Hello"));
}
二、自绘控件途径
1、如何以合法的手段来达到美化界面的效果?一般美化界面的方法包括:
1.1 利用Windows的消息机制,截获有用的Windows的消息。通过MFC的消息映射(Message Mapping)和反射(Message Reflecting)机制,在Windows准备或者正在绘制该元素时,偷偷修改它的状态和行为,譬如:让按钮的边框为红色;
在父窗口里,截获自身的或者由子元素(包括控件和菜单等元素)传递的关于界面绘制的消息;
1.2 利用MFC类的虚函数机制,重载有用的虚函数。在MFC框架调用该函数的时候,重新定义它的状态和行为;
子类化子元素,或者为子元素准备一个新的类(一般来说该类必须继承于MFC封装的某个标准类,如:CButton)。在该子元素里,截获自身的或者从父窗口反射过来的关于界面绘制的消息。譬如:用户可以创建一个CXPButton类来实现具有XP风格的按钮,CXPButton继承于CButton。
2、对于应用程序,使用CXPButton类的途径相对于对话框窗口和普通窗口分成两种:
2.1 对话框窗口中,直接将原先绑定按钮的CButton类替换成CXPButton类,或者在添加控件变量时直接指定Control类型为CXPButton
2.2 在普通窗口中,直接创建一个CXPButton类对象,然后在OnCreate()中调用CXPButton的Create方法;
三、具体实施
3.1 利用Windows的消息机制;
使用MFC类的既有函数来美化界面,其功能是有限的。既然Windows是通过消息机制进行通讯的,那么我们就可以通过截获一些有用的消息来美化我们的界面,以下是一些有用的Windows消息:
WM_PAINT
WM_ERASEBKGND
WM_CTLCOLOR*
WM_DRAWITEM*
WM_MEASUREITEM*
NM_CUSTOMDRAW*
注意,标注*的消息是子元素发送给父窗口的通知消息,其它的为窗口或者子元素自身的消息。
3.1.1 WM_PAINT消息
3.1.2 WM_ERASEBKGND消息
3.1.3 WM_CTLCOLOR消息
3.1.4 WM_DRAWITEM消息
3.1.5 WM_MEASUREITEM消息
3.1.6 NM_CUSTOMDRAW消息
3.2 利用MFC类的虚函数机制,准备一个新的类,重载有用的虚函数