visual c++ windows programming
DESCRIPTION
Visual C++ Windows Programming. 第六章 分裂視窗及多文件視窗. 大綱. 分裂視窗的建立 多文件視窗的建立. 分裂視窗的建立. 具有捲軸的視窗 當圖形可繪製區域大於視窗客戶區時,會有資料顯示的問題,而將捲軸加到視窗之上,即可有效解決這個問題。 MFC 具有 CScrollView 的 Class ,此為衍生於 CView 的 Class ,同時具有捲軸。利用 CScrollView ,就可以建立具有捲軸的視窗程式。. 分裂視窗的建立 ( 續 ). 物理座標系統與邏輯座標系統 - PowerPoint PPT PresentationTRANSCRIPT
Visual C++ Windows Programming
第六章 分裂視窗及多文件視窗
大綱• 分裂視窗的建立• 多文件視窗的建立
分裂視窗的建立• 具有捲軸的視窗
– 當圖形可繪製區域大於視窗客戶區時,會有資料顯示的問題,而將捲軸加到視窗之上,即可有效解決這個問題。
– MFC 具有 CScrollView 的 Class ,此為衍生於 CView 的 Class ,同時具有捲軸。利用 CScrollView ,就可以建立具有捲軸的視窗程式。
• 物理座標系統與邏輯座標系統– 對於視窗程式而言,存在著一個物理座標系
統 (physical coordinate) ,與另一個邏輯座標系統 (logical coordinate) 。
– 在一個沒有捲軸的視窗程式之下,物理座標與邏輯座標是相同的﹔但在一個具有捲軸的視窗程式之下,物理座標和邏輯座標滿足
– 要取得捲軸的座標,須呼叫 CScrollView::GetScrollPosition 函式。
分裂視窗的建立 ( 續 )
物理捲軸邏輯物理捲軸邏輯 yyyxxx ;
分裂視窗的建立 ( 續 )
• CSplitterWnd– 在許多情形下,我們希望能夠同時檢視同一
文件的不同部分。這通常是使用視窗分裂的方法來達成。
– 視窗分裂分為動態分裂與靜態分裂的兩種類型。不論是動態分裂或者靜態分裂,我們都可以利用 CSplitterWnd 類別來達成。
CSplitterWndCScrollView
分裂視窗的建立 ( 續 )
• 動態分裂視窗所必須完成的三件工作:1. 在視窗框架類別 (CFrameWnd, etc) 中增加
CSplitterWnd 物件為其屬性。2. 過載 CFrameWnd::OnCreateClient 函式,
並在其中呼叫 CSplitterWnd::Create 函式。3. 建立維持各子視窗同步更新的機制。
#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; }} ;
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; }
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);
}
} ;
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()} ;
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);
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() { }
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;
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;
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; } } }
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)); }
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)); }
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));
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;
分裂視窗的建立 ( 續 )
• 靜態分裂視窗需要完成的工作:1. 在視窗框架類別中增加 CSplitterWnd 物件
為其屬性。2. 過載 CFrameWnd::OnCreateClient 函式,
並在該函式中呼叫 CSplitterWnd::CreateStatic 函式,建立靜態分裂視窗。
3. 呼叫 CSplitterWnd::CreateView 函式,建立每個分裂視窗中的 View 物件。
多文件視窗程式的建立• MDI
– MDI 程式在架構上與 SDI 程式基本上是差不多的,不同的地方有下列三點:1.建立 MDI 視窗程式架構的樣板類別為 CMultiDocTemplat
e 。2.建立 MDI 視窗程式時,所使用的視窗框架物件,不是建
立應用程式的視窗框架類別,而是另行為 MDI 視窗定義的子視窗框架類別,該類別衍生於 CMDIChildWnd 類別。
3.應用程式所使用的視窗框架物件衍生於 CMDIFrameWnd 類別。
#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) { }
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; }
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) { }
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;
}
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;
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()
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;
}
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));
}
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;
}
}
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);
}
}
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)); }
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)); }
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() {
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;