MFC的钢笔和刷子知识
编译VC++6.0测试通过,
chinanetboy制作,qq:44633197
1.MFC中的钢笔(Cpen)种类
PS_SOLID
//实心线笔
PS_DASH
//虚线笔
PS_DOT
//点线笔
PS_DASHDOT //虚点笔
PS_DASHDOTDOT
//虚线与点交替的笔
PS_NULL
//空笔
PS_INSIDEFRAME
//矩形的实长条笔
2.MFC中的笔刷(CBrush)种类
HS_BDIAGONAL
//45度斜线,从左下到右上
HS_FDIAGONAL
//45度斜线,从左上到右下
HS_DIAGCROSS
//45度斜线,双线交叉
HS_CROSS
//水平与垂直方格线
HS_HORIZONTAL
//水平横条线
HS_VERTICAL
//垂直竖条线
/***************************************************/
3.代码实现
首先建立一个MFC的应用程序,项目名为pen
3.1在penView.h的类定义之前添加4个static 数组
#endif // _MSC_VER > 1000
//定义钢笔名称指称数组
static char *szLineStyles[] = {
"PS_SOLID", "PS_DASH", "PS_DOT", "PS_DASHDOT",
"PS_DASHDOTDOT", "PS_NULL", "PS_INSIDEFRAME" };
//定义钢笔常量数组
static int nLineStyles[] = {
PS_SOLID, PS_DASH, PS_DOT, PS_DASHDOT,
PS_DASHDOTDOT, PS_NULL, PS_INSIDEFRAME };
//定义刷子名称数组
static char *szBrushStyles[] = {
"HS_BDIAGONAL", "HS_CROSS", "HS_DIAGCROSS",
"HS_FDIAGONAL", "HS_HORIZONTAL", "HS_VERTICAL" };
//定义刷子常量数组
static int nBrushStyles[] = {
HS_BDIAGONAL, HS_CROSS, HS_DIAGCROSS,
HS_FDIAGONAL, HS_HORIZONTAL, HS_VERTICAL };
3.2在菜单删除多余的菜单并添加新菜单项目
第2个一级菜单改为&Choose,并添加子菜单,删除其它的
ID:ID_Cpen
caption:C&Pen
ID:ID_CBrush
caption:C&Brush
3.3在类的声明penView.h的class CPenView 类添加两个private变量
private:
//用来保存用户的Choose菜单的2个子菜单的2选1的结果
int m_nOperationType;
3.4在类的构造函数中初始化成员变量都为0
CPenView::CPenView()
{
m_nOperationType = 0;
//约定:m_nOperationType ==0是选用钢笔,=1选用刷子
}
3.5添加一级菜单&Choose下面的两个子菜单的消息处理和外观代码控制
ID:ID_Cpen
caption:C&Pen
ID:ID_CBrush
caption:C&Brush
3.5.1先完成ID:ID_Cpen和ID:ID_CBrush的菜单外观选中标记
用类向导选择CPenView视图类的ID_Cpen,ID_CBrush的WM_COMMAND_UI消息,
3.5.2添加2个函数,向导自动生成内容如下:
//CPenView.h在消息映射声明
afx_msg void OnUpdateCBrush(CCmdUI* pCmdUI);
afx_msg void OnUpdateCpen(CCmdUI* pCmdUI);
...
DECLARE_MESSAGE_MAP()
//CPenView.cpp在消息映射定义
ON_UPDATE_COMMAND_UI(ID_CBrush, CBrush)
ON_UPDATE_COMMAND_UI(ID_Cpen, Cpen)
...
END_MESSAGE_MAP()
3.5.3完成两个菜单的外观消息处理
在类的CPenView.h手工添加函数声明
public:
void OnUpdateCpenAndCbrush(CCmdUI*);
在类的CPenView.cpp手工添加函数实现
void CPenView::OnUpdateCpenAndCbrush(CCmdUI* pCmdUI)
{
//通过当前菜单的choose下的子菜单序号与成员变量是否相等,知道用户是单击了哪一个菜单
pCmdUI->SetCheck( (int) pCmdUI->m_nIndex ==m_nOperationType );
}
//修改两个消息映射的处理函数都用OnUpdateCpenAndCbrush()函数来处理工科
ON_UPDATE_COMMAND_UI(ID_CBrush, CBrush)
ON_UPDATE_COMMAND_UI(ID_Cpen, Cpen)
//由上面变成下面的代码,并删除OnUpdateCBrush(),OnUpdateCpen()两个由类向导生成的函数
ON_UPDATE_COMMAND_UI(ID_CBrush, OnUpdateCpenAndCbrush)
ON_UPDATE_COMMAND_UI(ID_Cpen, OnUpdateCpenAndCbrush)
3.6完成下面两个子菜单的单击消息处理
ID:ID_Cpen
caption:C&Pen
ID:ID_CBrush
caption:C&Brush
分别先中ID_Cpen,ID_CBrush的COMMAND消息,分别添加两个函数,此用类向导自动生成如下
//CPenView.h自动生成的消息映射声明
afx_msg void OnCBrush();
afx_msg void OnCpen();
//CPenView.cpp自动生成的消息映射定义
ON_COMMAND(ID_CBrush, OnCBrush)
ON_COMMAND(ID_Cpen, OnCpen)
3.6.1建立同时可以处理上面两个菜单的单击事件的函数,
在类的CPenView.h声明中添加成员函数
public:
void OnCpenAndCbrush();
实现成员函数OnCpenAndCbrush代码
void CPenView::OnCpenAndCbrush()
{
m_nOperationType =LOWORD( GetCurrentMessage()->wParam - ID_Cpen );
InvalidateRect( NULL, TRUE );
UpdateWindow();
/*
把用户是单击哪一个菜单的结果存入类的private变量m_nOperationType
判断方式:GetCurrentMessage()->wParam//取当前消息的菜单数字ID,
如果是单击ID_Cpen,则ID_Cpen的单击消息ID - ID_Cpen的结果是0
如果是单击ID_CBrush,则ID_CBrush的单击消息ID - ID_Cpen的结果不是0,经过LOWORD()后变1
私有变量m_nOperationType的结果是0,表示单击ID_Cpen菜单,
私有变量m_nOperationType的结果是1,表示单击ID_CBrush菜单
这个菜单处理技巧我们要掌握它,MFC中的选项菜单我们用的非常多
*/
}
3.6.2把ID_CBrush,D_Cpen两个菜单的消息映射处理函数都指向OnCpenAndCbrush()
//CPenView.cpp自动生成的消息映射定义
ON_COMMAND(ID_CBrush, OnCBrush)
ON_COMMAND(ID_Cpen, OnCpen)
修改成如下,并删除OnCBrush(),OnCpen()两个由类向导生成的函数
ON_COMMAND(ID_CBrush, OnCpenAndCbrush)
ON_COMMAND(ID_Cpen, OnCpenAndCbrush)
3.7修改CPenView类的OnDraw()函数
//完整代码如下
void CPenView::OnDraw(CDC* pDC)
{
CPenDoc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
// TODO: add draw code for native data here
int i;
switch( m_nOperationType )
{
case 0://选用钢笔
//循环输出6种钢笔名称和5种长方形
for( i=0; i<7; i++ ){
//输出钢笔名字
pDC->TextOut( 10, 10 + i * 50,szLineStyles[i] );
//建立钢笔对象pen
CPen Pen( nLineStyles[i],1,RGB( 0, 0, 0 ) );
//保存原来的钢笔
CPen *pOldPen = pDC->SelectObject( &Pen );
// 画直线
pDC->MoveTo( 150, 17 + i * 50 );
pDC->LineTo( 300, 17 + i * 50 );
// 恢复到原来的钢笔
pDC->SelectObject( pOldPen );
}
break;
case 1: //选用刷子
//建立一个钢笔对象pen
CPen Pen( PS_INSIDEFRAME,1,RGB( 0, 0, 0 ) );
//保存原来的钢笔
CPen *pOldPen = pDC->SelectObject( &Pen );
//循环输出5种刷子名称和5种长方形
for( i=0; i<6; i++ ){
//输出钢笔名字
pDC->TextOut( 10, 23 + i * 55,szBrushStyles[i] );
//初始化刷子类型
CBrush Brush( nBrushStyles[i], RGB( 0, 0, 0 ) );
//刷子绑定到pDC
CBrush *pOldBrush = pDC->SelectObject( &Brush );
//建立一个矩形长方形对象
CRect Rect( 150, 10 + i * 55, 500, 60 + i * 55 );
//
pDC->Rectangle( Rect );
//刷子显示到客户区
pDC->SelectObject( pOldBrush );
}
// 恢复到原来的刷子
pDC->SelectObject( pOldPen );
break;
}
}