#include <windows.h>
#include <tchar.h>
#include <iostream>
#include <vector>
#include <fstream>
struct Point {
int x, y;
Point(int i,int j):x{i}, y{j} {}
Point& operator+=(const Point& pt);
Point& operator-=(const Point& pt);
Point& operator/=(int n);
};
Point& Point::operator+=(const Point& pt)
{
this->x += pt.x;
this->y += pt.y;
return *this;
}
Point& Point::operator-=(const Point& pt)
{
this->x -= pt.x;
this->y -= pt.y;
return *this;
}
Point& Point::operator/=(int n)
{
this->x /= n;
this->y /= n;
return *this;
}
Point operator+(const Point& lp,const Point& rp)
{
Point res{lp};
res += rp;
return res;
}
Point operator-(const Point& lp,const Point& rp)
{
Point res{lp};
res -= rp;
return res;
}
class Shape {
public:
virtual Point center() const = 0;
virtual void move(const Point& to) = 0;
virtual void draw(HDC hdc) const = 0;
virtual ~Shape() {}
};
//Rectangle
class RectangleC : public Shape {
public:
RectangleC(const Point& lt,const Point& rb):left_top{lt}, right_bottom{rb} {}
Point center() const;
void move(const Point& to);
void draw(HDC hdc) const;
protected:
Point left_top, right_bottom;
};
Point RectangleC::center() const
{
Point res = left_top + right_bottom;
res /= 2;
return res;
}
void RectangleC::move(const Point& to)
{
Point diff = center() - to;
left_top += diff;
right_bottom += diff;
}
void RectangleC::draw(HDC hdc) const
{
Rectangle(hdc, left_top.x, left_top.y, right_bottom.x, right_bottom.y);
}
//Circular
class Circular : public RectangleC {
public:
Circular(const Point& lt,const Point& rb):RectangleC(lt,rb) {}
void draw(HDC hdc) const;
};
void Circular::draw(HDC hdc) const
{
Ellipse(hdc, left_top.x, left_top.y, right_bottom.x, right_bottom.y);
}
//Circle
class Circle : public Shape {
public:
Circle(const Point& p,int r):pt{p}, radius{r} {}
Point center() const;
void move(const Point& to);
void draw(HDC hdc) const;
protected:
Point pt;
int radius;
};
Point Circle::center() const
{
return pt;
}
void Circle::move(const Point& to)
{
pt = to;
}
void Circle::draw(HDC hdc) const
{
Point ra{radius, radius};
Point left_top = pt - ra;
Point right_bottom = pt + ra;
Ellipse(hdc, left_top.x, left_top.y, right_bottom.x, right_bottom.y);
}
//Smile
class Smile : public Circle {
public:
Smile(const Point& p,int r):Circle(p,r), mouth{nullptr} {}
~Smile() {
delete mouth;
for(auto p : eyes) delete p;
}
void move(const Point& to);
void draw(HDC hdc) const;
void set_default_eyes();
void set_default_mouth();
private:
std::vector<Shape*> eyes;
Shape* mouth;
};
void Smile::set_default_eyes()
{
//设置eye的位置和大小
Point p1{pt}, p2{pt};
p1.x -= radius/3;
p1.y -= radius/3;
p2.x += radius/3;
p2.y -= radius/3;
Shape* c1 = new Circle(p1, radius/5);
Shape* c2 = new Circle(p2, radius/5);
eyes.push_back(c1);
eyes.push_back(c2);
}
void Smile::set_default_mouth()
{
Point left_top{pt.x-radius/3, pt.y+radius/5};
Point right_bottom{pt.x+radius/3, pt.y+radius/5*3};
mouth = new Circular(left_top, right_bottom);
}
void Smile::move(const Point& to)
{
Circle::move(to);
for(auto eye : eyes)
eye->move(to);
if (mouth != nullptr) mouth->move(to);
}
void Smile::draw(HDC hdc) const
{
Circle::draw(hdc);
for(auto eye : eyes)
eye->draw(hdc);
if (mouth != nullptr) mouth->draw(hdc);
}
struct {
int iStyle;
TCHAR* szText;
}
buttons[] = {
BS_AUTORADIOBUTTON, TEXT("Circle"),
BS_AUTORADIOBUTTON, TEXT("Smile"),
BS_AUTORADIOBUTTON, TEXT("Rectangle"),
BS_AUTORADIOBUTTON, TEXT("Circular"),
};
std::ofstream of{"E:/test/zdc.txt"};
LRESULT CALLBACK WndProc(HWND,UINT,WPARAM,LPARAM);
int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,PSTR szCmdLine,int iCmdShow)
{
static TCHAR szAppName[] = TEXT("Shape");
HWND hwnd;
MSG msg;
WNDCLASS wndclass;
wndclass.style = CS_HREDRAW | CS_VREDRAW;
wndclass.lpfnWndProc = WndProc;
wndclass.cbClsExtra = 0;
wndclass.cbWndExtra = 0;
wndclass.hInstance = hInstance;
wndclass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
wndclass.hCursor = LoadCursor(NULL, IDC_ARROW);
wndclass.hbrBackground = (HBRUSH) GetStockObject(WHITE_BRUSH);
wndclass.lpszMenuName = NULL;
wndclass.lpszClassName = szAppName;
if (!RegisterClass(&wndclass))
{
MessageBox(NULL, TEXT("This program requires windows NT!"), szAppName, MB_ICONERROR);
return 0;
}
hwnd = CreateWindow(
szAppName, TEXT("Shape"),
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, CW_USEDEFAULT,
CW_USEDEFAULT, CW_USEDEFAULT,
NULL, NULL, hInstance, NULL
);
ShowWindow(hwnd, iCmdShow);
UpdateWindow(hwnd);
while (GetMessage(&msg,NULL,0,0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return msg.wParam;
}
void Draw_Shape(HDC hdc, RECT rect, TCHAR* szInput)
{
Shape* shape = nullptr;
//修改显示区域rect
int width = rect.right - rect.left;
int height = rect.bottom - rect.top;
rect.left += width/4;
rect.right -= width/4;
rect.top += height/4;
rect.bottom -= height/4;
of << "Draw_Shape:" << std::endl;
of << "left:" << rect.left << "\ttop:" << rect.top <<"\tright:" << rect.right <<"\tbottom:" << rect.bottom << std::endl;
if (_tcscmp(szInput, TEXT("Circle"))==0) {
shape = new Circle (Point{(rect.left+rect.right)/2, (rect.top+rect.bottom)/2}, (rect.bottom-rect.top)/2);
}else if (_tcscmp(szInput, TEXT("Smile"))==0) {
shape = new Smile (Point{(rect.left+rect.right)/2, (rect.top+rect.bottom)/2}, (rect.bottom-rect.top)/2);
((Smile*)shape)->set_default_eyes();
((Smile*)shape)->set_default_mouth();
}else if (_tcscmp(szInput, TEXT("Rectangle"))==0) {
shape = new RectangleC(Point{rect.left, rect.top}, Point{rect.right, rect.bottom});
}else if (_tcscmp(szInput, TEXT("Circular"))==0) {
shape = new Circular(Point{rect.left, rect.top}, Point{rect.right, rect.bottom});
}
if (shape != nullptr)
{
shape->draw(hdc);
delete shape;
}
}
void Clear_Client(HDC hdc,RECT rect)
{
HBRUSH hBrush = CreateSolidBrush(RGB(255,255,255));
FillRect(hdc, &rect, hBrush);
DeleteObject(hBrush);
}
LRESULT CALLBACK WndProc(HWND hwnd,UINT message,WPARAM wParam,LPARAM lParam)
{
static HWND hwndButtons[4];
static int cxChar, cyChar, cxClient, cyClient;
static RECT rect;
HDC hdc;
PAINTSTRUCT ps;
HBRUSH hBrush;
int i;
TCHAR szInput[15];
switch (message)
{
case WM_CREATE:
cxChar = LOWORD(GetDialogBaseUnits());
cyChar = HIWORD(GetDialogBaseUnits());
for(i=0; i<4; i++)
hwndButtons[i] = CreateWindow(
TEXT("button"), buttons[i].szText,
WS_CHILD | WS_VISIBLE | buttons[i].iStyle,
2*cxChar, cyChar*(1+2*i),
20*cxChar, cyChar*7/4,
hwnd, (HMENU)i, ((LPCREATESTRUCT)lParam)->hInstance, NULL
);
return 0;
case WM_SIZE:
rect.left = 24 * cxChar;
rect.top = 2 * cyChar;
rect.right = LOWORD(lParam);
rect.bottom = HIWORD(lParam);
return 0;
case WM_PAINT:
hdc = BeginPaint(hwnd, &ps);
EndPaint(hwnd, &ps);
return 0;
case WM_DRAWITEM:
case WM_COMMAND:
//lParam(窗口句柄) LOWRD(wParam) ID HIWORD(wParam) 通知码
hdc = GetDC(hwnd);
//清空右边显示区域
Clear_Client(hdc, rect);
GetWindowText((HWND)lParam, szInput, 15);
of << "input:" << szInput << std::endl;
Draw_Shape(hdc, rect, szInput);
ReleaseDC(hwnd, hdc);
break;
case WM_DESTROY:
of.close();
PostQuitMessage(0);
return 0;
}
return DefWindowProc(hwnd,message,wParam,lParam);
}
效果
在这里插入图片描述