当前位置:编程学习 > VC++ >>

MFC学习笔记之绘图控制

MFC中进行与绘图相关的控制,首先先为VIEW类添加一个成员变量 m_nDrawType,用来指定要画的图形 ,增加相应的菜单项用来绘制 点 直线 矩形 和 椭圆 在菜单项的响应函数中写下面的代码:

view plain
void CGraphicView::OnDot()  

    // TODO: Add your command handler code here 
    m_nDrawType = 1; 

 
void CGraphicView::OnLine()  

    // TODO: Add your command handler code here 
    m_nDrawType = 2; 

 
void CGraphicView::OnRectangle()  

    // TODO: Add your command handler code here 
    m_nDrawType = 3; 

 
void CGraphicView::OnEllipse()  

    // TODO: Add your command handler code here 
    m_nDrawType = 4; 

知道每种图形相应的序号,然后就要绘图,先是相应LBUTTONDOWM消息,记录下当前点,然后再响应 LBUTTONUP消息 进行绘图操作,代码如下:

view plain
void CGraphicView::OnLButtonDown(UINT nFlags, CPoint point)  

    // TODO: Add your message handler code here and/or call default 
    m_ptOrigin = point; 
    CView::OnLButtonDown(nFlags, point); 

 
void CGraphicView::OnLButtonUp(UINT nFlags, CPoint point)  

    // TODO: Add your message handler code here and/or call default 
    CClientDC dc(this); 
     
    CPen pen(m_nLineStyle,m_nLineWidth,m_clr); 
    dc.SelectObject(&pen); 
     
    CBrush *pBrush=CBrush::FromHandle((HBRUSH)GetStockObject(NULL_BRUSH)); 
    dc.SelectObject(pBrush); 
     
    switch(m_nDrawType) 
    { 
    case 1: 
        dc.SetPixel(point,m_clr); 
        break; 
    case 2: 
        dc.MoveTo(m_ptOrigin); 
        dc.LineTo(point); 
        break; 
    case 3: 
        dc.Rectangle(CRect(m_ptOrigin,point)); 
        break; 
    case 4: 
        dc.Ellipse(CRect(m_ptOrigin,point)); 
        break; 
    }    
    CView::OnLButtonUp(nFlags, point); 

其中m_pOrigin 是CPoint类的对象,变量 m_nLineStyle m_nLineWidth 在后面会用到,分别是线的样式和线的宽度。

为了在绘图过程中用透明画刷填充图形内部,所以用GetSocokObect()函数

view plain
HGDIOBJ GetStockObject(  int fnObject   // stock object type); 
关于它的参数可以在MSDN中查到,他的返回值是HGDIOBJ类型的,我们需要将他转换为HRUSH类型的 因为我们要调用 CBrush类的一个静态成员函数FromHandle将画刷句柄转换为相应的画刷指针。

接下来要创建一个设置绘画相关属性的对话框 该对话框最终的样子是下面这样的:

 \

相应的需要创建一个新的编辑框的类,这里类名是 CSettingDlg

现在先从创建线宽这个编辑框开始,编辑框ID设为 IDC_LINE_WIDTH ,然后在菜单项中增加一个设置的菜单项,在响应该菜单项的函数中显示该对话框,为了将用户输入的线宽保存下来,当然要为该编辑框关联一个变量 UINT类型的 m_nLineWidth 然后在用户输入完线宽按OK后将该值保存到VIEW类的m_nLineWidth中,为了用户再次打开的时候可以看到自己上次设的线宽是多少,我们将VIEW类中m_nLineWidth的值赋给对话框的m_nLineWidth ,下面是VIEW类的设置菜单项的响应函数:

view plain
void CGraphicView::OnSetting()  

    CSettingDlg dlg; 
    dlg.m_nLineWidth = m_nLineWidth; 
    dlg.m_nLineStyle=m_nLineStyle; 
    dlg.m_clr = m_clr; 
    if(IDOK==dlg.DoModal()) 
    { 
        m_nLineWidth = dlg.m_nLineWidth; 
        m_nLineStyle = dlg.m_nLineStyle; 
    } 

里面还有其他变量的赋值操作,在下面会说到。

当我们得到用户给定的线宽后,在LBUTTONUP响应函数中,就要将画笔对象的线宽参数改为m_nLineWidth了,这样就可以了。

现在再添加一个设置线形的组框,在其中添加三个单选按钮,标题如上图所示。我们在MFC APPWizard中要为单选框关联变量时,并没有看到他们的ID,这是因为在一个组框中的单选框,要将第一个单选按钮的属性中的Groud勾上,这样就可以找到第一个单选按钮的ID了,为它关联一个变量 m_nLineStyle,可以看到在对话框的构造函数中,它被初始化为-1了,当我们选中第一个单选按钮的时候,它的值是0,以此类推。和上面的线宽的一样,也是要让VIEW类保存用户选择的线型。

这里要再说一个知识点,就是画笔的属性比如 PS_SOLID PS_DASH PS_DOT 这些都是在MFC底层代码中定义好的一些常量,我们可以通过在CPEN类的对象构造函数的相应属性,点击右键 然后GO to Definition of... 去看到那些画笔样式的定义。

view plain
/* Pen Styles */ 
#define PS_SOLID            0 
#define PS_DASH             1       /* -------  */ 
#define PS_DOT              2       /* .......  */ 
#define PS_DASHDOT          3       /* _._._._  */ 
#define PS_DASHDOTDOT       4       /* _.._.._  */ 
#define PS_NULL             5 
#define PS_INSIDEFRAME      6 
#define PS_USERSTYLE        7 
#define PS_ALTERNATE        8 
#define PS_STYLE_MASK       0x0000000F 
在这里我们看到,实线、虚线、点线的值和它们所对应的单选按钮的值是一样的,当然这里是故意这么排列的,实际编程中应该先判断值,然后再用相应的画笔样式去构造画笔。

下面要创建一个颜色对话框,样子就是我们在绘图中看到的那个,自己要写的话,很麻烦,MFC为我们提供了一个类:CColorDialog ,可以很方便地创建一个颜色对话框。

在菜单项中添加颜色选项,然后在VIEW类的响应函数中创建该对话框。下面我们要做的事就是保存用户选择的颜色。在CColorDialog类中有一个CHOOSECOLOR结构体类型的成员变量 m_cc

view plain
typedef struct tagCHOOSECOLOR { 
    DWORD lStructSize; 
    HWND hwndOwner; 
    HINSTANCE hInstance; 
    COLORREF *lpCustColors; 
    DWORD Flags; 
    LPARAM lCustData; 
    LPCCHOOKPROC lpfnHook; 
    LPCTSTR lpTemplateName; 
} CHOO

补充:软件开发 , Vc ,
CopyRight © 2012 站长网 编程知识问答 www.zzzyk.com All Rights Reserved
部份技术文章来自网络,