/**************************************************************************** ** COPYRIGHT (C): 1997 Cay S. Horstmann. All Rights Reserved. ** PROJECT: Practical OO Development with C++ and Java ** FILE: CloudApp.cpp ** PURPOSE: Sample MFC application (chapter 19) ** VERSION 1.0 ** PROGRAMMERS: Cay Horstmann (CSH) ** RELEASE DATE: 3-15-97 (CSH) ** UPDATE HISTORY: ****************************************************************************/ /* Project: GUI Application Add files CloudApp.cpp MainFrm.cpp Settings: Project|Settings|General|Microsoft Foundation Classes|MFC in a shared DLL Project|Settings|C/C++|C++ Language|Enable Run-Time Type Information RTTI */ #if _MSC_VER == 1100 #define PRACTICALOO_COMPILER_UNREASONABLY_INSISTS_ON_COMPARISON_OPERATORS_FOR_VECTORS #endif #define VC_EXTRALEAN #include #include #include #include "MainFrm.h" #include #include #include #include "resource.h" #ifndef PRACTICALOO_NO_STD_NAMESPACE using namespace std; #endif #ifdef PRACTICALOO_COMPILER_UNREASONABLY_INSISTS_ON_COMPARISON_OPERATORS_FOR_VECTORS bool operator<(const CPoint& a, const CPoint& b) { return a.x < b.x || a.x == b.x && a.y < b.y; } bool operator==(const CPoint& a, const CPoint& b) { return a.x == b.x && a.y == b.y; } #endif //------------------------------------------------------------------ class CloudApp : public CWinApp { public: CloudApp(); virtual BOOL InitInstance(); DECLARE_MESSAGE_MAP() }; class CloudDoc : public CDocument { public: void add_point(CPoint p); CPoint get_point(int n) const; int count() const; BOOL regression(double& m, double& b) const; DECLARE_DYNCREATE(CloudDoc) private: #ifndef MUST_USE_ALLOCATORS vector _points; #else vector > _points; #endif }; class GraphView : public CView { public: virtual void OnDraw(CDC* pDC); afx_msg void OnLButtonDown(UINT nFlags, CPoint point); DECLARE_DYNCREATE(GraphView) DECLARE_MESSAGE_MAP() }; class TextView : public CEditView { public: virtual void OnUpdate(CView* pSender, LPARAM lHint, CObject* pHint ); DECLARE_DYNCREATE(TextView) }; //------------------------------------------------------------------ BEGIN_MESSAGE_MAP(CloudApp, CWinApp) ON_COMMAND(ID_FILE_NEW, CWinApp::OnFileNew) END_MESSAGE_MAP() CloudApp::CloudApp() {} CloudApp theApp; BOOL CloudApp::InitInstance() { CMultiDocTemplate* pDocTemplate; pDocTemplate = new CMultiDocTemplate( IDR_GRAPHVIEWTYPE, RUNTIME_CLASS(CloudDoc), RUNTIME_CLASS(CMDIChildWnd), RUNTIME_CLASS(GraphView)); AddDocTemplate(pDocTemplate); pDocTemplate = new CMultiDocTemplate( IDR_TEXTVIEWTYPE, RUNTIME_CLASS(CloudDoc), RUNTIME_CLASS(CMDIChildWnd), RUNTIME_CLASS(TextView)); AddDocTemplate(pDocTemplate); CMainFrame* pMainFrame = new CMainFrame; if (!pMainFrame->LoadFrame(IDR_MAINFRAME)) return FALSE; m_pMainWnd = pMainFrame; pMainFrame->ShowWindow(m_nCmdShow); pMainFrame->UpdateWindow(); return TRUE; } //------------------------------------------------------------------ IMPLEMENT_DYNCREATE(CloudDoc, CDocument) void CloudDoc::add_point(CPoint p) { _points.push_back(p); } CPoint CloudDoc::get_point(int i) const { assert(0 <= i && i < _points.size()); return _points[i]; } int CloudDoc::count() const { return _points.size(); } BOOL CloudDoc::regression(double& m, double& b) const { double sx = 0; double sxx = 0; double sy = 0; double sxy = 0; int n = _points.size(); if (n < 2) return false; for (int i = 0; i < n; i++) { CPoint p = _points[i]; int x = p.x; int y = p.y; sx += x; sy += y; sxx += x * x; sxy += x * y; } double den = sxx - sx * sx / n; if (den == 0) return false; m = (sxy - sx * sy / n) / den; b = (sy - m * sx) / n; return true; } //------------------------------------------------------------------ IMPLEMENT_DYNCREATE(GraphView, CView) BEGIN_MESSAGE_MAP(GraphView, CView) ON_WM_LBUTTONDOWN() END_MESSAGE_MAP() void GraphView::OnDraw(CDC* pDC) { CloudDoc* pDoc = dynamic_cast(GetDocument()); int n = pDoc->count(); int i; for (i = 0; i < n; i++) { CPoint p = pDoc->get_point(i); pDC->Ellipse(p.x - 3, p.y - 3, p.x + 3, p.y + 3); } double m, b; if (pDoc->regression(m, b)) { RECT rect; GetClientRect(&rect); int xright = rect.right; pDC->MoveTo(0, (int)b); pDC->LineTo(xright, (int) (m * xright + b)); } } void GraphView::OnLButtonDown(UINT nFlags, CPoint point) { CloudDoc* pDoc = dynamic_cast(GetDocument()); pDoc->add_point(point); CView::OnLButtonDown(nFlags, point); pDoc->UpdateAllViews(NULL); } //------------------------------------------------------------------ IMPLEMENT_DYNCREATE(TextView, CEditView) void TextView::OnUpdate(CView* pSender, LPARAM lHint, CObject* pHint) { CloudDoc* pDoc = dynamic_cast(GetDocument()); stringstream sstr; int i; for (i = 0; i < pDoc->count(); i++) { POINT p = pDoc->get_point(i); sstr << p.x << " " << p.y << "\r\n"; } double m, b; if (pDoc->regression(m, b)) sstr << "Regression line: y = " << m << " * x + " << b << "\r\n"; GetEditCtrl().SetWindowText(sstr.str().c_str()); }