学会了画点,下一步就该是画线了,线是由点组成的,每个点的位置用两个数来表示(x,y),即平面直角坐标系,
一条直线有两个点,或者说两点确定一条直线,一个是起点,一个是终点,如果连续画线,上一次的终点就是下一次的起点,弄明白了这两个点,我们就来来学习一下,怎样在自己的窗口中画出漂亮的线条来;
画线也用到设备,画线的函数是LineTo(hdc,(x,y));其中的(x,y)是终点,起点用上次的终点,第一次起点是(0,0),屏幕的左上角,
另一个是移动函数MoveToEx(hdc,(x,y),NULL);把起点设为上一次的终点,下面我们来编制程序:
1、启动VC,新建一个名为Line的Win32 Application工程,再新建一个相同名称的头文件和源程序文件,在头文件中输入函数的申明,在源程序中输入窗口框架代码;
2、画线的鼠标指针是十字形的,把第3课中的指针文件curMouse拷贝到Line文件夹中,
在头文件中加入一句标识符申明#define IDC_MYCUR 201
再用记事本新建一个相同文件名的资源文件Line.rc输入鼠标指针的定义:IDC_MYCUR CURSOR DISCARDABLE "curMouse.cur" 保存并关闭文件;
3、使用工程菜单中的“添加工程”命令将资源文件Line.rc加入到工程中,
再在InitApplication函数中修改加载鼠标指针一句为wcexLine.hCursor=LoadCursor(hInstance,MAKEINTRESOURCE(201));
其中wcexLine是窗口类名,根据自己的代码修改一致,注意标识符前后一致;
4、加入消息处理函数过程,画线是用鼠标,因此需要处理鼠标按键消息WM_LBUTTONDOWN以及鼠标拖动的消息WM_MOUSEMOVE,还有鼠标抬起WM_LBUTTONUP消息;
消息处理过程MainWndProc(绿色双斜杠部分是注释),有的一行太长会自动折到下一行,代码如下,细细品味每一行的作用是铺垫呢,还是操作;是给谁铺垫,操作结果又是什么呢?
LRESULT APIENTRY MainWndProc(
HWND hWnd,UINT message,WPARAM wParam,LPARAM lParam)
{
HDC hdc;
static HPEN hpenBlue;//申明一支彩色笔;
static POINT pointBegin,pointEnd,point;//保存起点和终点,当前点;
static int x1,y1;//单击鼠标画线的终点位置
switch (message)
{
case WM_CREATE: // 创建一支彩色笔
hpenBlue = CreatePen(PS_SOLID, 1, RGB(0,0,255));
break;
case WM_LBUTTONDOWN://左键按下
pointBegin.x =LOWORD(lParam);//初始化起点x
pointBegin.y=HIWORD(lParam);//初始化起点y
pointEnd.x=LOWORD(lParam);//初始化终点x
pointEnd.y=HIWORD(lParam);//初始化终点y
//当前点的位置用默认为屏幕左上角(0,0)
SetCapture(hWnd);//一直跟着鼠标
break;
case WM_MOUSEMOVE://进入鼠标移动消息;
if(wParam & MK_LBUTTON)//检测左键是否按下;
{//进入鼠标拖动;
point.x =LOWORD(lParam);//当前鼠标的位置x;
point.y=HIWORD(lParam);//当前鼠标的位置y;
hdc=GetDC(hWnd);
SetROP2(hdc,R2_NOT);//使用与背景色相反的颜色;
//第二次用与背景色相反的颜色绘制,可以擦去原来的线条(双重否定);
MoveToEx(hdc,pointBegin.x,pointBegin.y,NULL);
//画线起点是单击左键时的鼠标的位置
LineTo(hdc,pointEnd.x,pointEnd.y);
//擦除上次绘出的直线;
//第二次移动时,先把第一次的线擦除,然后下面画这次移动的线;
MoveToEx(hdc,pointBegin.x,pointBegin.y,NULL);//原来鼠标的位置
LineTo(hdc,point.x,point.y);//point是当前鼠标的位置
//这两条语句将绘制一条从起点到当前鼠标位置的线;
pointEnd.x=point.x; pointEnd.y=point.y;
//这两条语句保存当前鼠标位置,以便于鼠标移动后可以擦除这次绘制的直线
ReleaseDC(hWnd,hdc);
}
break;
case WM_LBUTTONUP:
//如果是单击画图将会用彩色笔
ReleaseCapture();//解除鼠标跟踪
hdc=GetDC(hWnd);
SelectObject(hdc, hpenBlue);//换上彩色笔
MoveToEx(hdc,point.x,point.y,NULL);
//设定起点,在鼠标移动消息中修改了point
x1=LOWORD(lParam);//画线终点x;
y1=HIWORD(lParam);//画线终点y;
LineTo(hdc,x1,y1);//从起点到当前点画线
//point.x=x1;//修改当前点的位置为这次的结束位置,
//point.y=y1;//不修改就一直用同一个起点(星形)
ReleaseDC(hWnd,hdc);
break;
case WM_DESTROY://退出应用程序;
PostQuitMessage(0);//向系统发送一条WM_QUIT消息,
break;
default: //让系统帮着处理的消息
return (DefWindowProc(hWnd,message,wParam,lParam));
}
return 0;
}
保存一下文件
本节学习了在用户区用鼠标画线的代码设计,如果你成功地完成了练习,请继续学习下一课内容;