Windows 编程基础

十、绘制直线 返回

 

 学会了画点,下一步就该是画线了,线是由组成的,每个点的位置用两个数来表示(x,y),即平面直角坐标系,

 

 一条直线有两个点,或者说两点确定一条直线,一个是起点,一个是终点,如果连续画线,上一次的终点就是下一次的起点,弄明白了这两个点,我们就来来学习一下,怎样在自己的窗口中画出漂亮的线条来;

 

 画线也用到设备,画线的函数是LineTo(hdc,(x,y));其中的(x,y)是终点,起点用上次的终点,第一次起点是(0,0),屏幕的左上角

 

 另一个是移动函数MoveToEx(hdc,(x,y),NULL);把起点设为上一次的终点,下面我们来编制程序:

 

 1、启动VC,新建一个名为LineWin32 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; 
}

 

 保存一下文件,单击编译条上的“构建”按钮,如果出现错误就仔细检查一下,然后单击“执行”按钮,看看又前进一步的程序窗口;

 

 本节学习了在用户区用鼠标画线的代码设计,如果你成功地完成了练习,请继续学习下一课内容;

返回

 

 余音绕梁 (在弹出的对话框中选择“运行”、“运行”)

本教程由86团学校TeliuTe制作|著作权所有

基础教程网:http://teliute.org/

美丽的校园……



转载和引用本站内容,请保留作者和本站链接。