课程设计论文-基于vcmfc程序设计--简易画图板内容摘要:

CView::OnLButtonDown(nFlags, point)。 } 在鼠标左键弹起消息响应函数中实现绘图,代码如下: void CGraphicView::OnLButtonUp(UINT nFlags, CPoint point) { 10 // TODO: Add your message handler code here and/or call default //创建并获得设备描述 CClientDC dc(this)。 switch (m_nDrawType) { case 1: (point,RGB( 255,0,0) )。 /*绘制点 */ break。 case 2: /*绘制直线 */ (m_ptOrigin)。 /*调用 MoveTo 函数移动到原点 */ (point)。 /*调用 LineTo 函数绘制到终点。 */ break。 case 3: /*绘制矩形 */ (CRect(m_ptOrigin,point))。 break。 case 4: /*绘制椭圆 */ (CRect(m_ptOrigin,point))。 break。 CView::OnLButtonUp(nFlags, point)。 } 在上述程序中,设置一个点,用到的函数是 SetPixel,这也是 CDC 类的一个成员方法,该函数的生命形式如下: COLORREF SetPixel ( POINT point, COLORREF crColor);该函数是在指定的点设置一个像素。 其中第一个参数( point)是指定的点,第二个参数( crColor)是指定的颜色。 在程序中设定的颜色在系统颜色表中可能不存在,但系统会选择一种和这个颜色最接近的颜色。 RGB 是一个宏,它有三个参数,分别代表红、绿、蓝三种颜色的值。 这三个参数 BYTE 类型,取值范围为 0~255。 RGB( 0,0,0)是黑色, RGB( 255,255,255)是白色,将这三个分量设置成为 0~255之间的任意值,从而得到各种不同的颜色。 这里的 RGB( 255,0,0)是红色。 绘制 直线时,首先调用 MoveTo 函数移动到原点,然后调用 LineTo 函数绘制到终点。 绘制矩形时使用 Rectangle 函数,该函数声明形式为: BOOL Rectangle ( LPCRECT lpRect); 该函数有一个指向 Crect 对象的参数,后者可以利用两个点来构造。 需要注意的是该函数需要的是指向 Crect 对象的指针,而上述代码中传递的却是 Crect 对象,但运11 行编译时也能成功通过,运行时也不会报错,这是为什么呢。 我们知道 C 系列的语言都是强类型语言,如果类型不匹配的话,需要进行强制类型转换。 但这里为什么没有进 行这样的强制类型转换程序也可以通过呢。 实际上, Crect 类提供了这样一个成员函数:重载 LPCRECT 操作符,其作用是将 Crect 转换为 LPCRECT 类型。 因此,当在程序中给 Rectangle 函数的参数赋值时,如果它发现该参数是一个 Crect对象,它就会隐式地调用 LPCRECT 操作符,将 Crect 类型的对象转换为 LPRECT类型。 因此,在给函数传递参数时,如果我们看到的传递的数值类型和所需要的类型不匹配,但编译和运行都正确的情况时,就要想想这其中的缘由了。 当然,有的情况下可能是这些类型之间本来就可以互相转换, 例如 short 类型和 int 类型。 但是参数是对象类的话,就要考虑了,它选择的对象的构造方法进行的隐式转换,还是有其他重载的操作符。 当用户选择椭圆菜单项时,调用 Ellipes 函数绘制一个椭圆。 连续线和扇形的绘制 Windows 系统为我们提供了一个画图程序,在该程序中,利用画笔可以绘制连续的线条,下面我们设计绘制连续线和扇形。 为了绘制连续的线条,首先要得到线条的起点,这在前面已经实现。 然后需要捕获鼠标移动过程中的每一个点,这可以通过捕获鼠标移动消息( WM_MOUSEMOVE)来实现。 在此消息响应函 数中,在依次捕获的各个点之间绘制一条条非常短的线段,从而就可以绘制出一条连续的线条。 遵照这一思路,我们开始增加程序的功能。 首先为视类增加鼠标移动消息( WM_MOUSEMOVE)的响应函数( OnMouseMove)。 这样,只要鼠标在应用程序窗口中移动时都会进入到这个消息响应函数中。 但这并不是我们所期望的,我们希望在鼠标左键按下后开始绘图。 因此,我们需要有一个变量来表示鼠标左键是否按下这一状态,然后在鼠标移动消息响应函数中对这一变量进行判断。 当此变量为真,即鼠标左键已经按下去,我们开始绘图。 于是,为视类添加一 个 BOOL 型的私有变量 m_bDraw,当鼠标左键按下去时,此变量为真;当鼠标左键弹起时,此变量为假,这时,我们就不再绘制线条了。 该变量在视类头文件中的定义代码如下: Private: BOOL m_bDraw; 接下来在视类的构造函数中,将此变量初始化为 FALSE。 m_bdraw=FALSE; 当鼠标左键按下去时,在视类的 OnLButtonDown 函数中将此变量初始化为12 TRUE。 m_bdraw=TRUE; 当鼠标左键弹起时,在视类的 OnLButton 函数中将此变量初始化为假。 m_bdraw=FALSE; 然后在 OnMouseMove 函数中首先对 m_bdraw 变量进行判断,如果其值为真,说明鼠标左键已经按下去了,这时就可开始进行画线操作。 还有一点需要注意,因为每绘制一条线段后,下次应该从这条线段的终点开始继续绘制。 因此,绘制完当前线段后,应该修改线段的起点,将当前线段的终点作为下一条线段的起点,程序代码如下: void CGraphicView::OnMouseMove(UINT nFlags, CPoint point) { // TODO: Add your message handler code here and/or call default { //创建并获得设备描述 CClientDC dc(this)。 //创建宽度为 1 的实线红色画笔 CPen pen (PS_SOLID, 1, RGB( 255,0,0) )。 //把创建的画笔选入设备描述 CPen *pOldpen=(amp。 pen)。 if(m_bDraw==true) { (m_ptOrigin)。 (point)。 //修改线段的起点 m_ptOrigin=point。 } //恢复设备描述 (pOldpen)。 CView::OnMouseMove(nFlags, point)。 } 如果在上面绘制连续线条的程序中,保持每段小直线的起点不变,即以鼠标左键按下时的起点为起点不变,分别绘制到鼠标移动点的直线,这时就会出现扇形的效果。 也就是去掉上述代码 OnMouseMove 函数中修改线段起点的代码。 程序代 码如下: 13 void CGraphicView::OnMouseMove(UINT nFlags, CPoint point) { // TODO: Add your message handler code here and/or call default { //创建并获得设备描述 CClientDC dc(this)。 //创建宽度为 1 的实线红色画笔 CPen pen (PS_SOLID, 1, RGB( 255,0,0) )。 //把创建的画笔选入设备描述 CPen *pOldpen=(amp。 pen)。 if(m_bDraw==true) { (m_ptOrigin)。 (point)。 } //恢复设备描述 (pOldpen)。 CView::OnMouseMove(nFlags, point)。 } 画刷 再为此程序添加一个子菜单,菜单名称为“画刷”,并为其添加三个菜单项,分别用来控制不同的画刷。 MFC 提供了一个 CBrush 类,可以用来创建画刷对象。 画刷通常用来填充一块区域。 简单画刷、位图画刷、透明画刷,程序代码如下: void CDrawView::OnLButtonUp(UINT nFlags, CPoint point) { //创建一个红色画刷 CBrush brush(RGB(255,0,0))。 //创建并获得设备描述表 CClientDC dc(this)。 //利用红色画刷填充鼠标拖曳过程中形成的矩形区域 14 (CRect(m_ptOrigin,point),amp。 brush)。 //创建位图对象 CBitmap bitmap。 //加载位图资源 (IDB_BITMAP1)。 //创建位图画刷 CBrush brush(amp。 bitmap)。 //创建并获得设备描述表 CClientDC dc(this)。 //利用红色画刷填充鼠标拖曳过程中形成的矩形区域 (CRect(m_ptOrigin,point),amp。 brush)。 //创建并获得设备描述表 CClientDC dc(this)。 //创建一个空画刷 CBrush *pBrush = CBrush::FromHandle((HBRUSH)GetStockObject(NULL_BRUSH))。 //将空画刷选入设备描述表 CBrush *pOldBrush = (pBrush)。 //绘制一个矩形 (CRect(m_ptOrigin,point))。 //恢复先前的画刷 (pOldBrush)。 m_bDraw = FALSE。 CView::OnLButtonUp(nFlags, point)。 } 在简单画刷程序中,首先创建一个红色画刷;接着创建设备描述表对象;然后调用设备描述表对象的成员函数 FillRect,利用指定的画刷填充一块指定的矩形区域,而鼠标拖动过程中的起点和终点就决定了需要填充的矩形区域,因此,代码中通过 CRect 类利用鼠标拖动的起点和终点构造了这快矩形区域。 CRect 类提供了多个构造函数,这里使用的是下面这种构造函数,即通过指定矩形区域的左上角和右下角这两个点来构造一块矩形区域。 CRect( POINT topLeft, POINT bottomRight); 代码中的 CDC 类的成员函数 FillRect,该函数的功能是用指定的画刷填充一个15 矩形。 该函数将填充全部的矩形,包括上左边界,但不填充右底边界。 FillRect 函数的声明如下: void FillRect ( LPCRECT lpRect, CBrush* pBrush); 该函数有两个参数, lpRect 是指向一个 RECT 结构体或 CRect 对象的指针,该结构体或对象中包含了要填充的矩形的逻辑坐标。 pBrush 是指向用于填充矩形的画刷对象 的指针。 在位图画刷程序中, CBrush 类有下面这样一种构造函数。 CBrush ( CBitmap* pBitmap); 该构造函数要求一个 CBitmap 类型的指针, CBitmap 类是位图类,于是我们就会这样想:利用这个构造函数是否就可以创建一个位图画刷呢。 事实确实如此。 创建 CBitmap 对象时,仅调用其构造函数并不能得到一个有用的位图对象,还需要调用一个初始化函数来初始化这个位图对象。 CBitmap 类提供了多个初始化函数,例如, LoadBitmap、 CreateBitmap、 BitmapIndirect 等。 这里用 LoadBitmap 函数来加载一副位图,该函数的声明如下: BOOL LoadBitmap ( LPCTSTR lpszResourceName); BOOL LoadBitmap ( UINT nIDResource); 其中第二种声明需要一个资源 ID 作为参数。 首先给程序增加一个位图资源。 为一个工程创建资源有多种实现方法,其中一种方法可以利用【 Insert】菜单下的【 Resource… 】命令,在弹出的对话框中选择 Bitmap 资源类型,单击【 New】按钮,即可创建一个默认名称为。
阅读剩余 0%
本站所有文章资讯、展示的图片素材等内容均为注册用户上传(部分报媒/平媒内容转载自网络合作媒体),仅供学习参考。 用户通过本站上传、发布的任何内容的知识产权归属用户或原始著作权人所有。如有侵犯您的版权,请联系我们反馈本站将在三个工作日内改正。