5.GDI与GDI+的比较
GDI+相对GDI而言主要在编程方式上发生了巨大的改变。
GDI的核心是设备上下文,GDI函数都依赖于设备上下文句柄,其编程方式是基于句柄的;GDI+无需时刻依赖于句柄或设备上下文,用户只需创建一个Graphics 对象,就可以用面向对象的方式调用其成员函数进行图形操作,编程方式是基于对象的。
GDI在使用设备上下文绘制线条之前,必须先调用SelectObject 以使钢笔对象和设备上下文关联。其后,在设备上下文中绘制的所有线条均使用该钢笔,直到选择另一支不同的钢笔为止。CGdiexampleDlg::OnGdiDrawLine函数中的下列语句完成的就是这个功能:
//创建绘制正旋曲线的pen并将其选入设备上下文 CPen pen(PS_SOLID,1,RGB(255,0,0)); HGDIOBJ oldObject = dc.SelectObject(pen.GetSafeHandle()); … //创建绘制x轴的pen并将其选入设备上下文 CPen penx(PS_SOLID,1,RGB(0,0,255)); dc.SelectObject(penx.GetSafeHandle()); … //恢复原先的pen dc.SelectObject(oldObject); | 但是,在GDI+中,只需将Pen对象直接作为参数传递给Graphics类的DrawLine等方法即可,而不必使Pen对象与Graphics对象关联,例如CGdiexampleDlg::OnGdipDrawLine函数中的下列语句:
Pen myPen(Color::Red); myPen.SetWidth(1); … graphics.DrawLine(&myPen,i,100*sin(2*(i/(rect.right/5.0))*PI), i+1,100*sin(2*((i+1)/(rect.right/5.0))*PI)); … graphics.DrawLine(&myPen,0,0,rect.right,0); | GDI中有当前位置的概念,所以在使用GDI绘制线条前应该先使用MoveTo移动当前位置,再使用LineTo画线,例如:
//绘制正旋曲线 dc.MoveTo(0,0) ; for(int i=0;i<rect.right;i++) { dc.LineTo(i,100*sin(2*(i/(rect.right/5.0))*PI)); } | 而GDI+中则没有当前位置的概念,画线函数中可以直接指定起点和终点,例如:
| graphics.DrawLine(&myPen,0,0,rect.right,0); | 6.结论
鉴于GDI+良好的易用性和其具有的强大功能,我们建议尽快抛弃GDI编程方式,因为我们没有必要将时间浪费在无意义的重复代码的设计上。GDI+对GDI的增强,某种意义上类似于MFC对Windows API的整理和封装。作为一种良好的"生产工具",它必将大大地促进开发时的"生产力"。
|