?? 畫圖軟件開發實例.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 + -