Win32 鼠标绘图代码研究

本文深入探讨了使用Win32 API进行鼠标绘图的技术,通过提供的代码片段展示了如何在Windows环境下实现鼠标绘制功能。读者可以结合winmain和窗口过程函数的相关知识进一步理解该技术。
摘要由CSDN通过智能技术生成

http://download.csdn.net/detail/u012313945/9534690

下面摘录绘图部分代码以供研究;winmain和相关窗口过程函数参阅相关资料;


#include<windows.h>
#include "resource.h"
#include"func.h"
#include <stdio.h>
#include <math.h>
void DrawMyLine(HDC hdc, PMYPIC pLine)		// 绘制一条线
{
	HPEN hPen = CreatePenIndirect(&(pLine->logpen));
	HPEN hPenOld = (HPEN)SelectObject(hdc, hPen);
	MoveToEx(hdc, pLine->ptS.x, pLine->ptS.y, NULL);
	LineTo(hdc, pLine->ptE.x, pLine->ptE.y);
	SelectObject(hdc, hPenOld);
	DeleteObject(hPen);
}

void DrawMyRect(HDC hdc, PMYPIC pRect)	// 绘制一个矩形
{
	HPEN hPen = CreatePenIndirect(&(pRect->logpen));
	HPEN hPenOld = (HPEN)SelectObject(hdc, hPen);
	HBRUSH hNewBrush = CreateBrushIndirect (&(pRect->logbrush));
	HBRUSH hOldBrush = (HBRUSH)SelectObject (hdc, hNewBrush);
	Rectangle(hdc,pRect->ptS.x,pRect->ptS.y,pRect->ptE.x,pRect->ptE.y);
	SelectObject(hdc, hPenOld);
	DeleteObject(hPen);
	SelectObject(hdc,hOldBrush);
	DeleteObject(hNewBrush);
}

void DrawMyEll(HDC hdc, PMYPIC pRect)		// 绘制一个椭圆
{
	HPEN hPen = CreatePenIndirect(&(pRect->logpen));
	HPEN hPenOld = (HPEN)SelectObject(hdc, hPen);
	HBRUSH hNewBrush = CreateBrushIndirect (&(pRect->logbrush));
	HBRUSH hOldBrush = (HBRUSH)SelectObject (hdc, hNewBrush);
	Ellipse(hdc,pRect->ptS.x,pRect->ptS.y,pRect->ptE.x,pRect->ptE.y);
	SelectObject(hdc, hPenOld);
	DeleteObject(hPen);
	SelectObject(hdc,hOldBrush);
	DeleteObject(hNewBrush);
}


void DrawMyText(HDC hdc,PMYPIC pText)		//画文字
{
	HFONT hFont=CreateFontIndirect(&(pText->logfont));
	HFONT hFontOld = (HFONT)SelectObject (hdc, hFont);
	SetTextColor(hdc,pText->textColor);
	TextOut(hdc,(pText->ptS.x+pText->ptE.x)/2,(pText->ptS.y+pText->ptE.y)/2,pText->szText,lstrlen(pText->szText));
	GetTextExtentPoint32 (hdc,pText->szText, lstrlen (pText->szText), &pText->size);
	SelectObject(hdc,hFontOld);
	DeleteObject (hFont);
}


int Sum_Pics(PMYPIC pPic,int len)//返回现有图片总数
{
	for (int i=0;i<len;i++)
	{
		if (pPic[i].order==0)
			return i;
	}
	return 0;//保留
}



void DrawAll(HDC hdc, PMYPIC pPic,int count)//画所有图像,包括线,矩形,椭圆
{
	for (int i=0;i<count;i++)
	{
		if(pPic[i].DrawObj==0)break;
		switch (pPic[i].DrawObj)
		{
		case ID_PIC_LINE:DrawMyLine(hdc,&(pPic[i]));break;
		case ID_PIC_RECT:DrawMyRect(hdc,&(pPic[i]));break;
		case ID_PIC_ELL: DrawMyEll(hdc,&(pPic[i]));break;
		case ID_PIC_TEXT:DrawMyText(hdc,&(pPic[i]));break;//
		default: break;
		}
	}
}



void SaveData(PMYPIC pPic,int len)//保存图像到文件
{
	FILE* fp;
	errno_t err;
	if((err=fopen_s(&fp,"data.bin","wb+"))==0)
	{
		fwrite(pPic,sizeof(*pPic),len,fp);
		fclose(fp);
		MessageBox(NULL, L"保存成功!",L"提示",MB_ICONEXCLAMATION|MB_OK);
	}
	else MessageBox(NULL, L"保存失败!",L"Error!",MB_ICONEXCLAMATION|MB_OK);;
}



void ClearArg(PMYPIC pPic,int len)//清空储存图像的数组
{
	for(int i=0;i<len;i++)
	{
		pPic[i].ptS.x=0;
		pPic[i].ptS.y=0;
		pPic[i].ptE.x=0;
		pPic[i].ptE.y=0;
		pPic[i].logpen.lopnColor=0;
		pPic[i].logpen.lopnStyle=0;
		pPic[i].logpen.lopnWidth.x=0;
		pPic[i].logpen.lopnWidth.y=0;
		pPic[i].logbrush.lbColor=0;
		pPic[i].logbrush.lbHatch=0;
		pPic[i].logbrush.lbStyle=0;
		pPic[i].DrawObj=0;
		pPic[i].order=0;
	}
}



bool LoadData(PMYPIC pPic,int len,bool open_tip)//从文件读取图像
{
	FILE* fp;
	errno_t err;
	if((err=fopen_s(&fp,"data.bin","rb+"))==0)
	{
		fread(pPic,sizeof(*pPic),len,fp);
		fclose(fp);
		if(open_tip)MessageBox(NULL, L"加载成功!",L"提示",MB_ICONEXCLAMATION|MB_OK);
		return 1;
	}
	else {
		MessageBox(NULL, L"加载失败!",L"Error!",MB_ICONEXCLAMATION|MB_OK);
		return 0;
	}
}



double Dis_p2p(POINT p1,POINT p2)//点到点的距离
{
	return sqrt(1.0*(p1.x-p2.x)*(p1.x-p2.x)+1.0*(p1.y-p2.y)*(p1.y-p2.y));
}
double Dis_p2line(POINT ptS,POINT ptE,POINT p)//点到线段的距离
{
	double a,b,c;
	a=Dis_p2p(ptS,p);
	if(a<=0.00001)return 0.0f;
	b=Dis_p2p(ptE,p);
	if(b<=0.00001)return 0.0f;
	c=Dis_p2p(ptS,ptE);				 //三角形底边
	if(c<=0.00001)return a;			 //线段太短
	if(a*a>=b*b+c*c) return b;
	if(b*b>=a*a+c*c) return a;
	double l=(a+b+c)/2;				//三角形周长
	double s=sqrt(l*(l-a)*(l-b)*(l-c));//三角形面积
	return 2*s/c;
}


/***********************************
*判断选中哪个图形的函数,返回选中图形
*的次序,未选中返回0
************************************/
int SelectedPic(POINT p, PMYPIC pPic,int len)
{
	for (int i=Sum_Pics(pPic,len)-1;i>=0;i--)
	{
		switch (pPic[i].DrawObj)
		{
		case ID_PIC_LINE:
			/*if(abs((pPic[i].ptE.y-pPic[i].ptS.y)*p.x-(pPic[i].ptE.x-pPic[i].ptS.x)*p.y-pPic[i].ptS.x*(pPic[i].ptE.y-pPic[i].ptS.y)+pPic[i].ptS.y*(pPic[i].ptE.x-pPic[i].ptS.x))/sqrt(pow((pPic[i].ptE.y-pPic[i].ptS.y)*1.0,2)+pow((pPic[i].ptE.x-pPic[i].ptS.x)*1.0,2))<2)
				return pPic[i].order;*/  //点到直线的距离是错误的
			if((Dis_p2line(pPic[i].ptS,pPic[i].ptE,p))<=pPic[i].logpen.lopnWidth.x)
				return pPic[i].order;
			break;
		case ID_PIC_RECT:
			if(abs(pPic[i].ptS.x-p.x)+abs(pPic[i].ptE.x-p.x)<=abs(pPic[i].ptS.x-pPic[i].ptE.x) && abs(pPic[i].ptS.y-p.y)+abs(pPic[i].ptE.y-p.y)<=abs(pPic[i].ptS.y-pPic[i].ptE.y))
				return pPic[i].order;
			break;
		case ID_PIC_ELL:
			if((p.x-(pPic[i].ptS.x+pPic[i].ptE.x)/2.0)*(p.x-(pPic[i].ptS.x+pPic[i].ptE.x)/2.0)/(((pPic[i].ptS.x-pPic[i].ptE.x)/2.0)*((pPic[i].ptS.x-pPic[i].ptE.x)/2.0))
			  +(p.y-(pPic[i].ptS.y+pPic[i].ptE.y)/2.0)*(p.y-(pPic[i].ptS.y+pPic[i].ptE.y)/2.0)/(((pPic[i].ptS.y-pPic[i].ptE.y)/2.0)*((pPic[i].ptS.y-pPic[i].ptE.y)/2.0))<=1)
			  return pPic[i].order;
			break;
		case ID_PIC_TEXT:
			if(abs(p.x-(pPic[i].ptS.x+pPic[i].ptE.x)/2)+abs(p.x-((pPic[i].ptS.x+pPic[i].ptE.x)/2+pPic[i].size.cx))<=pPic[i].size.cx && abs(p.y-(pPic[i].ptS.y+pPic[i].ptE.y)/2)+abs(p.y-((pPic[i].ptS.y+pPic[i].ptE.y)/2+pPic[i].size.cy))<=pPic[i].size.cy)
				return pPic[i].order;
			break;	
		default:
			break;
		}
	}
	return FALSE;
}


void DeletePic(PMYPIC pPic,int order,int len)//删除一个图像
{
	for(int i=0;i<Sum_Pics(pPic,len)-order+1;i++)
	{
		pPic[order-1+i]=pPic[order+i];
		pPic[order-1+i].order=order+i;//这句很关键
	}
}//最后一个图形的清零如何?




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值