vc++ big job mfc simple drawing program

Major job requirements:

a drawing program
Using VC++, MFC can draw at least 4 types of graphics; it has functions such as adding, deleting, modifying, (checking, optional, and adding attribute functions) to fill in unlimited amounts, and stroked graphics can be saved and opened.

I’m really busy, but there are still people urging me to update this.

Sharing results can meet the minimum requirements of the assignment. The specific implementation is as follows:

1. Create a project

Creation completed.

2. Create your own shape class

(1) Create header file

class Yjjj0310Shape : public CObject
{
DECLARE_SERIAL(Yjjj0310Shape)
private:
double up;
double down;
double left;
double right;
int body;
COLORREF col_area;
COLORREF col_line;
bool isOk;
public:
Yjjj0310Shape(); // No parameter construction
Yjjj0310Shape(double up, double down, double left, double right, int body, COLORREF col_area, COLORREF col_line); // Constructor
virtual void Serialize(CArchive & amp; ar); // Serialization function
void Draw(CDC* pDC); // Drawing function
void IsSelect(double x, double y); // Judgment selection function
bool CD(); // Return selection status function
void NoSelect(); // Deselect status function
void MoveUP(); // Move up
void MoveDOWN(); // Move down
void MoveLEFT(); // Move left
void MoveRight(); // Move right
double GetUP(); // Return the up value
double GetDPWN(); // Return the down value
double GetLEFT(); // Return left value
double GetRIGHT(); // Return the right value
int GetBODY(); // Return body value
COLORREF GetCOL_AREA(); // Return the fill color
COLORREF GetCOL_LINE(); // Return the stroke color
void ad(); // number +
void da(); // number-
};

(2) Create source files

#include "pch.h"
#include "windef.h"
#include "Yjjj0310Shape.h"

IMPLEMENT_SERIAL(Yjjj0310Shape, CObject, 1)
Yjjj0310Shape::Yjjj0310Shape() {}
Yjjj0310Shape::Yjjj0310Shape(double x, double y, double m, double n, int z, COLORREF c, COLORREF c0) // Construction
{
up = x;
down = y;
left = m;
right = n;
body = z;
col_area = c;
col_line = c0;
isOk = false;
}

void Yjjj0310Shape::Serialize(CArchive & amp; ar)

{
if (ar.IsStoring()) { //Serialization, saving information
ar << up << down << left << right << body << col_area << col_line << isOk;
}
else //Deserialize, read information
{
ar >> up >> down >> left >> right >> body >> col_area >> col_line >> isOk;
}

}

void Yjjj0310Shape::Draw(CDC* pDC) // Drawing
{
CBrush NBrush(col_area);
CPen NPen(PS_SOLID, 0, col_line);
pDC->SelectObject(NBrush);
pDC->SelectObject(NPen);
switch (body)
{
case 1:
{
pDC->MoveTo(left, up);
pDC->LineTo(right, down);
break;
}
case 2:
{
pDC->Ellipse(left, down, right, up);
break;
}
case 3:
{
pDC->Rectangle(left, down, right, up);
break;
}
case 4:
{
double r = sqrt(pow(up - down, 2) + pow(right - left, 2)) / 2;
double o_x = (left + right) / 2, o_y = (up + down) / 2;
pDC->Ellipse(o_x + r, o_y + r, o_x - r, o_y - r);
break;
}
}
}
void Yjjj0310Shape::IsSelect(double x, double y) // select
{
switch (body)
{
case 1: // straight line
{
double k = (up - down) / (left - right);
double b = up - k * left;
if (y == k * x + b)
isOk = true;
break;
}
case 2: // ellipse
{
double a = abs(right - left) / 2, b = abs(up - down) / 2;
double c, Clx, Cly, Crx, Cry, o_l;
if (a > b)
{
c = sqrt(pow(a, 2) - pow(b, 2));
Clx = (left + right) / 2 - c, Crx = (left + right) / 2 + c, Cly = Cry = (up + down) / 2;
o_l = sqrt(pow(x - Clx, 2) + pow(y - Cly, 2)) + sqrt(pow(x - Crx, 2) + pow(y - Cry, 2));
if (o_l <= 2 * a)
isOk = true;
}
else
{
c = sqrt(pow(b, 2) - pow(a, 2));
Cly = (up + down) / 2 - c, Cry = (up + down) / 2 + c, Clx = Crx = (left + right) / 2;
o_l = sqrt(pow(x - Clx, 2) + pow(y - Cly, 2)) + sqrt(pow(x - Crx, 2) + pow(y - Cry, 2));
if (o_l <= 2 * b)
isOk = true;
}
break;
}
case 3: // rectangle
{
if (y >= up & amp; & amp; y <= down & amp; & amp; x >= left & amp; & amp; x <= right)
isOk = true;
break;
}
case 4: // perfect circle
{
double r = sqrt(pow(up - down, 2) + pow(right - left, 2)) / 2;
double o_x = (left + right) / 2, o_y = (up + down) / 2;
double o_l = sqrt(pow(x - o_x, 2) + pow(y - o_y, 2)) / 2;
if (o_l <= r)
isOk = true;
break;
}
}

}

bool Yjjj0310Shape::CD() // Return to selected state
{
return isOk;
}

void Yjjj0310Shape::NoSelect() // Uncheck state
{
isOk = false;
}

void Yjjj0310Shape::MoveUP()
{
up -= 10;
down -= 10;
}

void Yjjj0310Shape::MoveDOWN()
{
up + = 10;
down + = 10;
}

void Yjjj0310Shape::MoveLEFT()
{
left -= 10;
right -= 10;
}

void Yjjj0310Shape::MoveRight()
{
left + = 10;
right + = 10;
}

double Yjjj0310Shape::GetUP() { return up; }
double Yjjj0310Shape::GetDPWN() { return down; }
double Yjjj0310Shape::GetLEFT() { return left; }
double Yjjj0310Shape::GetRIGHT() { return right; }
int Yjjj0310Shape::GetBODY() { return body; }
COLORREF Yjjj0310Shape::GetCOL_AREA() { return col_area; }
COLORREF Yjjj0310Shape::GetCOL_LINE() { return col_line; }
void Yjjj0310Shape::ad() { up + + ; }
void Yjjj0310Shape::da() { up--; }

3. Doc class

(1)Header file

(2) Source file


    for (int i = 0; i < ShapeArray.GetSize(); + + i)
{
Yjjj0310Shape* pShape = ShapeArray.GetAt(i);
delete pShape;
}

There is something wrong in the screenshot, please refer to the following

 if (ar.IsStoring())
{
// TODO: Add storage code here

for (int i = 0; i < ShapeArray.GetSize(); i + + )
{
Yjjj0310Shape* CS = ShapeArray[i];
CS->Serialize(ar);

}

}
else
{
// TODO: Add loading code here
ShapeArray.RemoveAll(); // Clear the array
Yjjj0310Shape* CS = new Yjjj0310Shape();
CS->Serialize(ar);
ShapeArray.Add(CS); // Add elements to the array
int num = ShapeArray[0]->GetUP();
for (int i = 0; i < num; i + + )
{
Yjjj0310Shape* CS2 = new Yjjj0310Shape();
CS2->Serialize(ar);
ShapeArray.Add(CS2); // Add elements to the array
}
}

4. View class

(1)Header file

int num = 0;
bool ff = false;
double m_u;
double m_d;
double m_l;
double m_r;
double m_x;
double m_y;
COLORREF col_in = RGB(0, 0, 0);
COLORREF col_out = RGB(0, 0, 0);
Yjjj0310Shape* CS;
void DeleteSelect(double x, double y); // Delete selection function
Yjjj0310Shape* Choose(double x, double y); //Choose function

(2) Add button

Save it when you’re done

(3) Source files

If there are none or a few are missing, reopen VS

It’s OK when done. (Updated in 12.27, there is one less message on the right here, and the WM_CREATE message must also be added)

void CYjjj0310View::CreateLine()
{
// TODO: Add command handler code here
num = 1;

}


void CYjjj0310View::CreateCircle()
{
// TODO: Add command handler code here
num = 2;

}


void CYjjj0310View::CreateRectangle()
{
// TODO: Add command handler code here
num = 3;

}


void CYjjj0310View::CreateRCircle()
{
// TODO: Add command handler code here
num = 4;

}


void CYjjj0310View::ChooseColor()
{
// TODO: Add command handler code here
CColorDialog dlg;

dlg.m_cc.Flags |= CC_RGBINIT | CC_FULLOPEN;

if (IDOK == dlg.DoModal())
{
col_in = dlg.m_cc.rgbResult; // Save the color in the color dialog box obtained by dlg.m_cc.rgbResult into the variable m_clr
}
}


void CYjjj0310View::ChooseColorOut()
{
// TODO: add command handler code here
CColorDialog dlg;

dlg.m_cc.Flags |= CC_RGBINIT | CC_FULLOPEN;

if (IDOK == dlg.DoModal())
{
col_out = dlg.m_cc.rgbResult; // Save the color in the color dialog box obtained by dlg.m_cc.rgbResult into the variable m_clr
}
}


void CYjjj0310View::OnFileOpen()
{
// TODO: Add command handler code here
CFileDialog dlg(TRUE, _T("dat"), NULL, OFN_FILEMUSTEXIST | OFN_HIDEREADONLY, _T("Data Files (*.dat)|*.dat|All Files (*.*)|*.*||"), this );

if (dlg.DoModal() == IDOK) {
CFile file(dlg.GetPathName(), CFile::modeRead);
CArchive ar( & amp;file, CArchive::load);

GetDocument()->Serialize(ar); // Call the serialization method of the document class

ar.Close();
file.Close();

// After loading the data, if you need to update the view, you can refresh it here
Invalidate(NULL); // Redraw the view
}
}


void CYjjj0310View::OnFileSave()
{
// TODO: Add command handler code here
CFileDialog dlg(FALSE, _T("dat"), NULL, OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT, _T("Data Files (*.dat)|*.dat|All Files (*.*)|*.*||"), this );

if (dlg.DoModal() == IDOK) {
CFile file(dlg.GetPathName(), CFile::modeCreate | CFile::modeWrite);
CArchive ar( & amp;file, CArchive::store);

GetDocument()->Serialize(ar); // Call the serialization method of the document class

ar.Close();
file.Close();
}
}


void CYjjj0310View::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags)
{
// TODO: Add message handler code and/or call defaults here
switch(nChar)
{
case VK_DELETE:
{
DeleteSelect(m_x, m_y);
InvalidateRect(NULL);
break;
}
case VK_CONTROL:
{
CS = Choose(m_x, m_y);
ff = true;
break;
}
case VK_UP:
{
if(ff)
{
CS->MoveUP();
CS->NoSelect();
InvalidateRect(NULL);

}
break;
}
case VK_DOWN:
{
if(ff)
{
CS->MoveDOWN();
CS->NoSelect();
InvalidateRect(NULL);
}
break;
}
case VK_LEFT:
{
if(ff)
{
CS->MoveLEFT();
CS->NoSelect();
InvalidateRect(NULL);
}
break;
}
case VK_RIGHT:
{
if(ff)
{
CS->MoveRight();
CS->NoSelect();
InvalidateRect(NULL);
}
break;
}
}
CView::OnKeyDown(nChar, nRepCnt, nFlags);
}


void CYjjj0310View::OnKeyUp(UINT nChar, UINT nRepCnt, UINT nFlags)
{
// TODO: Add message handler code and/or call defaults here
switch(nChar)
{
case VK_CONTROL:
{
ff = false;
break;
}

}
CView::OnKeyUp(nChar, nRepCnt, nFlags);
}


void CYjjj0310View::OnLButtonDown(UINT nFlags, CPoint point)
{
// TODO: Add message handler code and/or call defaults here
m_u = point.y;
m_l = point.x;
CView::OnLButtonDown(nFlags, point);
}


void CYjjj0310View::OnLButtonUp(UINT nFlags, CPoint point)
{
// TODO: Add message handler code and/or call defaults here
m_d = point.y;
m_r = point.x;
if (num != 0)
{
CYjjj0310Doc* pDoc = GetDocument();
Yjjj0310Shape* pShape;
if (num == 1)
pShape = new Yjjj0310Shape(m_u, m_d, m_l, m_r, num, col_in, col_out);
else
pShape = new Yjjj0310Shape(min(m_u, m_d), max(m_u, m_d), min(m_l, m_r), max(m_l, m_r), num, col_in, col_out);
pDoc->ShapeArray.Add(pShape);
pDoc->ShapeArray[0]->ad();
InvalidateRect(NULL);
}
CView::OnLButtonUp(nFlags, point);
}


void CYjjj0310View::OnMouseMove(UINT nFlags, CPoint point)
{
// TODO: Add message handler code and/or call defaults here
m_x = point.x;
m_y = point.y;
CView::OnMouseMove(nFlags, point);
}


int CYjjj0310View::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (CView::OnCreate(lpCreateStruct) == -1)
return -1;

// TODO: Add your own creation code here
Yjjj0310Shape* pShape = new Yjjj0310Shape(0, 0, 0, 0, 99999, col_in, col_out);
CYjjj0310Doc* pDoc = GetDocument();
pDoc->ShapeArray.Add(pShape);
return 0;
}

void CYjjj0310View::DeleteSelect(double x, double y)
{
CYjjj0310Doc* pDoc = GetDocument();
for (int i = 0; i < pDoc->ShapeArray.GetSize(); + + i)
{
Yjjj0310Shape* pShape = pDoc->ShapeArray.GetAt(i);
pShape->IsSelect(x, y);
if (pShape->CD())
{
pDoc->ShapeArray.RemoveAt(i);
pDoc->ShapeArray[0]->da();
}
}
}
Yjjj0310Shape* CYjjj0310View::Choose(double x, double y)
{
CYjjj0310Doc* pDoc = GetDocument();
Yjjj0310Shape* pShape = NULL;
for (int i = 0; i < pDoc->ShapeArray.GetSize(); + + i)
{
pShape = pDoc->ShapeArray.GetAt(i);
pShape->IsSelect(x, y);
}
return pShape;
}
void CYjjj0310View::OnDraw(CDC* pDC)
{
CYjjj0310Doc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
if (!pDoc)
return;

// TODO: Add drawing code for native data here
for (int i = 0; i < pDoc->ShapeArray.GetSize(); + + i)
{
Yjjj0310Shape* pShape = (pDoc->ShapeArray).GetAt(i);
pShape->Draw(pDC);
}
}

The effect is roughly like this. (Updated in 12.27, if you encounter an abs() function error, you can replace that sentence with the following one. There should be no other errors)

double a = (right - left) / 2, b = (up - down) / 2;
a = a > 0 ? a : a * -1;
b = b > 0 ? b : b * -1;

Just finish it and run it. This semester’s VC++ coursework should be completed. I did a few questions that I left last time but he didn’t let me hand them in…

Thank you for your companionship. If you have any other needs in the future, feel free to message me privately or leave a comment.