正文

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

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

分享到:

第四课:画线 一、    GDI、DC的概念 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坐标,将其取出存入nOrginX,nOrginY。       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_LBUTTONDOWN,WM_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.  Windows的GDI对象: A. CPen : 笔是一促用来画线及绘制有形边框的工具,可以指定它的颜色及宽度,并且可以指定它的线型(实线、点线、虚线等)。   B.CBrush : 刷子定义了一种位图形式的象素,利用它可以对区域内部填充颜色。 C.CFont :字体是一种具有某种风格和尺寸的所有字符的完整集合。 D.CBitmap:位图是一种位矩阵,每一个显示象素都对应于其中的一个或多个位,可以利用位图来表示图象,也可以利用它来创建刷子。 E.CRgn :区域是由多边形、椭圆或二者组合形成的一种范围,可以利用它来进行填充、裁剪以及点中测试。 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); 2)HBRUSH hbr=(HBRUSH)::GetStockObject(NULL_BRUSH);        CBrush *pbr;        pbr=CBrush::FromHandle(hbr);        dc.SelectObject(pbr); 其中,CBrush::FromHandle是一个静态成员函数,它可以不生成类的实例而直接调用,但前面一定要加上类名,以表示它是哪个类的成员函数。

阅读(7218) | 评论(0)


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

评论

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