MFC4.钢笔和刷子

来源:互联网 发布:手持式数据终端器 编辑:程序博客网 时间:2024/04/27 16:37
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;
        }
}