Seuraavassa MopoCadin toteutuksesta Microsoftin Foundation Class -luokkakirjastoa käyttäen. Koska STL- kirjastoa ei yrityksistä huolimatta saatu toimimaan, on se korvattu "omatekoisella" luokalla, jossa on ulospäin samat toiminnot.
// mopocad.cpp
// Mopocad for Visual C++ 4.0/vl-96
#include <afxwin.h>
#include "..\mopocad.rh"
//-----------------------------------------------------------------------------
// Koska STL:aa ei saatu yli 10 h kokeiluista huolimatta toimimaan,
// rakennetaan tilalle vastaavat toiminnot (jotka riittavat tahan esim)
// MFC:n omalla CArray -sailo-luokalla.
#include <afxtempl.h>
class cPoints { // Sailoluokka joka osaa tallettaa vain pisteitä
CArray<CPoint,CPoint> points;
public:
class cPIte { // Iteraattori, jolla sailoluokkaa voidaan kasitella
int i;
cPoints *p;
public:
friend cPoints;
cPIte() { i=0; p = NULL; }
cPIte(int ii,cPoints *ip) { i= ii; p = ip; }
CPoint &operator*() const { return p->points[i]; }
int operator!=(const cPIte &i2) const { return i != i2.i; }
cPIte &operator++() { i++; return *this; }
cPIte &operator++(int) { i++; return *this; }
}; // cPIte
friend cPoints::cPIte;
void push_back(const CPoint &pt) { points.Add(pt); }
cPIte begin() { return cPIte(0,this); }
cPIte end() { return cPIte(points.GetSize(),this);}
void erase(const cPIte &b, const cPIte &e) { points.RemoveAt(b.i,e.i-b.i); }
}; // cPoints
typedef cPoints::cPIte cPointsIterator;
//-----------------------------------------------------------------------------
CPoint MovePoint(-2000,-2000); // Merkki taulukkoon siirrosta
//-----------------------------------------------------------------------------
class CMainWindow : public CFrameWnd {
CClientDC *HoldDC;
BOOL ButtonDown;
cPoints Points;
protected:
void DeleteAllPoints();
void ClearWindow();
public:
CMainWindow();
~CMainWindow() { DeleteAllPoints(); }
virtual void Exit();
virtual void About();
void OnLButtonDown(UINT nFlags,CPoint point);
void OnMouseMove(UINT nFlags,CPoint point);
void OnLButtonUp(UINT nFlags,CPoint point);
void OnRButtonDown(UINT nFlags,CPoint point);
void OnPaint();
DECLARE_MESSAGE_MAP()
};
BEGIN_MESSAGE_MAP( CMainWindow, CFrameWnd )
ON_COMMAND(CM_FILE_EXIT, Exit)
ON_COMMAND(CM_HELP_ABOUT, About)
ON_WM_LBUTTONDOWN()
ON_WM_MOUSEMOVE()
ON_WM_LBUTTONUP()
ON_WM_RBUTTONDOWN()
ON_WM_PAINT()
END_MESSAGE_MAP()
//-----------------------------------------------------------------------------
class CDLG_AboutDlg : public CDialog{ // Tässä tarpeeton, ks. CMainWin::About!
public:
CDLG_AboutDlg(LPCTSTR name,CWnd *Parent): CDialog(name,Parent) {}
virtual void Ok();
DECLARE_MESSAGE_MAP()
};
BEGIN_MESSAGE_MAP( CDLG_AboutDlg, CDialog )
ON_COMMAND(IDOK, Ok)
END_MESSAGE_MAP()
//-------------------- CDLG_AboutDlg metodit: ---------------------------------
void CDLG_AboutDlg::Ok()
{
EndDialog(0);
}
//-----------------------------------------------------------------------------
CMainWindow::CMainWindow()
{
Create(NULL,"MopoCad");
ButtonDown = FALSE;
HoldDC = NULL;
LoadAccelTable("PIKA");
CMenu menu;
menu.LoadMenu("PAAMENU");
SetMenu(&menu);
menu.Detach();
}
void CMainWindow::Exit()
{
DestroyWindow();
}
void CMainWindow::About()
{
// Tosin voitaisiin kutsua suoraan geneeristä CDialog ja jättää
// koko CDLG_AboutDlg luokka pois!
// CDialog dlg("DLG_ABOUT",this);
CDLG_AboutDlg dlg("DLG_ABOUT",this);
dlg.DoModal();
}
void CMainWindow::OnLButtonDown(UINT ,CPoint point)
{
if ( ButtonDown ) return;
ButtonDown = TRUE;
SetCapture();
HoldDC = new CClientDC(this);
HoldDC->MoveTo(point);
Points.push_back(MovePoint);
Points.push_back(point);
}
void CMainWindow::OnMouseMove(UINT ,CPoint point)
{
if ( !ButtonDown ) return;
HoldDC->LineTo(point);
Points.push_back(point);
}
void CMainWindow::OnLButtonUp(UINT ,CPoint)
{
if ( !ButtonDown ) return;
ReleaseCapture();
delete HoldDC;
HoldDC = NULL;
ButtonDown = FALSE;
}
void CMainWindow::OnRButtonDown(UINT ,CPoint)
{
if ( ButtonDown ) return;
ClearWindow();
}
void CMainWindow::OnPaint() {
CPaintDC hdc(this);
cPointsIterator pi;
for (pi=Points.begin(); pi != Points.end() ; pi++)
if ( *pi == MovePoint ) hdc.MoveTo(*++pi);
else hdc.LineTo(*pi);
}
void CMainWindow::DeleteAllPoints()
{
Points.erase(Points.begin(),Points.end());
}
void CMainWindow::ClearWindow()
{
DeleteAllPoints();
Invalidate(TRUE);
}
//-----------------------------------------------------------------------------
class CMopoCadApp : public CWinApp {
public:
virtual BOOL InitInstance() {
m_pMainWnd = new CMainWindow();
m_pMainWnd->ShowWindow(m_nCmdShow);
m_pMainWnd->UpdateWindow();
m_pMainWnd->SetIcon(LoadIcon("IKONI"),TRUE);
return TRUE;
}
};
CMopoCadApp MopoCadApp; // constructor initializes and runs the app