visual c++ windows programming

35
Visual C++ Windows Programming 第第第 第第第第第第

Upload: misty

Post on 14-Jan-2016

77 views

Category:

Documents


4 download

DESCRIPTION

Visual C++ Windows Programming. 第五章 基本繪圖原理. 大綱. Windows 的基本繪圖原理 基本繪圖函式. Windows 的基本繪圖原理. 繪圖裝置介面 (GDI) 在視窗介面下,資料輸出的方式,相較於文字模式是較為複雜的,但也更具彈性且較多變。在視窗介面下顯示的所有資料,都被視為圖形,不論資料看起來是線段、圖形或者文字。 - PowerPoint PPT Presentation

TRANSCRIPT

Page 1: Visual C++ Windows Programming

Visual C++ Windows Programming

第五章 基本繪圖原理

Page 2: Visual C++ Windows Programming

大綱• Windows 的基本繪圖原理• 基本繪圖函式

Page 3: Visual C++ Windows Programming

Windows 的基本繪圖原理• 繪圖裝置介面 (GDI)

– 在視窗介面下,資料輸出的方式,相較於文字模式是較為複雜的,但也更具彈性且較多變。在視窗介面下顯示的所有資料,都被視為圖形,不論資料看起來是線段、圖形或者文字。

– 在視窗程式裡,資料輸出均透過繪圖裝置介面 (graphics device interface; GDI) 來完成,由於運用 GDI 函式的關係,使得程式設計師只要運用相同的函式,就可以將資料輸出到不同的裝置上。換句話說,對於程式而言,將資料顯示在螢幕上,與將資料輸出到印表機的方法是一樣的。

Page 4: Visual C++ Windows Programming

應用程式

GDI

印表機 螢幕

印表機驅動程式 螢幕驅動程式

Page 5: Visual C++ Windows Programming

Windows 的基本繪圖原理 ( 續 )

• 裝置內文 (DC)– 當我們想要在視窗的工作區中繪製圖案,或者將工作區

中的資料列印出來時,都必須先獲得一個裝置內文 (device context; DC) 。

– 裝置 (device) 泛指各種與資料輸出有關的設備,例如:螢幕,印表機等,以及各種特定格式的檔案,如 BMP 圖檔。

– 所謂的內文 (context) ,是指將輸出於各種裝置的資料。當你需要將你建立的資料輸出至裝置時,就必須為這個裝置準備一個 DC ,以便儲存欲輸出的資料。而這些資料就是使用 GDI 函數繪圖的結果。

Page 6: Visual C++ Windows Programming

Windows 的基本繪圖原理 ( 續 )

– 裝置內文是一個用以溝通程式與裝置的媒介。– 不論是要在視窗客戶區顯示繪圖 , 或是將圖輸出到印表

機裡印出來 , 所需要做的就是為那個裝置產生一個 DC,然後利用 GDI 函數繪製圖形 . 透過 GDI 函數與 DC 的協助 , 可以讓我們不論將資料輸出到那個裝置 , 都使用相同的方法 .

• 顏色的定義• RGB 巨集• (0,0,0): 黑色 , (255,255,255): 白色• COLORREF color = RGB(255, 0, 0);

Page 7: Visual C++ Windows Programming

Windows 的基本繪圖原理 ( 續 )

• MFC 的 GDI Classes (CGdiObject)– CBitmap :用以建立操作點陣圖的物件。– CPen :用於建立操作畫筆的物件。– CBrush :用於建立操作畫刷的物件。– CFont :用於建立操作文字的物件。– CRgn :用於建立繪製圖形的物件。– CPalette :用於建立調色盤的物件。

Page 8: Visual C++ Windows Programming

Windows 的基本繪圖原理 ( 續 )

• MFC 的 DC Classes (CDC)– CClientDC :用於將資料輸出至視窗工作區。– CWindowDC :用於將資料輸出至視窗中,

包含工作區以外的區域。– CPaintDC :用於輸出回應 WM_PAINT 訊

息的資料。– CMetaFileDC :用於將資料輸出至特殊格式

的檔案中。

Page 9: Visual C++ Windows Programming

GDI's

DC's

Page 10: Visual C++ Windows Programming

基本繪圖函式• 畫點 (point) 函式

COLORREF CDC::SetPixel(int x, int y, COLORREF color);COLORREF CDC::SetPixel(POINT point, COLORREF color);

COLORREF CDC::GetPixel(int x, int y) const;COLORREF CDC::GetPixel(POINT point) const;

virtual BOOL CDC::PtVisible(int x, int y) const;virtual BOOL CDC::PtVisible(POINT point) const;// 如果此像點恰好被其它視窗遮住就看不到了 .

• 畫線 (line) 函式BOOL CDC::MoveTo(int x, int y);BOOL CDC::MoveTo(POINT point);

BOOL CDC::LineTo(int x, int y);BOOL CDC::LineTo(POINT point);

Page 11: Visual C++ Windows Programming

基本繪圖函式 ( 續 )

• 畫弧 (arc) 函式與畫鐘 (chord) 函式BOOL CDC::Arc(int x1, int y1, int x2, int y2, int x3, int y3, in

t x4, int y4);

BOOL CDC::Arc(LPCRECT r, POINT Start, POINT End);

BOOL CDC::AngleArc(int x, int y, int radius, float startAngle, float sweepAngle);

BOOL CDC::Chord(int x1, int y1, int x2, int y2, int x3, int y3, int x4, int y4);

BOOL CDC::Chord(LPCRECT r, POINT Start, POINT End);

• 畫餅 (pie) 函式BOOL CDC::Pie(int x1, int y1, int x2, int y2, int x3, int y3, in

t x4, int y4);

BOOL CDC::Pie(LPCRECT r, POINT Start, POINT End);

Page 12: Visual C++ Windows Programming

(x1,y1)

(x2,y2)

(x3,y3) (x4,y4)

Arc

AngleArc

(x,y)radius startAngle

sweepAngle

(x1,y1)

(x2,y2)

(x3,y3) (x4,y4)

Chord

(x1,y1)

(x2,y2)

(x3,y3) (x4,y4)

Pie

Page 13: Visual C++ Windows Programming

基本繪圖函式 ( 續 )

• 畫橢圓 (ellipses) 函式BOOL CDC::Ellipses(int x1, int y1, int x2, int y2);BOOL CDC::Ellipses(LPCRECT rect);

• 畫矩形 (rectangle) 函式BOOL CDC::Rectangle(int x1, int y1, int x2, int y2);BOOL CDC::Rectangle(LPCRECT rect);

void CDC::FrameRect(LPCRECT lpRect, CBrush *pBrush);

void CDC::InvertRect(LPCRECT lpRect);// 不會畫出任何東西 , 只是把指定矩形中所有像點都作一次 NOT 運算而已 .

BOOL CDC::RoundRect(int x1, int y1, int x2, int y2, int x3, int y3);

BOOL CDC::RoundRect(LPCRECT lpRect, POINT point);

BOOL CDC::RectVisible(LPCRECT rect) const;// 只要有一丁點露出來 , 就是T

Page 14: Visual C++ Windows Programming

基本繪圖函式 ( 續 )

• 畫多邊形 (polygon) 函式BOOL CDC::Polygon(LPPOINT lpPoints, int nCount);

// 多邊形BOOL CDC::Polyline(LPPOINT lpPoints, int nCount);

// 不會封閉BOOL CDC::PolyPolygon(LPPOINT lpPoints, LPINT lpPolyCounts, int

nCount);

// 好幾個多邊形BOOL CDC::PolylineTo(const POINT *lpPoints, int nCount);

// 類似 Polyline, 但會改變游標之值 , 像是作了一大串的 LineTo

BOOL CDC::PolyBezier(const POINT *lpPoints, int nCount);

Page 15: Visual C++ Windows Programming

物件 Collection

• CArray 樣板類別– 你可以用這個樣板將任何物件存在 array 內 ,

讓 array 可以視需要自動加大 .

CArray<ObjectType, ObjectType&> anArray

要存放的物件型態 成員函式的引數型態

Page 16: Visual C++ Windows Programming

Object1

Object2

Object3

Object4

Object5

Object6

Obj A

SetSize(5)

定義初始大小

自動增加

Index

0

1

2

3

4

5

6

GetAt(2)傳回物件

Add(Obj A)

存放物件

Page 17: Visual C++ Windows Programming

CList<ObjectType, ObjectType&> aList;

Object1

Object2

Object3

Object4

Obj B

Obj AAddHead(ObjA)

存放物件

傳回型態為 Position

的值

AddTail(ObjB)

大小的增加

是自動的

GetNext(aPos)

aPos

Page 18: Visual C++ Windows Programming

CMap<KeyType, KeyType&,ObjectType, ObjectType&> aMap;

Key1 Object1

Key2 Object2

Key3 Object3

Key4 Object4

aMap[Key2]=Object2

LookUp(Key3,AnObject)

Page 19: Visual C++ Windows Programming

#include <afxwin.h>#include <afxtempl.h>#include <afxext.h>#include "resource.h"

class CGObject : public CObject {// 儲存形狀物件的類別 , 衍生自 CObject 類別以便具備儲存 (serialize) 的功能 public: int shapenum; // 形狀代號 BOOL fill; // 是否填滿 COLORREF FillColor, LineColor; //填滿顏色與外框顏色 int width; // 外框寛度 CPoint StartPnt, EndPnt; // 形狀的起點與終點

CGObject() { }//預設建構子 CGObject(int shapenum, BOOL fill, COLORREF FillColor, COLORREF LineColor, int width, CPoint StartPnt, CPoint EndPnt) : shapenum(shapenum), fill(fill), FillColor(FillColor), LineColor(LineColor), width(width), StartPnt(StartPnt), EndPnt(EndPnt) { } // 一般建構子 CGObject(CGObject &g) : // 複製建構子 shapenum(g.shapenum), fill(g.fill), FillColor(g.FillColor), LineColor(g.LineColor), width(g.width), StartPnt(g.StartPnt), EndPnt(g.EndPnt) { }// 過載 = 運算子 CGObject & operator = (CGObject &g) { shapenum = g.shapenum; fill = g.fill; FillColor = g.FillColor; LineColor = g.LineColor; width = g.width; StartPnt = g.StartPnt; EndPnt = g.EndPnt;

return *this; }} ;

Page 20: Visual C++ Windows Programming

class Shape { // 形狀類別的基礎類別 protected: CPoint StartPnt, EndPnt; // 定義形狀的起點與終點 int shapenum; // 形狀代號 friend class CMyView; // 將 MyView 設為 friend 類別 , 方便資料存取

public: // 一般建構子 Shape(CPoint StartPnt, CPoint EndPnt, int shapenum) : StartPnt(StartPnt), EndPnt(EndPnt), shapenum(shapenum) { } // 複製建構子 Shape(Shape &s) : StartPnt(s.StartPnt), EndPnt(s.EndPnt), shapenum(s.shapenum) { } Shape() { } //預設建構子 // 過載 = 運算子 Shape & operator = (Shape &s) { StartPnt = s.StartPnt; EndPnt = s.EndPnt; //shapenum = s.shapenum;

return *this; } virtual void draw(CDC &aDC, COLORREF color, COLORREF fcolor, int width, BOOL Filled = f

alse) = 0; //純虛擬函式 int GetShapeNum() { return shapenum; }//取得形狀代號 void SetPoint(CPoint SPnt, CPoint EPnt) { StartPnt = SPnt; EndPnt = EPnt; }// 設定起 ,終點} ;

Page 21: Visual C++ Windows Programming

class Line : public Shape { //直線類別 public:

friend class CMyView;

Line() { shapenum = 0; } //預設建構子 Line(CPoint StartPnt, CPoint EndPnt) : Shape(StartPnt, EndPnt, 0) { } // 一般建構子 Line(Line &l) : Shape(l.StartPnt, l.EndPnt, 0) { } // 複製建構子 Line & operator = (Line &l) { // 過載 = 運算子 StartPnt = l.StartPnt;

EndPnt = l.EndPnt;

return *this;

}

//Line::draw 繪出直線 void draw(CDC &dc, COLORREF color, COLORREF fcolor, int width, BOOL Filled = false) {

CPen pen(PS_SOLID, width, color); // 建立畫筆物件 CPen *oldPen = dc.SelectObject(&pen); // 設定 DC 物件使用 pen 物件 ,並將舊的 default pen 物件儲存起來 dc.MoveTo(StartPnt); //移到直線起點 dc.LineTo(EndPnt); // 畫到直線終點 dc.SelectObject(oldPen); // 將原來的 pen還原 }

} ;

Page 22: Visual C++ Windows Programming

class ellipse : public Shape {

public:

friend class CMyView;

ellipse() { shapenum = 1; }

ellipse(CPoint StartPnt, CPoint EndPnt) : Shape(StartPnt, EndPnt, 1) { }

ellipse(ellipse &e) : Shape(e.StartPnt, e.EndPnt, 1) { }

ellipse & operator = (ellipse &e) {

StartPnt = e.StartPnt;

EndPnt = e.EndPnt;

return *this;

}

void draw(CDC &dc, COLORREF color, COLORREF fcolor, int width, BOOL Filled = false) {

CRect rect(StartPnt, EndPnt);

CPen pen(PS_SOLID, width, color);

CPen *oldPen = dc.SelectObject(&pen);

dc.SelectStockObject(NULL_BRUSH); // 設定 DC 物件不使用畫刷 dc.Ellipse(rect);

dc.SelectObject(oldPen);

}

} ;

class rectangle : public Shape {

public:

friend class CMyView;

rectangle() { shapenum = 2; }

rectangle(CPoint StartPnt, CPoint EndPnt) : Shape(StartPnt, EndPnt, 2) { }

rectangle(rectangle &r) : Shape(r.StartPnt, r.EndPnt, 2) { }

rectangle & operator = (rectangle &r) {

StartPnt = r.StartPnt;

EndPnt = r.EndPnt;

return *this;

}

void draw(CDC &dc, COLORREF color, COLORREF fcolor, int width, BOOL Filled = false) {

CRect rect(StartPnt, EndPnt);

CPen pen(PS_SOLID, width, color);

CPen *oldPen = dc.SelectObject(&pen);

dc.SelectStockObject(NULL_BRUSH);

dc.Rectangle(rect);

dc.SelectObject(oldPen);

}

} ;

Page 23: Visual C++ Windows Programming

class CMyDocument : public CDocument {

private:

CArray<CGObject, CGObject&> gArray; // 儲存 CGObject 物件的 CArray容器物件

public:

void AddObject(CGObject &g) { gArray.Add(g); }

CGObject & GetObject(int i) { return gArray[i]; }

int GetSize() { return gArray.GetSize(); }

DECLARE_DYNCREATE(CMyDocument)

DECLARE_MESSAGE_MAP()

} ;

IMPLEMENT_DYNCREATE(CMyDocument, CDocument)

BEGIN_MESSAGE_MAP(CMyDocument, CDocument)

END_MESSAGE_MAP()

Page 24: Visual C++ Windows Programming

class CMyFrame : public CFrameWnd {

protected:

CMenu *menu;

public:

CToolBar RGBBar, ShapeBar;

CStatusBar statusbar;

CMyFrame() { }

~CMyFrame() { }

//

afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct) {

if(CFrameWnd::OnCreate(lpCreateStruct)) return -1;

RGBBar.Create(this);

RGBBar.LoadToolBar(IDR_TBRGB);

RGBBar.EnableDocking(CBRS_ALIGN_ANY);

RGBBar.SetBarStyle(RGBBar.GetBarStyle() | CBRS_TOOLTIPS | CBRS_FLYBY | CBRS_SIZE_DYNAMIC);

ShapeBar.Create(this);

ShapeBar.LoadToolBar(IDR_TBSHAPE);

ShapeBar.EnableDocking(CBRS_ALIGN_ANY);

ShapeBar.SetBarStyle(RGBBar.GetBarStyle() | CBRS_TOOLTIPS | CBRS_FLYBY | CBRS_SIZE_DYNAMIC);

EnableDocking(CBRS_ALIGN_ANY);

DockControlBar(&RGBBar);

DockControlBar(&ShapeBar);

static UINT indicators[] = { ID_SEPARATOR, IDS_RED, IDS_LINE } ;

statusbar.Create(this);

statusbar.SetIndicators(indicators, sizeof(indicators) / sizeof(UINT));

return 0;

}

DECLARE_DYNCREATE(CMyFrame)

DECLARE_MESSAGE_MAP()

} ;

IMPLEMENT_DYNCREATE(CMyFrame, CFrameWnd)

BEGIN_MESSAGE_MAP(CMyFrame, CFrameWnd)

ON_WM_CREATE()

END_MESSAGE_MAP()

Page 25: Visual C++ Windows Programming

class CMyView : public CView {

private:

COLORREF lcolor, fcolor;// lcolor 為形狀外框的顏色 ,fcolor 為填滿內部的顏色

Shape *aShape; // 指向欲繪製之形狀類別的物件指標

Shape *rdShape; // 為重繪視窗時 ,從 Document 中取得形狀物件

int width; // 形狀外框的寬度

HCURSOR hcursor;

public:

CMyView() {

lcolor = RGB(255, 0, 0);

aShape = new Line;

fcolor = RGB(0, 0, 0);

width = 2;

}

~CMyView() { }

afx_msg void OnEllipse() {

CString resstr;

aShape = new ellipse;

resstr.LoadString(IDS_ELLIPSE);

((CMyFrame *) GetParentFrame())->statusbar.SetPaneText(2, resstr.GetBuffer(80));

}

afx_msg void OnRect() {

CString resstr;

aShape = new rectangle;

resstr.LoadString(IDS_RECTANGLE);

((CMyFrame *) GetParentFrame())->statusbar.SetPaneText(2, resstr.GetBuffer(80));

}

afx_msg void OnLine() {

CString resstr;

aShape = new Line;

resstr.LoadString(IDS_LINE);

((CMyFrame *) GetParentFrame())->statusbar.SetPaneText(2, resstr.GetBuffer(80));

}

afx_msg void OnDraw(CDC *aDC) {

CMyDocument *doc = (CMyDocument *) GetDocument();

int num = doc->GetSize(); //取得目前 Document 物件中儲存的形狀物件個數

CView::OnDraw(aDC);

int i;

for(i = 0; i < num; i++) {

CGObject *object = &(doc->GetObject(i));

switch(object->shapenum) {

case 0:

rdShape = new Line;

break;

case 1:

rdShape = new ellipse;

break;

case 2:

rdShape = new rectangle;

break;

}

rdShape->SetPoint(object->StartPnt, object->EndPnt);

rdShape->draw((*aDC), object->LineColor, object->FillColor, object->width);

delete rdShape;

}

}

Page 26: Visual C++ Windows Programming

afx_msg void OnLButtonDown(UINT, CPoint point) {

SetCapture();

if(this == GetCapture()) {

(*aShape).StartPnt = (*aShape).EndPnt = point;

switch((*aShape).shapenum) {

case 0:

hcursor = AfxGetApp()->LoadCursor(IDC_LINE);

::SetCursor(hcursor);

break;

case 1:

hcursor = AfxGetApp()->LoadCursor(IDC_ELLIPSE);

::SetCursor(hcursor);

break;

case 2:

hcursor = AfxGetApp()->LoadCursor(IDC_RECT);

::SetCursor(hcursor);

break;

}

}

}

afx_msg void OnMouseMove(UINT, CPoint point) {

if(this == GetCapture()) {

CClientDC aDC(this);

aDC.SetROP2(R2_NOT);

(*aShape).draw(aDC, lcolor, fcolor, width);

(*aShape).EndPnt = point;

(*aShape).draw(aDC, lcolor, fcolor, width);

}

}

afx_msg void OnLButtonUp(UINT, CPoint point) {

if(this == GetCapture()) {

CClientDC aDC(this);

(*aShape).EndPnt = point;

(*aShape).draw(aDC, lcolor, fcolor, width);

CGObject object(aShape->GetShapeNum(), true, fcolor, lcolor, width,

aShape->StartPnt, aShape->EndPnt);

CMyDocument *doc = (CMyDocument *) GetDocument();

doc->AddObject(object);

ReleaseCapture();

}

}

afx_msg void OnRed() {

CString resstr;

lcolor = RGB(255, 0, 0);

resstr.LoadString(IDS_RED);

((CMyFrame *) GetParentFrame())->statusbar.SetPaneText(1, resstr.GetBuffer(80));

}

afx_msg void OnGreen() {

CString resstr;

lcolor = RGB(0, 255, 0);

resstr.LoadString(IDS_GREEN);

((CMyFrame *) GetParentFrame())->statusbar.SetPaneText(1, resstr.GetBuffer(80));

}

afx_msg void OnBlue() {

CString resstr;

lcolor = RGB(0, 0, 255);

resstr.LoadString(IDS_BLUE);

((CMyFrame *) GetParentFrame())->statusbar.SetPaneText(1, resstr.GetBuffer(80));

}

Page 27: Visual C++ Windows Programming

afx_msg void OnUpdateEllipse(CCmdUI *aCmdUI) {

aCmdUI->SetCheck((*aShape).shapenum == 1);

}

afx_msg void OnUpdateRect(CCmdUI *aCmdUI) {

aCmdUI->SetCheck((*aShape).shapenum == 2);

}

afx_msg void OnUpdateLine(CCmdUI *aCmdUI) {

aCmdUI->SetCheck((*aShape).shapenum == 0);

}

afx_msg void OnUpdateRed(CCmdUI *aCmdUI) {

aCmdUI->SetCheck(lcolor == RGB(255, 0, 0));

}

afx_msg void OnUpdateGreen(CCmdUI *aCmdUI) {

aCmdUI->SetCheck(lcolor == RGB(0, 255, 0));

}

afx_msg void OnUpdateBlue(CCmdUI *aCmdUI) {

aCmdUI->SetCheck(lcolor == RGB(0, 0, 255));

}

DECLARE_DYNCREATE(CMyView)

DECLARE_MESSAGE_MAP()

} ;

IMPLEMENT_DYNCREATE(CMyView, CView)

BEGIN_MESSAGE_MAP(CMyView, CView)

ON_WM_LBUTTONDOWN()

ON_WM_MOUSEMOVE()

ON_WM_LBUTTONUP()

ON_COMMAND(IDM_RED, OnRed)

ON_COMMAND(IDM_GREEN, OnGreen)

ON_COMMAND(IDM_BLUE, OnBlue)

ON_COMMAND(IDM_LINE, OnLine)

ON_COMMAND(IDM_ELLIPSE, OnEllipse)

ON_COMMAND(IDM_RECTANGLE, OnRect)

ON_UPDATE_COMMAND_UI(IDM_RED, OnUpdateRed)

ON_UPDATE_COMMAND_UI(IDM_GREEN, OnUpdateGreen)

ON_UPDATE_COMMAND_UI(IDM_BLUE, OnUpdateBlue)

ON_UPDATE_COMMAND_UI(IDM_LINE, OnUpdateLine)

ON_UPDATE_COMMAND_UI(IDM_ELLIPSE, OnUpdateEllipse)

ON_UPDATE_COMMAND_UI(IDM_RECTANGLE, OnUpdateRect)

END_MESSAGE_MAP()

Page 28: Visual C++ Windows Programming

class CMyApp : public CWinApp {

public:

BOOL InitInstance() {

CDocument *aDOC;

CSingleDocTemplate *aDocTemplate;

aDocTemplate = new CSingleDocTemplate(IDR_MENU,

RUNTIME_CLASS(CMyDocument),

RUNTIME_CLASS(CMyFrame),

RUNTIME_CLASS(CMyView));

AddDocTemplate(aDocTemplate);

aDOC = aDocTemplate->CreateNewDocument();

CFrameWnd *Frame = aDocTemplate->CreateNewFrame(aDOC, NULL);

m_pMainWnd = Frame;

aDocTemplate->InitialUpdateFrame(Frame, aDOC);

Frame->ShowWindow(SW_SHOW);

return true;

}

} ;

CMyApp a_app;

Page 29: Visual C++ Windows Programming

滑鼠訊息/視窗訊息

CMyView訊息處理方法

呼叫

形狀類別

繪圖方法

執行繪圖

視窗

Page 30: Visual C++ Windows Programming

1. 點選Afx_msg void MyView::OnRect

{

aShape = new rectangle;

}

3.拖曳2

Afx_msg MyView::OnMouseMove()

{

aShape->draw()

}

Virtual shape::draw()=0

Virtual rectangle:draw()

{}

3

4

5

6. 放開

7

Afx_msg MyView::OnLButtonUp()

{

aShape->draw()

}

Page 31: Visual C++ Windows Programming

調整視窗大小

重繪畫布

發出 WM_PAINT 訊息呼叫

MyView::OnDraw

存取MyDocument 中的 gArray

Page 32: Visual C++ Windows Programming

Class CGObject: public CObject

{

..

CGObject(){};

Void Serialize(CArchive & ar) { …};

DECLARE_SERIAL(CGObject);

};

IMPLEMENT_SERIAL(CGObject, CObject, 1)

1

2

3

4_1

4_2

Page 33: Visual C++ Windows Programming

Void CGObject::Serialize (CArchive & ar)

{

CObject::Serialize(ar);

If (ar.IsStoring())

{

ar << Shapenum << fill << fillcolor << linecolor

<< width << StartPnt << EndPnt;

}

Else

{ ar >> … }

}

Page 34: Visual C++ Windows Programming

Void CMyDocment::Serialize(CArchive & ar)

{

CObject::Serialize(ar);

gArray.Serialize(ar);

}

Void CMyDocument::AddObject(CGObject & g)

{

gArray.Add(g);

SetModifiedFlag(true);

}

Page 35: Visual C++ Windows Programming

New

Open

Save

Save as

ID_FILE_NEW

ID_FILE_OPEN

ID_FILE_SAVE

ID_FILE_SAVE_AS

ON_COMMAND(ID_FILE_NEW, CWinApp::OnFileNew)

ON_COMMAND(ID_FILE_OPEN, CWinApp::OnFileOpen)