visual c++ windows programming

36
Visual C++ Windows Programming 第第第 第第第第第第第第第第

Upload: lucita

Post on 24-Jan-2016

48 views

Category:

Documents


5 download

DESCRIPTION

Visual C++ Windows Programming. 第六章 分裂視窗及多文件視窗. 大綱. 分裂視窗的建立 多文件視窗的建立. 分裂視窗的建立. 具有捲軸的視窗 當圖形可繪製區域大於視窗客戶區時,會有資料顯示的問題,而將捲軸加到視窗之上,即可有效解決這個問題。 MFC 具有 CScrollView 的 Class ,此為衍生於 CView 的 Class ,同時具有捲軸。利用 CScrollView ,就可以建立具有捲軸的視窗程式。. 分裂視窗的建立 ( 續 ). 物理座標系統與邏輯座標系統 - PowerPoint PPT Presentation

TRANSCRIPT

Page 1: Visual C++ Windows Programming

Visual C++ Windows Programming

第六章 分裂視窗及多文件視窗

Page 2: Visual C++ Windows Programming

大綱• 分裂視窗的建立• 多文件視窗的建立

Page 3: Visual C++ Windows Programming

分裂視窗的建立• 具有捲軸的視窗

– 當圖形可繪製區域大於視窗客戶區時,會有資料顯示的問題,而將捲軸加到視窗之上,即可有效解決這個問題。

– MFC 具有 CScrollView 的 Class ,此為衍生於 CView 的 Class ,同時具有捲軸。利用 CScrollView ,就可以建立具有捲軸的視窗程式。

Page 4: Visual C++ Windows Programming

• 物理座標系統與邏輯座標系統– 對於視窗程式而言,存在著一個物理座標系

統 (physical coordinate) ,與另一個邏輯座標系統 (logical coordinate) 。

– 在一個沒有捲軸的視窗程式之下,物理座標與邏輯座標是相同的﹔但在一個具有捲軸的視窗程式之下,物理座標和邏輯座標滿足

– 要取得捲軸的座標,須呼叫 CScrollView::GetScrollPosition 函式。

分裂視窗的建立 ( 續 )

物理捲軸邏輯物理捲軸邏輯 yyyxxx ;

Page 5: Visual C++ Windows Programming

分裂視窗的建立 ( 續 )

• CSplitterWnd– 在許多情形下,我們希望能夠同時檢視同一

文件的不同部分。這通常是使用視窗分裂的方法來達成。

– 視窗分裂分為動態分裂與靜態分裂的兩種類型。不論是動態分裂或者靜態分裂,我們都可以利用 CSplitterWnd 類別來達成。

Page 6: Visual C++ Windows Programming

CSplitterWndCScrollView

Page 7: Visual C++ Windows Programming

分裂視窗的建立 ( 續 )

• 動態分裂視窗所必須完成的三件工作:1. 在視窗框架類別 (CFrameWnd, etc) 中增加

CSplitterWnd 物件為其屬性。2. 過載 CFrameWnd::OnCreateClient 函式,

並在其中呼叫 CSplitterWnd::Create 函式。3. 建立維持各子視窗同步更新的機制。

Page 8: Visual C++ Windows Programming

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

class CGObject : public CObject { 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 9: Visual C++ Windows Programming

class Shape { protected: CPoint StartPnt, EndPnt; int shapenum; friend class CMyView;

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; return *this; } virtual void draw(CDC &aDC, COLORREF color, COLORREF fcolor, int width, BOOL Filled = false) = 0; int GetShapeNum() { return shapenum; } void SetPoint(CPoint SPnt, CPoint EPnt) { StartPnt = SPnt; EndPnt = EPnt; }} ;

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; }

Page 10: Visual C++ Windows Programming

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.MoveTo(StartPnt);

dc.LineTo(EndPnt);

dc.SelectObject(oldPen);

}

} ;

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.Ellipse(rect);

dc.SelectObject(oldPen);

}

} ;

Page 11: Visual C++ Windows Programming

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); }} ;

class CMyDocument : public CDocument { private: CArray<CGObject, CGObject> gArray; 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()} ;

Page 12: Visual C++ Windows Programming

IMPLEMENT_DYNCREATE(CMyDocument, CDocument)BEGIN_MESSAGE_MAP(CMyDocument, CDocument)

END_MESSAGE_MAP()

class CMyFrame : public CFrameWnd { protected: CSplitterWnd DynSplit; CMenu *menu; public: CToolBar RGBBar, ShapeBar; CStatusBar statusbar;

CMyFrame() { } ~CMyFrame() { }

BOOL OnCreateClient(LPCREATESTRUCT lpcs, CCreateContext *pContext) { return DynSplit.Create(this, 2, 2, CSize(1, 1), pContext); }

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);

Page 13: Visual C++ Windows Programming

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()

class CMyView : public CScrollView { private: COLORREF lcolor, fcolor; Shape *aShape; Shape *rdShape; int width; HCURSOR hcursor; public: CMyView() { lcolor = RGB(255, 0, 0); aShape = new Line; fcolor = RGB(0, 0, 0); width = 2; } ~CMyView() { }

Page 14: Visual C++ Windows Programming

void LogicalCoor(CPoint *point) { CPoint Origin = GetScrollPosition(); point->x = Origin.x + point->x; point->y = Origin.y + point->y; }

void PhysicalCoor(CPoint *point) { CPoint Origin = GetScrollPosition(); point->x = point->x - Origin.x; point->y = point->y - Origin.y; }

afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct) { if(CScrollView::OnCreate(lpCreateStruct) == -1) return -1; CSize DCSize(800, 800); SetScrollSizes(MM_TEXT, DCSize); return 0; }

void OnUpdate(CView *pSender, LPARAM lHint, CObject *pHint) { if(pHint != NULL) { CRect rect((CRect *)pHint); PhysicalCoor(&rect.TopLeft()); PhysicalCoor(&rect.BottomRight()); rect.NormalizeRect(); rect.InflateRect(rect.Width()/2+1, rect.Height()/2+1); InvalidateRect(&rect); } else CScrollView::OnUpdate(pSender, lHint, pHint); }

afx_msg void OnEllipse() { CString resstr;

Page 15: Visual C++ Windows Programming

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();

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;

Page 16: Visual C++ Windows Programming

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; } }

afx_msg void OnLButtonDown(UINT, CPoint point) { SetCapture(); if(this == GetCapture()) { LogicalCoor(&point); (*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; } } }

Page 17: Visual C++ Windows Programming

afx_msg void OnMouseMove(UINT, CPoint point) { if(this == GetCapture()) { CClientDC aDC(this); aDC.SetROP2(R2_NOT); OnPrepareDC(&aDC); LogicalCoor(&point); (*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()) { LogicalCoor(&point); CClientDC aDC(this); OnPrepareDC(&aDC); (*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)); }

Page 18: Visual C++ Windows Programming

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)); }

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)); }

Page 19: Visual C++ Windows Programming

DECLARE_DYNCREATE(CMyView) DECLARE_MESSAGE_MAP()} ;

IMPLEMENT_DYNCREATE(CMyView, CScrollView)BEGIN_MESSAGE_MAP(CMyView, CScrollView) ON_WM_CREATE() 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()

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));

Page 20: Visual C++ Windows Programming

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 21: Visual C++ Windows Programming

分裂視窗的建立 ( 續 )

• 靜態分裂視窗需要完成的工作:1. 在視窗框架類別中增加 CSplitterWnd 物件

為其屬性。2. 過載 CFrameWnd::OnCreateClient 函式,

並在該函式中呼叫 CSplitterWnd::CreateStatic 函式,建立靜態分裂視窗。

3. 呼叫 CSplitterWnd::CreateView 函式,建立每個分裂視窗中的 View 物件。

Page 22: Visual C++ Windows Programming

多文件視窗程式的建立• MDI

– MDI 程式在架構上與 SDI 程式基本上是差不多的,不同的地方有下列三點:1.建立 MDI 視窗程式架構的樣板類別為 CMultiDocTemplat

e 。2.建立 MDI 視窗程式時,所使用的視窗框架物件,不是建

立應用程式的視窗框架類別,而是另行為 MDI 視窗定義的子視窗框架類別,該類別衍生於 CMDIChildWnd 類別。

3.應用程式所使用的視窗框架物件衍生於 CMDIFrameWnd 類別。

Page 23: Visual C++ Windows Programming

#include <afxwin.h>

#include <afxtempl.h>

#include <afxext.h>

#include "resource.h"

class CMyMDIChild : public CMDIChildWnd {

DECLARE_DYNCREATE(CMyMDIChild)

DECLARE_MESSAGE_MAP()

} ;

IMPLEMENT_DYNCREATE(CMyMDIChild, CMDIChildWnd)

BEGIN_MESSAGE_MAP(CMyMDIChild, CMDIChildWnd)

END_MESSAGE_MAP()

class CGObject : public CObject {

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) { }

Page 24: Visual C++ Windows Programming

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; }} ;

class Shape { protected: CPoint StartPnt, EndPnt; int shapenum; friend class CMyView;

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; }

Page 25: Visual C++ Windows Programming

virtual void draw(CDC &aDC, COLORREF color, COLORREF fcolor, int width, BOOL Filled = false) = 0;

int GetShapeNum() { return shapenum; } void SetPoint(CPoint SPnt, CPoint EPnt) { StartPnt = SPnt; EndPnt = EPnt; }} ;

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; } 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.MoveTo(StartPnt); dc.LineTo(EndPnt); dc.SelectObject(oldPen); }} ;

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) { }

Page 26: Visual C++ Windows Programming

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.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;

}

Page 27: Visual C++ Windows Programming

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); }} ;

class CMyDocument : public CDocument { private: CArray<CGObject, CGObject> gArray; 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()

class CMyFrame : public CMDIFrameWnd { protected: CMenu *menu; public: CToolBar RGBBar, ShapeBar; CStatusBar statusbar;

Page 28: Visual C++ Windows Programming

CMyFrame() { } ~CMyFrame() { }

afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct) { if(CMDIFrameWnd::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; }

afx_msg void OnExit() { DestroyWindow(); }

DECLARE_DYNCREATE(CMyFrame) DECLARE_MESSAGE_MAP()} ;

IMPLEMENT_DYNCREATE(CMyFrame, CMDIFrameWnd)BEGIN_MESSAGE_MAP(CMyFrame, CMDIFrameWnd) ON_WM_CREATE() ON_COMMAND(IDM_EXIT, OnExit)END_MESSAGE_MAP()

Page 29: Visual C++ Windows Programming

class CMyView : public CScrollView {

private:

COLORREF lcolor, fcolor;

Shape *aShape;

Shape *rdShape;

int width;

HCURSOR hcursor;

public:

CMyView() {

lcolor = RGB(255, 0, 0);

aShape = new Line;

fcolor = RGB(0, 0, 0);

width = 2;

}

~CMyView() { }

afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct) {

if (CScrollView::OnCreate(lpCreateStruct)==-1) return -1;

CSize DCSize(800,800);

SetScrollSizes(MM_TEXT,DCSize);

return 0;

}

void LogicalCoor(CPoint* point) {

CPoint Origin=GetScrollPosition();

point->x=Origin.x+point->x;

point->y=Origin.y+point->y;

}

Page 30: Visual C++ Windows Programming

void PhysicalCoor(CPoint* point) {

CPoint Origin=GetScrollPosition();

point->x=point->x-Origin.x;

point->y=point->y-Origin.y;

}

afx_msg void OnEllipse() {

CString resstr;

aShape = new ellipse;

resstr.LoadString(IDS_ELLIPSE);

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

}

afx_msg void OnRect() {

CString resstr;

aShape = new rectangle;

resstr.LoadString(IDS_RECTANGLE);

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

}

afx_msg void OnLine() {

CString resstr;

aShape = new Line;

resstr.LoadString(IDS_LINE);

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

}

Page 31: Visual C++ Windows Programming

afx_msg void OnDraw(CDC *aDC) {

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

int num = doc->GetSize();

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 32: Visual C++ Windows Programming

afx_msg void OnLButtonDown(UINT, CPoint point) {

SetCapture();

if(this == GetCapture()) {

LogicalCoor(&point);

(*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);

OnPrepareDC(&aDC);

LogicalCoor(&point);

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

(*aShape).EndPnt = point;

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

}

}

Page 33: Visual C++ Windows Programming

afx_msg void OnLButtonUp(UINT, CPoint point) { if(this == GetCapture()) { LogicalCoor(&point); 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); PhysicalCoor(&aShape->StartPnt); PhysicalCoor(&aShape->EndPnt);

CRect rect(aShape->StartPnt,aShape->EndPnt);

rect.NormalizeRect(); rect.InflateRect(5,5);

InvalidateRect(&rect);

GetDocument()->UpdateAllViews(this); ReleaseCapture(); } }

afx_msg void OnRed() { CString resstr; lcolor = RGB(255, 0, 0); resstr.LoadString(IDS_RED); ((CMyFrame *) AfxGetMainWnd())->statusbar.SetPaneText(1, resstr.GetBuffer(80)); }

Page 34: Visual C++ Windows Programming

afx_msg void OnGreen() { CString resstr; lcolor = RGB(0, 255, 0); resstr.LoadString(IDS_GREEN); ((CMyFrame *) AfxGetMainWnd())->statusbar.SetPaneText(1, resstr.GetBuffer(80)); }

afx_msg void OnBlue() { CString resstr; lcolor = RGB(0, 0, 255); resstr.LoadString(IDS_BLUE); ((CMyFrame *) AfxGetMainWnd())->statusbar.SetPaneText(1, resstr.GetBuffer(80)); }

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)); }

Page 35: Visual C++ Windows Programming

DECLARE_DYNCREATE(CMyView)

DECLARE_MESSAGE_MAP()

} ;

IMPLEMENT_DYNCREATE(CMyView, CScrollView)

BEGIN_MESSAGE_MAP(CMyView, CScrollView)

ON_WM_CREATE()

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 36: Visual C++ Windows Programming

class CMyApp : public CWinApp {

public:

BOOL InitInstance() {

CMultiDocTemplate *aDocTemplate;

aDocTemplate = new CMultiDocTemplate(IDR_ChildMENU,

RUNTIME_CLASS(CMyDocument),

RUNTIME_CLASS(CMyMDIChild),

RUNTIME_CLASS(CMyView));

AddDocTemplate(aDocTemplate);

CMyFrame *Frame = new CMyFrame;

m_pMainWnd = Frame;

Frame->LoadFrame(IDR_MENU);

Frame->ShowWindow(SW_SHOW);

if (m_lpCmdLine[0]=='\0')

OnFileNew();

return true;

}

DECLARE_MESSAGE_MAP()

} ;

BEGIN_MESSAGE_MAP(CMyApp, CWinApp)

ON_COMMAND(ID_FILE_NEW, CWinApp::OnFileNew)

END_MESSAGE_MAP()

CMyApp a_app;