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