Shape、Circle、Smile用win32实现

#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);
}

效果

在这里插入图片描述在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
©️2022 CSDN 皮肤主题:1024 设计师:我叫白小胖 返回首页
评论

打赏作者

明天过后mm

你的鼓励将是我创作的最大动力

¥2 ¥4 ¥6 ¥10 ¥20
输入1-500的整数
余额支付 (余额:-- )
扫码支付
扫码支付:¥2
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值