正文

第四课:画线2007-09-22 13:00:00

【评论】 【打印】 【字体: 】 本文链接:http://blog.pfan.cn/lym51/29596.html

分享到:

第四课:画线

一、    GDIDC的概念

1.  GDI:(Graphics Device Interfase)图形设备接口,是一个应用程序与输出设备之间的中介。一方面,GDI向应用程序提供一个与设备无关的编程环境,另一方面,它又以设备相关的格式和具体的设备打交道。

2.  DC(Device Context)设备描述表,是一种Windows数据结构。包括了与一个设备的绘制属性相关的信息。所有的绘制操作通过一个设备描述表进行,绘制线条、形状和文本的Windows API 函数都与DC有关。

二、    Windows Application程序中画线

1.  定义两个全局变量用于记录鼠标按下的(x,y)坐标。

      int nOrginX;

      int nOrginY;

这两个变量如果定义为局部变量,放在Switch—Case语句中和回调函数中都将画不出线来。

2.  响应鼠标按下和鼠标抬起的消息:

Swich中加入case WM_LBUTTONDOWN:

                     case WM_LBUTTONUP:

3.  在鼠标按下时记录鼠标按下的(x,y)坐标,查MSDN得知WM_LBUTTONDOWN

lParam的低字存放x坐标,高字存放y坐标,将其取出存入nOrginXnOrginY

      case WM_LBUTTONDOWN:

             nOrginX=lParam & 0x0000ffff;

             nOrginY=lParam >> 16 & 0x0000ffff;

             break;

4.  在鼠标抬起时画线:

    case WM_LBUTTONUP:

           HDC hdc;

           hdc=GetDC(hwnd);

           PAINTSTRUCT ps;

           ::MoveToEx(hdc,nOrginX,nOrginY,NULL);

           ::LineTo(hdc,LOWORD(lParam),HIWORD(lParam) );

           ::ReleaseDC(hwnd,hdc);

三、在MFC程序中画线:

1.  CxxxView(其中xxx是你的工程名字)中响应鼠标按下和鼠标抬起的消息(因为只有CxxxView中才能接收到鼠标消息):

使用ClassWizard加入WM_LBUTTONDOWNWM_LBUTTONUP的消息响应函数OnLButtonDown, OnLButtonUp

2.  CxxxView中添加成员变量CPoint m_ptOrigin,用于记录鼠标按下的(x,y)坐标。

CPoint是一个用于描述点的简单的类,它有两个成员变量可以存放点的(x,y)坐标。

3.  在鼠标按下时记录该点的坐标:

m_ptOrigin =point;

其中point是调用OnLButtonDown传入的鼠标按下的点的坐标。

4.  在鼠标抬起时画线:

CClientDC dc(this);

dc.MoveTo(m_ptOrigin);

dc.LineTo(point);

其中CClientDC 是一个CDC的子类,在它的构造函数中调用了GetDC,析构函数中调用了ReleaseDC,简化了用户的操作。

 

三、          实现橡皮筋功能:

1.  再定义一个成员变量,用于记录鼠标抬起的点,以便擦线。

CPoint m_ptEnd;

2.  在鼠标按下时记录该点的坐标:

  m_ptOrigin=m_ptEnd=point;

3.使用ClassWizard加入WM_MOUSEMOVE的消息响应函数OnMouseMove

在鼠标移动时判断鼠标左鍵是否按下,如果按下,就不断地擦去上一条线,画出鼠标按下点到鼠标移动的当前点之间的线。

      if(MK_LBUTTON & nFlags)

      {

             CClientDC dc(this);

             dc.SetROP2(R2_NOT);

             dc.MoveTo(m_ptOrigin);

             dc.LineTo(m_ptEnd);

             dc.MoveTo(m_ptOrigin);

             dc.LineTo(point);

             m_ptEnd=point;

      }

   其中:

if (MK_LBUTTON & nFlags)

是判断鼠标左鍵是否按下。在调用OnMouseMove时,不仅为用户传来了坐标信息,还把鼠标左鍵是否按下,Shift鍵是否按下(详细信息可查MSDN)等信息放在UINT nFlags中传入OnMouseMove,用户可以检查相应位是否为1来判断相应键是否按下。

dc.SetROP2(R2_NOT);

该句设置逆转当前屏幕颜色的绘图模式。这种模式下,在屏幕上首次画出的线的是可见的,但在同一位置再画一遍时,线就不见了。这样可以方便的实现不断画线、擦线的效果。

四、          生成自定义的笔和刷子:

1.  WindowsGDI对象:

A CPen : 笔是一促用来画线及绘制有形边框的工具,可以指定它的颜色及宽度,并且可以指定它的线型(实线、点线、虚线等)。  

BCBrush 刷子定义了一种位图形式的象素,利用它可以对区域内部填充颜色。

CCFont :字体是一种具有某种风格和尺寸的所有字符的完整集合。

DCBitmap:位图是一种位矩阵,每一个显示象素都对应于其中的一个或多个位,可以利用位图来表示图象,也可以利用它来创建刷子。

ECRgn :区域是由多边形、椭圆或二者组合形成的一种范围,可以利用它来进行填充、裁剪以及点中测试。

2.  SelectObject函数:

当用户生成一个GDI对象时,它是不会生效的。必须用SelectObject将该GDI对象选入设备描述表,它才会在以后的绘制操作中生效。SelectObject函数会返回指向前一次被选对象的指针。

3.  自定义画笔:

CPen 类提供构造函数用于产生Cpen可以定义笔的线型、线宽和颜色。

CPen( int nPenStyle, int nWidth, COLORREF crColor );

程序中,生成了一个实线,宽度为6,颜色为黑色的笔。要注意的是,有的线型只在线宽小于1时才有效。

       CPen newpen(PS_SOLID ,6,RGB(0,0,0));

       dc.SelectObject(&newpen);

4.  自定义刷子:

CBrush 提供用于产生刷子的构造函数:

CBrush( COLORREF crColor );

CBrush( int nIndex, COLORREF crColor );

CBrush( CBitmap* pBitmap );

I.               CBrush( COLORREF crColor );

它可以产生某种颜色的实心刷子,下面的代码产生了一个红色的实心刷子。

CBrush br(RGB(255,0,0));

dc.SelectObject(br);

II.            CBrush( int nIndex, COLORREF crColor );

它可以产生某种剖面线的刷子,下面的代码产生了一个红色的剖面线刷子。

CBrush br(HS_FDIAGONAL,RGB(255,0,0));

dc.SelectObject(br);

III.          CBrush( CBitmap* pBitmap );

它可以产生位图刷子。

CBitmap bmp;

bmp.LoadBitmap(IDB_BITMAP1);

CBrush br(&bmp);

dc.SelectObject(br);

这段代码首先装入了一幅位图(先在资源中添加一个位图资源,其ID指定为IDB_BITMAP1),再根据这幅位图产生了一个位图刷子。

IV.          产生空刷子

空刷子是一种特殊的刷子,有两种方法可以产生。

1 LOGBRUSH logbr;

logbr.lbStyle=BS_NULL;

        br.CreateBrushIndirect(&logbr);

        dc.SelectObject(br);

2HBRUSH hbr=(HBRUSH)::GetStockObject(NULL_BRUSH);

       CBrush *pbr;

       pbr=CBrush::FromHandle(hbr);

       dc.SelectObject(pbr);

其中,CBrush::FromHandle是一个静态成员函数,它可以不生成类的实例而直接调用,但前面一定要加上类名,以表示它是哪个类的成员函数。


阅读(7033) | 评论(0)


版权声明:编程爱好者网站为此博客服务提供商,如本文牵涉到版权问题,编程爱好者网站不承担相关责任,如有版权问题请直接与本文作者联系解决。谢谢!

评论

暂无评论
您需要登录后才能评论,请 登录 或者 注册