📄 画图软件开发实例.txt
字号:
【标 题】:VC 画图软件开发实例(源代码+图片)
【关键字】:VC
【来 源】:http://blog.csdn.net/yxz149/archive/2006/11/25/1414324.aspx
VC 画图软件开发实例(源代码+图片)
第三章画图
叶新州 中山大学 计算机应用软件
作业:
1.(绘图)编写一个交互式绘图程序。要求:
l 可以选择图形的种类(直线、折线、矩形、[椭]圆、多边形及对应的填充图形)、绘图颜色(使用颜色公用对话框)、笔的粗细和风格、填充模式(包括填充颜色[与图案])、背景模式与颜色;
l 可以根据用户的选择,用鼠标和方向键来绘制各种图形;
l 可以动态拖动绘图,并显示鼠标当前位置坐标以及拖动矩形的大小;
l [可以用选择的字体、大小和颜色(使用字体公用对话框)在指定的位置按指定的对齐方式来输出文字串;]
l 可以清屏(调用CWnd类的函数Invalidate()或用背景色画填充客户区矩形)、可以按Esc键取消正在进行的绘图操作;
l 各种操作和选择必须有对应的菜单项,最好有对应的工具条按钮和加速键。
解决:
一、 基本思路:
本程序按照功能模块划分,主要分为画直线、折线、矩形、椭圆、多边形等,工具方面提供了颜色、画刷、画笔等设置。
程序用例图如下
二、 主要类/结构体,及其作用
1)CAlexDrawView,是画图操作的主要类
// AlexDrawView.h : CAlexDrawView 类的接口
//
#pragma once
#include "MainFrm.h"
#include "afxwin.h"
#include "PrintFontDialog.h"
#define MAX_POLYRECT_POINTS 255
class CAlexDrawView : public CView
{
protected: // 仅从序列化创建
CAlexDrawView();
DECLARE_DYNCREATE(CAlexDrawView)
// 属性
public:
CAlexDrawDoc* GetDocument() const;
// 操作
public:
// 重写
public:
virtual void OnDraw(CDC* pDC); // 重写以绘制该视图
virtual BOOL PreCreateWindow(CREATESTRUCT& cs);
protected:
virtual BOOL OnPreparePrinting(CPrintInfo* pInfo);
virtual void OnBeginPrinting(CDC* pDC, CPrintInfo* pInfo);
virtual void OnEndPrinting(CDC* pDC, CPrintInfo* pInfo);
// 实现
public:
virtual ~CAlexDrawView();
#ifdef _DEBUG
virtual void AssertValid() const;
virtual void Dump(CDumpContext& dc) const;
#endif
protected:
// 生成的消息映射函数
protected:
DECLARE_MESSAGE_MAP()
public:
afx_msg void OnDrawline();
public:
afx_msg void OnDrawPolyLine();
public:
afx_msg void OnDrawRectangle();
public:
afx_msg void OnDrawEllipse();
public:
afx_msg void OnChooseColor();
public:
afx_msg void OnBkGround();
public:
afx_msg void OnClear();
public:
afx_msg void OnChooseLine();
public:
afx_msg void OnFill();
public:
afx_msg void OnMode();
public:
afx_msg void OnDrawToolBar();
public:
afx_msg void OnPrintFont();
public:
BOOL m_bIsCheked;
public:
afx_msg void OnPolyRect();
public:
afx_msg void OnMouseMove(UINT nFlags, CPoint point);
public:
//CMainFrame *pMainFrame;
CToolBar *m_wndToolBar;
CStatusBar *m_wndStatusBar;
CMenu *m_pMenu;
CPrintFontDialog *m_PrintFontDlg;
BOOL m_bIsDrawLine,m_bIsDrawPolyLine,m_bIsDrawRectangle,m_bIsDrawEllipse,m_bIsDrawPolyRect,m_bIsPrintFont;
public:
CDC *m_pDC;
CPen m_Pen,*m_oldPen;
CBrush m_Brush,*m_oldBrush;
COLORREF m_PenColor;
COLORREF m_BkColor;
/****************************************************/
CBitmap *m_pBitmap; //是用于画刷m_Brush的位图。
HBITMAP hBmp;
BITMAP bs;
/****************************************************/
UINT m_PenStyle;
int m_PenWidth;
LineDrawer m_Line; //直线、折线公用的信息
AlexRect m_RectangleAndEllipse; //矩形信息
int m_nPolyRectPointCount; //闭合不规则多边形定点个数
CPoint m_Points[MAX_POLYRECT_POINTS]; //闭合不规则多边形顶点
public:
afx_msg void OnLButtonDown(UINT nFlags, CPoint point);
public:
afx_msg void OnLButtonUp(UINT nFlags, CPoint point);
public:
afx_msg void OnRButtonDown(UINT nFlags, CPoint point);
public:
void DrawLineOfOnLButtonUp(UINT nFlags, CPoint point);
public:
void DrawPolyLineAndPolyRectOfOnLButtonUp(UINT nFlags, CPoint point);
public:
void DrawLineOfOnLButtonDown(UINT nFlags, CPoint point);
public:
void DrawPolyLineAndPolyRectOfOnLButtonDown(UINT nFlags, CPoint point);
public:
void DrawLineAndPloyLineAndPolyRectOfOnMouseMove(UINT nFlags, CPoint point);
public:
void DrawRectangleAndEllipseOfOnMouseMove(UINT nFlags, CPoint point);
public:
void DrawRectangleAndEllipseOfOnLButtonDown(UINT nFlags, CPoint point);
public:
void DrawRectangleAndEllipseOfOnLButtonUp(UINT nFlags, CPoint point);
};
#ifndef _DEBUG // AlexDrawView.cpp 中的调试版本
inline CAlexDrawDoc* CAlexDrawView::GetDocument() const
{ return reinterpret_cast<CAlexDrawDoc*>(m_pDocument); }
#endif
2)CLineDialog:画笔设置类
#pragma once
#include "afxwin.h"
// CLineDialog 对话框
class CLineDialog : public CDialog
{
DECLARE_DYNAMIC(CLineDialog)
public:
CLineDialog(CWnd* pParent = NULL); // 标准构造函数
virtual ~CLineDialog();
// 对话框数据
enum { IDD = IDD_DIALOG1 };
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV 支持
DECLARE_MESSAGE_MAP()
public:
int m_nLineWidth;
public:
afx_msg void OnBnClickedOk();
public:
public:
virtual BOOL OnInitDialog(void) ;
public:
afx_msg void OnVScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar);
public:
CButton m_ctrlStyle1;
public:
int m_nStyle;
public:
afx_msg void OnBnClickedRadio1();
public:
afx_msg void OnBnClickedRadio2();
public:
afx_msg void OnBnClickedRadio3();
public:
afx_msg void OnBnClickedRadio4();
};
3)CPrintFontDialog:输出字体
#pragma once
// CPrintFontDialog 对话框
class CPrintFontDialog : public CDialog
{
DECLARE_DYNAMIC(CPrintFontDialog)
public:
CPrintFontDialog(CWnd* pParent = NULL); // 标准构造函数
virtual ~CPrintFontDialog();
// 对话框数据
enum { IDD = IDD_DIALOG3 };
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV 支持
DECLARE_MESSAGE_MAP()
public:
CString m_strContent;
public:
afx_msg void OnBnClickedOk();
public:
virtual BOOL OnInitDialog();
};
4)CSetBrushDialog:设置画刷
#pragma once
// CSetBrushDialog 对话框
class CSetBrushDialog : public CDialog
{
DECLARE_DYNAMIC(CSetBrushDialog)
public:
CSetBrushDialog(CWnd* pParent = NULL); // 标准构造函数
virtual ~CSetBrushDialog();
// 对话框数据
enum { IDD = IDD_DIALOG2 };
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV 支持
DECLARE_MESSAGE_MAP()
public:
afx_msg void OnBnClickedOk();
public:
afx_msg void OnBnClickedRadio1();
public:
afx_msg void OnBnClickedRadio3();
public:
afx_msg void OnBnClickedRadio4();
public:
afx_msg void OnBnClickedRadio5();
public:
afx_msg void OnBnClickedRadio6();
public:
afx_msg void OnBnClickedRadio7();
public:
afx_msg void OnBnClickedRadio2();
public:
afx_msg void OnBnClickedButton_SetDefault();
public:
afx_msg void OnBnClickedCancel();
public:
// 表示笔刷的类型,其中图形为-1, -2为默认,即普通模式
int m_BrushType;
public:
// 图形方式的笔刷时,表示图形是否载入
BOOL m_bIsPictureLoaded;
HBITMAP hBmp;
BITMAP bs;
public:
afx_msg void OnBnClickedButton_LoadPicture();
public:
CString m_strPicFileName;
public:
afx_msg HBRUSH OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor);
public:
void DrawPictureFromExternalPicFile(void);
public:
afx_msg void OnActivate(UINT nState, CWnd* pWndOther, BOOL bMinimized);
};
5)主要结构体:
typedef struct tagLineDrawer //定义一个线(包括直线、折线)的结构体
{
CPen *pen; //画此直线的笔指针
BOOL bIsDown; //表明鼠标左键是否按下
BOOL bIsErase;
int sPointX,sPointY,ePointX,ePointY;
}LineDrawer;
typedef struct tagAlexRect //定义一个矩形的存储信息,可以用于表示椭圆和矩形
{
CBrush *brush; //定义指向一个填充刷子的指针
CPoint sp,ep; //sp,ep分别表示起始点、终点
BOOL bIsDown; //表明鼠标左键是否按下
BOOL bIsErase;
}AlexRect;
三、 主要程序清单:
由于程序较长,所以没有在此列出。可参考具体源代码
四、 运行效果截图:
运行效果一
运行效果二
运行效果四
五、 总结
总得来说,通过写这个程序收获不少,其中就是进一步熟悉了MFC 画图的方法,一些窗口控件的使用方法。现在总结一些认为比较实用的代码:
1) 设置ToolBar中的按钮状态(选中/未选中)
m_wndToolBar->GetToolBarCtrl().CheckButton(ID_DRAWLINE,FALSE);
2) 从外部位图创建笔刷
hBmp = (HBITMAP)LoadImage(NULL, dlg.m_strPicFileName, IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE | LR_DEFAULTCOLOR | LR_DEFAULTSIZE);
//GetObject(hBmp, sizeof(bs), &bs);
m_pBitmap=CBitmap::FromHandle(hBmp); //注意这句
m_Brush.DeleteObject();
m_Brush.CreateObject();
m_Brush.CreatePatternBrush(m_pBitmap);
3) 设置状态栏显示信息:
CMainFrame *pMainFrame=(CMainFrame*)AfxGetApp()->m_pMainWnd;
CStatusBar *m_wndStatusBar=&pMainFrame->m_wndStatusBar;
CString str1,str2;
str1.Format(L"x:%d",point.x);
str2.Format(L"y:%d",point.y);
m_wndStatusBar->SetPaneText(1,str1);
m_wndStatusBar->SetPaneText(2,str2);
4) XOR方式动态画图(直线)
void CAlexDrawView::DrawLineAndPloyLineAndPolyRectOfOnMouseMove(UINT nFlags, CPoint point)
{
if (m_Line.bIsDown)
{
CDC* pDC=GetDC();
CPen GrayPen;
GrayPen.CreatePen(m_PenStyle,m_PenWidth,RGB(128,128,128));
pDC->SelectObject(&GrayPen);
pDC->SetROP2(R2_XORPEN);
if (m_Line.bIsErase)
{
pDC->MoveTo(m_Line.sPointX,m_Line.sPointY);
pDC->LineTo(point.x,point.y);
pDC->MoveTo(m_Line.sPointX,m_Line.sPointY);
pDC->LineTo(m_Line.ePointX,m_Line.ePointY);
}
else
{
m_Line.bIsErase=TRUE;
}
m_Line.ePointX=point.x;
m_Line.ePointY=point.y;
ReleaseDC(pDC);
}
}
5) 缩放式显示外部位图(实现类似在OnDraw函数中的效果),三个函数,不可少
HBRUSH CSetBrushDialog::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor) //此事件是窗口控件重画时候响应
{
HBRUSH hbr = CDialog::OnCtlColor(pDC, pWnd, nCtlColor);
// TODO: 在此更改DC 的任何属性
// TODO: 如果默认的不是所需画笔,则返回另一个画笔
if (m_bIsPictureLoaded)
{
DrawPictureFromExternalPicFile(); //当画面被擦除是刷新
}
return hbr;
}
void CSetBrushDialog::DrawPictureFromExternalPicFile()
{
//************************* 从外部文件中显示位图*******************************************************//
if (!m_bIsPictureLoaded)
{
hBmp = (HBITMAP)LoadImage(NULL, m_strPicFileName, IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE | LR_DEFAULTCOLOR | LR_DEFAULTSIZE);
GetObject(hBmp, sizeof(bs), &bs);
}
CDC dc, *pDC = GetDC();
dc.CreateCompatibleDC(pDC);
::SelectObject(dc.GetSafeHdc(), hBmp);
pDC->SetStretchBltMode(COLORONCOLOR); //设置缩放模式
pDC->StretchBlt(15, 100, 165, 145, &dc, 0, 0,bs.bmWidth,bs.bmHeight,SRCCOPY); //绘制经过缩放的图片,前面
ReleaseDC(&dc);
ReleaseDC(pDC);
//************************* End of 从外部文件中显示位图***********************************************//
}
void CSetBrushDialog::OnActivate(UINT nState, CWnd* pWndOther, BOOL bMinimized)
{
CDialog::OnActivate(nState, pWndOther, bMinimized);
DrawPictureFromExternalPicFile();
}
6) SpinButtonCtrl的用法
BOOL CLineDialog::OnInitDialog(void)
{
CDialog::OnInitDialog();
CSpinButtonCtrl *pSpin=(CSpinButtonCtrl*)GetDlgItem(IDC_SPIN1);
pSpin->SetRange(1,100);
m_ctrlStyle1.SetCheck(TRUE);
return TRUE;
}
void CLineDialog::OnVScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar)
{
// TODO: 在此添加消息处理程序代码和/或调用默认值
if (nSBCode==SB_ENDSCROLL)
return;
if (pScrollBar->GetDlgCtrlID()==IDC_SPIN1)
{
CString str;
str.Format(L"%d",nPos);
GetDlgItem(IDC_EDIT1)->SetWindowText(str);
}
CDialog::OnVScroll(nSBCode, nPos, pScrollBar);
}
说明:这个程序是老师布置的作业,程序的主要功能已经实现,还有部分功能未在本版本中实现。
程序的主要缺点:没有实现屏幕刷新是重显屏幕绘图,这个主要是没有找到好的算法,所以没有在这个版本中实现。另外程序的图标做得实在是**。还有本文档其实也不是什么文档,只是一些总结。
附上源代码(由于CSDN不能上传rar文件,所以改成了jpg文件,右键单击可下载):点击下载
VC下的基本字处理:【上一篇】
strcspn ( )【C语言库函数源代码】:【下一篇】
【相关文章】
VC下的基本字处理
VC编程规范
VC杂项编程
演练VC中的COMMON一族
profiling in vc6 ... 没vtune....vc7 玩不了
VC中".pch"是什么文件,没有.pch文件怎么办
VC中一些保存,读取应用程序数据的方式
MVC与三层架构的研讨
About ! appfuse-springmvc
About SpringMVC ! other
【相关评论】
没有相关评论
【发表评论】
姓名:
邮件:
随机码*:
评论*:
| 首 页 | 版权声明 | 联系我们 | 网站地图 |
CopyRight ? 2004-2006 软讯网络 All Rigths Reserved.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -