《VC++深入详解》学习笔记 第十章 绘图控制

1.简单绘图

1)画点:CDC类的成员函数SetPixel

     函数原型:COLORREF SetPixel(POINT point,COLORREF crColor);

2)画直线:CDC类的成员函数MoveToLineTo

3)画矩形:CDC类的成员函数Rectangle,参数为一个指向CRect对象的指针,要先建一个矩形对象

4)画椭圆:CDC类的成员函数Ellipse

5)设置:1.响应函数OnSetting

           2.设置对话框类CSettingDlg

           3.响应函数中添加代码:(设置画笔宽度)

             CSettintDlg dlg;

             If(IDOK == dlg.DoModal())

             {

               m_nLineWidth = dlg.m_nLineWidth;

             }

2.颜色对话框:MFC提供的类CColorDialog

1CColorDialogCCommonDialogCDialogCWnd

2)构造方法:CColorDialogclrInit = 0,DWORD dwFlags = 0,CWnd* pParentWnd = NULL;

//第一个参数指定默认的颜色选择,默认是黑色

//第二个参数是一组标记,用来定制颜色对话框的功能和它的外观

//第三个参数指向颜色对话框父窗口或拥有者的指针

3)将选择的颜色保存下来:CColorDialog类的CHOOSECOLOR结构体成员变量m_ccrgbResult中保存了颜色  COLORREF  m_clr = dlg.m_cc.rgbResult;

4)若要设置颜色对话框选择的颜色,则需要设置该对话框的CC_RGBINIT标记(第二个参数中设置)  dlg.m_cc.Flags |= CC_RGBINIT;

3.字体对话框:MFC提供的CFontDialog

1CFontDialogCCommonDialogCDialogCWnd

2)构造方法:CFontDialog

                 LPLOGFONT lplfInitial = NULL,//指向结构体指针,设置字体特征

                 DWORD dwFlags = CF_EFFECTS | CF_SCREENFONTS,//设置一个或多个与选择的字体相关的标记

                 CDC* pdcPrinter = NULL,//指向打印设备上下文的指针

                 CWnd* pParentWnd = NULL//指向字体对话框父窗口的指针

);

3)将选择的字体保存下来:CFontDialog类的CHOOSEFONT结构体类型的数据成员m_cf的成员lpLogFont指向逻辑字体LOGFONT结构体类型,该类型的lfFaceName中存放的就是字体的名称

    1.字体对象的创建,首先利用CFont类构造一个字体对象,然后利用CFont类的

       CreateFontIndirect成员函数根据指定特征的逻辑字体(LOGFONT类型)初始化

函数原型:BOOL CreateFontIndirectconst LOGFONT* lpLogFont;

      m_font.CreateFontIndirect(dlg.m_cf.lpLogFont);

      m_strFontName = dlg.m_cf.lpLogFont->lfFaceName;

    2.调用Invalidate函数可以让窗口无效,这样当下一次发生WM_PAINT消息时,窗口就会进行重绘

4)下一次再选字体时,程序出错,因为第一次选择字体后调用CreateFontIndirectm_font对象和这种字体资源关联了,所以要进行判断,若已关联,则断开关联,释放该字体资源,然后关联新的资源

     1.释放资源用CGdiObject类(CPenCFontCBitmapCBrush都派生于该类)的DeleteObject成员函数实现,该函数通过释放所有为Windows GDI对象所分配的资源,从而删除与CGdiObject对象相关联的Windows GDI对象,同时与CGdiObject对象相关联的存储控件不会收到影响(即释放资源不影响对象,指示二者关联切断了)

     2.判断字体对象是否与资源相关联,最简单的办法是利用CGdiObject对象的数据成员m_hObject来判断

     If(m_font.m_hObject)  m_font.DeleteObject();

4.示例对话框

1)对编辑框控件来说,当用户在其上面对文本进行改变时,它会向其父窗口(即对话框)发送一个EN_CHANGE通知消息,同样,当用户单击单选按钮时,该按钮会向对话框发送BN_CLICKED消息

2)捕获消息并添加响应代码

3)在设置对话框增加一个组框,并将其Caption设置为:示例

4)在组框中绘图,那么先得到组框的矩形区域,可以调用GetDlgItem函数得到组框指针,然后利用GetWindowRect函数获得组框窗口区域的大小(该函数得到的是屏幕坐标,而我们需要的是对话框坐标,需要用ScreenToClient函数将其由屏幕坐标转换为客户坐标)

   函数原型:void ScreenToClient(LPRECT lpRect) const;

5)当一个控件和一个成员变量相关联时,如果想让控件上的值反映到成员变量上,必须调用UpdateDate函数

5.改变对话框和控件的背景及文本颜色

1WM_CTLCOLOR消息,响应函数是CWnd类的OnCtlColor,该函数的声明形式如下:

Afx_msg HBRUSH OnCtlColor(CDC* pDC,CWnd* pWnd,UINT nCtlColor);

//pDC 指向当前要绘制的控件的显示上下文指针,pWnd 指向当前要绘制的控件的指针

//nCtlColor 指定当前要绘制的控件的类型

//该函数将返回将被用来绘制控件背景的画刷的句柄,当一个子控件将要被绘制时,它都回向它的父窗口(对话框)发送一个WM_CTLCOLOR消息来准备一个设备上下文,以便使用正确的颜色来绘制该控件,如果想要改变该控件上的文本颜色,可以在OnCtrColor函数中以指定的颜色为参数调用SetTextColor函数来实现

2)改变整个对话框及其上子控件的背景色

      1.为程序的设置对话框捕获WM_CTLCOLOR消息,并添加响应函数

      2.在函数中注释掉原来的画刷,自己创建一个画刷(类的私有成员)并返回

3)仅改变某个子控件的背景及文本颜色

      1.得到控件IDOnCtrColor函数参数pWnd 指向当前要绘制的控件)用CWnd类的GetDlgCtrlID成员函数得到该控件的ID

        PWnd->GetDlgCtrlID()

      2.将得到的ID与要改变的控件比较,若是,则改变

      3.调用SetTextColor可以设置控件上文本的颜色

      4.将文字的背景色设为透明的 pDC->SetBkMode(TRANSPARENT);

        IfpWnd->GetDlgCtrlID() == IDC_LINE_WIDTH

       {

         pDC->SetTextColor(RGB(255,0,0));

         pDC->SetBkMode(TRANSPARENT);

         return  m_brush;

        }

      5.如果要改变单行编辑框控件的背景颜色,除了设置背景画刷句柄外,还要调用SetBkColor函数设置其背景色,因为编辑框控件的背景为透明这一操作没有意义

4)改变控件上的文本字体

     创建字体m_font=CreatePointFont,判断控件ID,改变字体SelectObject&m_font

5)改变按钮控件的背景色及文本色

      1.对按钮来说,使用以上的办法来改变其背景和文本颜色是无效的

      2.要改变按钮控件的背景色和文本色,需要使用CButton类的成员函数DrawItem

        函数原型:virtual void DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct);

//当一个自绘制按钮(BS_OWNERDRAW风格的按钮)在绘制时,框架将会调用这个虚函数

//所以要重载这个虚函数,该函数的参数是DRAWITEMSTRUCT结构类型,该结构体中有一

//hDC成员,指向将要绘制的按钮的DC,为了绘制这个按钮,可以向该DC中选入颜色、//画刷等,需要注意的是,在此重载函数结束前,一定要恢复hDC中原有对象

     3.要想改变按钮的文本颜色,要编写一个自己的按钮类,让这个类派生于CButton类,并重写DrawItem函数,在其中实现设置,然后将按钮与这个类相关联,这样绘制按钮时,框架类就会调用这个自定义的DrawItem函数来绘制

     4.用新建的类定义对象

     5.将按钮的Owner draw风格选上(自绘控件应该具有此风格:BS_OWNERDRAW

     6.ClassWizardAdd Member Variable对话框,为对话框上的按钮关联成员变量

     7.CButtonST类(网上找个一个按钮类,功能比较齐全)

6.位图的显示

1)创建位图: Cbitmap bitmap;

                bitmap.LoadBitmap(IDB_BITMAP1);

2)创建兼容DC  CDC dcCompatible;

                    dcCompatible.CreateComPatibleDC(pDC);

    该函数创建一个内存设备上下文,与参数pDC所指定的DC相兼容,内存设备上下文实际上是一个内存块,表示一个显示的表面,如果想把图像复制到实际的DC中,可以先用其兼容的内存设备上下文在内存中准备这些图像,然后再将这些数据复制到实际DC

3)将位图选入兼容DC中:dc.Compatible.SelectedObject(&bitmap);

    当兼容的内存设备上下文被创建时,它的显示表面是标准的一个单色像素宽和一个单色像素高,在程序中可以使用内存设备上下文进行绘图之前,必须将一个具有正确高度和宽度的位图选入设备上下文,这时,它的显示表面就由选入的位图决定了

4)将兼容DC中的位图贴到当前DC中:

        pDC->BitBlt(rect.left,rect.top,rect.Width(),rect.Height(),&dcCompatible,0,0,SRCCOPY);

        将兼容DC中的位图贴到当前DC中,有多个函数可以以不同方式完成这一操作

       函数原型:BOOL BitBltint x,int y,int nWidth,int nHeight,CDC* pSrcDC,

int xSrc,int ySrc,DWORD dwRop;

//xy指定目标矩形区域左上角坐标;nWidthnHeigh指定源和目标矩形区域的逻辑宽

//度和高度;pSrcDC指定源设备上下文对象;xSrcySrc指定源矩形区域坐上角的坐标

// dwRop指定复制的模式,也就是指定源矩形区域的颜色数据,如何与目标矩形区域的颜

//色数据组合得到最后的颜色

5)檫除窗口背景时,程序会发送一个WM_ERASEBKGND消息,在视类添加响应该消息的函数并填写代码(也可以在OnDraw函数中填写代码实现)

CBitmap bitmap;

          bitmap.LoadBitmap(IDB_BITMAP1);

          CDC dcCompatible;

          dcCompatible.CreateCompatibleDC(pDC);

          dcCompatible.SelectObject(&bitmap);

          CRect rect;

          GetClientRect(&rect);

          pDC->BitBlt(0,0,rect.Width(),rect.Height(),&dcCompatible,0,0,SRCCOPY);

          return TRUE;

//return CView::OnEraseBkgnd(pDC);

6BitBlt函数没有办法实现压缩和拉伸,因为它时11复制的,这个功能我们可以用另一个函数实现:StretchBlt

函数原型:BOOL StretchBlt(int x,int y,int nWidth,int nHeight,CDC* pSrcDC,int xSrc,int ySrc,int nSrcWidth,int nSrcHeight,DWORD dwRop);

// 该函数多了nSrcWidthnSrcHeight两个参数,分别用来指示源矩形区域的宽度和高度

得到位图的高度和宽度可以用函数:GetBitmap

函数原型:int GetBitmap(BITMAP* pBitMap);

//该函数有一个指向BITMAP的结构体指针参数,该函数将用位图信息填充这个结构体

你可能感兴趣的:(《VC++深入详解》学习笔记)