Click here to Skip to main content
15,885,874 members
Articles / Desktop Programming / MFC

MFC - Multiple inheritance and serialization

Rate me:
Please Sign up or sign in to vote.
4.80/5 (34 votes)
29 Oct 2003CPOL14 min read 163.4K   4.2K   73  
Describing a solution to allow namespaces, multiple inheritance, and serialization in an MFC program
#include "StdAfx.h"
#include <math.h>

using namespace GE_::Operators;

namespace GE_{namespace Mfc{

	//CSize and CPoint operators 

	CSize& operator*=(CSize& s, const int& m)
	{s.cx*=m; s.cy*=m; return s;}

	CSize& operator/=(CSize& s, const int& m)
	{s.cx/=m; s.cy/=m; return s;}

	CSize& operator*=(CSize& s, const CSize& m)
	{s.cx*=m.cx; s.cy*=m.cy; return s;}

	CSize& operator/=(CSize& s, const CSize& m)
	{s.cx/=m.cx; s.cy/=m.cy; return s;}

	CPoint& operator*=(CPoint& p, const int& m)
	{p.x*=m; p.y*=m; return p;}

	CPoint& operator/=(CPoint& p, const int& m)
	{p.x/=m; p.y/=m; return p;}

	CPoint& operator*=(CPoint& p, const CSize& m)
	{p.x*=m.cx; p.y*=m.cy; return p;}

	CPoint& operator/=(CPoint& p, const CSize& m)
	{p.x/=m.cx; p.y/=m.cy; return p;}

	bool operator!(const CSize& s)
	{return !s.cx && !s.cy;};


	int PointToInt(const CPoint& p, const CSize& s)
	{	return p.y*s.cx + p.x;	}

	CPoint IntToPoint(int i, const CSize& s)
	{
		CPoint p;
		p.y = i/s.cx;
		p.x = i%s.cx;
		return p;
	}


	void Start(CPoint& p, const CSize& s)
	{
		p.x=-1;
		p.y=0;
	}

	void Start(CPoint& p, const CRect& r)
	{
		p.x = r.left-1;
		p.y = r.top;
	}

	bool Next(CPoint& p, const CSize& s)
	{
		p.x++;
		if(p.x >= s.cx)
			p.x=0, p.y++;
		if (p.y >= s.cy)
			return false;
		return true;
	}

	bool Next(CPoint& p, const CRect& r)
	{
		p.x++;
		if (p.x >= r.right)
			p.x = r.left, p.y++;
		if (p.y >= r.bottom)
			return false;
		return true;
	}

	bool PtInSize(const CPoint& p, const CSize& s)
	{
		return p.x<s.cx && p.y < s.cy;
	}


	CSize MulDiv(CSize szNumber, CSize szNumerator, CSize szDenominator)
	{	
		return CSize(
			::MulDiv(szNumber.cx, szNumerator.cx, szDenominator.cx), 
			::MulDiv(szNumber.cy, szNumerator.cy, szDenominator.cy)
			);
	}

	CPoint InterpolatePoints(CPoint p1, CPoint p2, LONG t, LONG step)
	{
		using namespace Mfc;
		using namespace Operators;
		return (p1*(step-t) + p2*t) / step;
	}

	LONG Length(const CSize& sz)
	{	return (long)sqrt(sz.cx*sz.cx+sz.cy*sz.cy);	}

	LONG& Openess(CSize& sz, bool bHorz) {return (bHorz)? sz.cx: sz.cy;};
	LONG& Amplitude(CSize& sz, bool bHorz) {return (bHorz)? sz.cy: sz.cx;};
	LONG& Openess(CPoint& pt, bool bHorz) {return (bHorz)? pt.x: pt.y;};
	LONG& Amplitude(CPoint& pt, bool bHorz) {return (bHorz)? pt.y: pt.x;};

	void CalcBorders(const CRect& rcFrom, CSize szWidth, CRect* rcTo)
	{
		for(int i=site_left; i<site__count; i++)
			rcTo[i] = rcFrom;
		rcTo[site_top].bottom = rcTo[site_top].top + szWidth.cy;
		rcTo[site_bottom].top= rcTo[site_bottom].bottom - szWidth.cy;
		rcTo[site_left].right = rcTo[site_left].left + szWidth.cy;
		rcTo[site_right].left= rcTo[site_right].right - szWidth.cy;
		rcTo[site_left].top = rcTo[site_right].top = rcTo[site_top].bottom;
		rcTo[site_left].bottom = rcTo[site_right].bottom= rcTo[site_bottom].top;
	}

	CPoint CLine::Intersect(const CLine& line) const
	{
		LONG a1,b1,c1,a2,b2,c2;
		GetABC(a1,b1,c1);
		line.GetABC(a2,b2,c2);
		return CPoint(
			(b1*c2-c1*b2)/(a1*b2-a2*b1),
			(a1*c2-a2*c1)/(a2*b1-a1*b2)
			);
	}

	LONG CLine::LDistance(const CPoint& point) const
	{
		LONG a,b,c; GetABC(a,b,c);
		return (a*point.x + b*point.x + c)/(LONG)(sqrt(a*a+b*b));
	}

}}



namespace GE_{ namespace Draw{

	CDrwRect::XData::XData()
	{
		clrPen = RGB(0,0,0);
		clrBrush = RGB(192,192,192);
		uPenSize = 1;
		uPenStyle = PS_INSIDEFRAME;
	}

	CDrwRect::CDrwRect(LPCRECT pr, COLORREF fill, COLORREF border, UINT borderSize, UINT borderStyle)
	{
		//initialize members
		CopyRect(pr);
		m_.clrBrush = fill;
		m_.clrPen = border;
		m_.uPenSize = borderSize;
		m_.uPenStyle = borderStyle;
	}

	void CDrwRect::Draw(CDC* pDC)
	{
		// create pen and brush
		CPen pen(m_.uPenStyle, m_.uPenSize, m_.clrPen & 0x00FFFFFF);
		CBrush brs(m_.clrBrush & 0x00FFFFFF);

		// save dc state (restore on return)
		Mfc::CAutoDC dc(pDC->GetSafeHdc());
		
		if(m_.clrBrush == -1) dc.SelectStockObject(HOLLOW_BRUSH);
		else dc.SelectObject(&brs);
		
		if(m_.clrPen == -1) dc.SelectStockObject(NULL_PEN);
		else dc.SelectObject(&pen);
		
		dc.Rectangle(this);
	}

	
	
	CDrwLine::XData::XData()
	{
		uPenSize = 1;
		uPenStyle = PS_SOLID;
		clrPen = RGB(0,0,0);
	}

	CDrwLine::CDrwLine(POINT point1, POINT point2)
	{	_p1 = point1; _p2 = point2;		}

	CDrwLine::CDrwLine(POINT point1, POINT point2, COLORREF clr, UINT size, UINT style)
	{
		_p1 = point1; _p2 = point2;
		m_.clrPen = clr;
		m_.uPenSize = size;
		m_.uPenStyle = style;
	}

	void CDrwLine::Draw(CDC* pDC)
	{
		// create pen (delete on return)
		CPen pen(m_.uPenStyle, m_.uPenSize, m_.clrPen & 0x00FFFFFF);

		//save DC state (restore on return)
		Mfc::CAutoDC dc(pDC->GetSafeHdc());

		if(m_.clrPen == -1) dc.SelectStockObject(NULL_PEN);
		else dc.SelectObject(&pen);
		
		dc.MoveTo(_p1); dc.LineTo(_p2);
	}


	CDrwArrow::XData2::XData2()
	{
		clrFill = RGB(128,128,128);
		cowide = 5000; //30 degrees
		basepush = 0; 
		bDirection = true;
		placement = 8000;
		len = 8;
	}

	void CDrwArrow::Draw(CDC* pDC)
	{
		CPoint points[4]; //will be used as a plygon
		CPoint& ptStart = points[0];	//arrow point
		CPoint& ptBase = points[2];		//base point
		CPoint& ptCorner1 = points[1];	//external corners
		CPoint& ptCorner2 = points[3];

		using namespace Mfc;
		using namespace Operators;

		ptStart = Mfc::InterpolatePoints(_p1,_p2,n.placement);
		LONG linelen = Length(_p2-_p1);
		LONG sinline = (_p2.y - _p1.y)*10000/linelen;
		LONG cosline = (_p2.x - _p1.x)*10000/linelen;
		LONG basedelta = n.len - n.basepush*n.len/10000;

		ptBase = ptStart - CSize(basedelta*cosline/10000, basedelta*sinline/10000)*((n.bDirection)?1:-1);
		CPoint ptprojection = ptStart - CSize(n.len*cosline/10000, n.len*sinline/10000)*((n.bDirection)?1:-1);
		LONG widelen = n.len*n.cowide/10000;
		ptCorner1.x = ptprojection.x - widelen*sinline/10000;
		ptCorner2.x = ptprojection.x + widelen*sinline/10000;
		ptCorner1.y = ptprojection.y + widelen*cosline/10000;
		ptCorner2.y = ptprojection.y - widelen*cosline/10000;

		CBrush brs(n.clrFill & 0x00FFFFFF);
		CPen pen(m.uPenStyle,1,m.clrPen & 0x00FFFFFF);

		CAutoDC dc(pDC->GetSafeHdc());
		if(m.clrPen == -1) dc.SelectStockObject(NULL_PEN);
		else dc.SelectObject(&pen);
		if(n.clrFill == -1) dc.SelectStockObject(NULL_BRUSH);
		else dc.SelectObject(&brs);

		dc.Polygon(points,4);
	}

}}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Architect
Italy Italy
Born and living in Milan (Italy), I'm an engineer in electronics actually working in the ICT department of an important oil/gas & energy company as responsible for planning and engineering of ICT infrastructures.
Interested in programming since the '70s, today I still define architectures for the ICT, deploying dedicated specific client application for engineering purposes, working with C++, MFC, STL, and recently also C# and D.

Comments and Discussions