一个基于win32的涂鸦程序

   

代码如下:

#include <Windows.h>
#include <tchar.h>
#include <string>
#include <math.h>
using namespace std;
//声明回调函数
LRESULT CALLBACK WndProc(HWND hWnd,UINT msg,WPARAM wParam,LPARAM lParam);

//窗口类名和窗口函数
const TCHAR szWindowClass[] = L"第一个窗口";
const TCHAR szWindowTitle[] = L"涂鸦";
const int IDM_TOPMOST=101;
const int IDMTIMER=1;

//判断安静是否按下的宏
#define KEY_DOWN(vk_code) (GetAsyncKeyState(vk_code) & 0x8000)

//WinMain函数,入口点
int WINAPI _tWinMain(HINSTANCE hInstance,HINSTANCE hPreInstance,
					 LPTSTR lpCmdLine,int nCmdSHow)
{
	//注册窗口类
	WNDCLASSEX wcex={0};
	wcex.cbSize=sizeof(WNDCLASSEX);
	wcex.style=CS_HREDRAW|CS_VREDRAW;
	wcex.lpfnWndProc=(WNDPROC)WndProc;
	wcex.hInstance=hInstance;
	wcex.hIcon=LoadIcon(NULL,IDI_APPLICATION);

	wcex.hCursor=LoadCursor(NULL,IDC_ARROW);
	wcex.hbrBackground=(HBRUSH)GetStockObject(WHITE_BRUSH);
	wcex.lpszClassName=szWindowClass;
	RegisterClassEx(&wcex);

	//创建窗口
	HWND hWnd = CreateWindow(
		szWindowClass,
		szWindowTitle,
		WS_OVERLAPPEDWINDOW,
		100,200,500,500,
		HWND_DESKTOP,
		NULL,
		hInstance,
		NULL
		);
	if(!hWnd) return FALSE;

	//显示并更新窗口
	ShowWindow(hWnd,nCmdSHow);
	UpdateWindow(hWnd);

	//进入消息循环
	MSG msg;

	while (GetMessage(&msg,NULL,0,0))
	{
		TranslateMessage(&msg);
		DispatchMessage(&msg);
	}
	return msg.wParam;	
}

enum SCRAWLTYPE {SCRAWLINE,SCRAWRECTANGLE,SCRAWLELLIPSE,
SCRAWLCIRCIE};
TCHAR typeText[SCRAWLCIRCIE+1][10]={L"直线",L"矩形",L"椭圆",L"正圆"};

//在指定设备(hdc)上,用指定颜色(penColor)在矩形内(begin,end)绘制指定类型(type)的图形
void Draw(HDC hdc,POINTS begin,POINTS end,COLORREF penColor,SCRAWLTYPE type)
{
	HPEN pen=CreatePen(PS_SOLID,1,penColor);
	HPEN oldpen=(HPEN)SelectObject(hdc,pen);
	switch(type){
		case SCRAWLINE:
			MoveToEx(hdc,begin.x,begin.y,NULL);
			LineTo(hdc,end.x,end.y);
			break;
		case SCRAWRECTANGLE:
			Rectangle(hdc,begin.x,begin.y,end.x,end.y);
			break;
		case SCRAWLELLIPSE:
			Ellipse(hdc,begin.x,begin.y,end.x,end.y);
			break;
		case SCRAWLCIRCIE:
			//计算半径
			float r = sqrtf((end.x-begin.x)*(end.x-begin.x) + (end.y-begin.y)*(end.y-begin.y))/2;
			//计算圆心
			end.x=(begin.x+end.x)/2;
			end.y=(begin.y+end.y)/2;

			Ellipse(hdc,end.x-r,end.y-r,end.x+r,end.y+r);
			break;
	}
	SelectObject(hdc,oldpen);
}

//窗口函数,用于消息处理
LRESULT CALLBACK WndProc(HWND hWnd,UINT msg,WPARAM wParam,LPARAM lParam){
	int nSel=0;
	static SCRAWLTYPE type = SCRAWLINE;
	static POINTS begin={0,0};
	static COLORREF penColor=RGB(0,0,0);
	static BOOL bTopMost=FALSE;

	switch(msg){
			
		case WM_KEYDOWN:
			{
				switch(wParam){
					case 55: //按数字7,切换到直线
						type = SCRAWLINE;
						break;
					case 56: //按数字8,切换到矩形
						type=SCRAWRECTANGLE;
						break;
					case 57: //9,切换到椭圆
						type=SCRAWLELLIPSE;
						break;
					case 48: //0,切换到圆
						type=SCRAWLCIRCIE;
						break;
					case 0x52: //按字母R,选择红色
						penColor=RGB(255,0,0);
						break;
					case 0x47: //G,绿色
						penColor=RGB(0,255,0);
						break;
					case 0x42: //B,蓝色
						penColor=RGB(0,0,255);
						break;
					case 0x4B: //K,黑色
						penColor=RGB(0,0,0);
						break;
				}
			}

		case WM_LBUTTONDOWN:
			{
				begin=MAKEPOINTS(lParam); //获取起点坐标
				return 0;
			}
		case WM_LBUTTONUP:
			{
				POINTS end=MAKEPOINTS(lParam); //获取终点坐标

				//如果Ctrl键按下,则begin为所在矩形中心坐标,需要计算左上角坐标
				if (wParam & MK_CONTROL)
				{
					begin.x=begin.x-(end.x-begin.x);
					begin.y=begin.y-(end.y-end.y);
				}

				HDC hdc=GetDC(hWnd);
				HBRUSH brush=(HBRUSH)SelectObject(hdc,(HBRUSH)GetStockObject(HOLLOW_BRUSH));
				Draw(hdc,begin,end,penColor,type);
				SelectObject(hdc,brush);
				ReleaseDC(hWnd,hdc);
				return 0;
			}

		case WM_CLOSE:
			{
				nSel=MessageBox(hWnd,L"你真的要退出吗?",szWindowTitle,MB_YESNO|MB_ICONQUESTION);
				if(nSel==IDYES) DestroyWindow(hWnd);
				return 0;
			}
		case WM_DESTROY:
			{
				KillTimer(hWnd,IDMTIMER);
				PostQuitMessage(0);
				return 0;
			}	
		
		
		default:
			return DefWindowProc(hWnd,msg,wParam,lParam);
	}
}


 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

sanqima

一键三连,多多益善

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

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

打赏作者

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

抵扣说明:

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

余额充值