1.简单绘图
(1)画点:CDC类的成员函数SetPixel
函数原型:COLORREF SetPixel(POINT point,COLORREF crColor);
(2)画直线:CDC类的成员函数MoveTo和LineTo
(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
(1)CColorDialog—CCommonDialog—CDialog—CWnd
(2)构造方法:CColorDialog(clrInit = 0,DWORD dwFlags = 0,CWnd* pParentWnd = NULL);
//第一个参数指定默认的颜色选择,默认是黑色
//第二个参数是一组标记,用来定制颜色对话框的功能和它的外观
//第三个参数指向颜色对话框父窗口或拥有者的指针
(3)将选择的颜色保存下来:CColorDialog类的CHOOSECOLOR结构体成员变量m_cc的rgbResult中保存了颜色 COLORREF m_clr = dlg.m_cc.rgbResult;
(4)若要设置颜色对话框选择的颜色,则需要设置该对话框的CC_RGBINIT标记(第二个参数中设置) dlg.m_cc.Flags |= CC_RGBINIT;
3.字体对话框:MFC提供的CFontDialog
(1)CFontDialog—CCommonDialog—CDialog—CWnd
(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 CreateFontIndirect(const LOGFONT* lpLogFont);
m_font.CreateFontIndirect(dlg.m_cf.lpLogFont);
m_strFontName = dlg.m_cf.lpLogFont->lfFaceName;
2.调用Invalidate函数可以让窗口无效,这样当下一次发生WM_PAINT消息时,窗口就会进行重绘
(4)下一次再选字体时,程序出错,因为第一次选择字体后调用CreateFontIndirect将m_font对象和这种字体资源关联了,所以要进行判断,若已关联,则断开关联,释放该字体资源,然后关联新的资源
1.释放资源用CGdiObject类(CPen,CFont,CBitmap,CBrush都派生于该类)的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.改变对话框和控件的背景及文本颜色
(1)WM_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.得到控件ID(OnCtrColor函数参数pWnd 指向当前要绘制的控件)用CWnd类的GetDlgCtrlID成员函数得到该控件的ID
PWnd->GetDlgCtrlID()
2.将得到的ID与要改变的控件比较,若是,则改变
3.调用SetTextColor可以设置控件上文本的颜色
4.将文字的背景色设为透明的 pDC->SetBkMode(TRANSPARENT);
If(pWnd->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.在ClassWizard的Add 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 BitBlt(int x,int y,int nWidth,int nHeight,CDC* pSrcDC,
int xSrc,int ySrc,DWORD dwRop);
//x和y指定目标矩形区域左上角坐标;nWidth和nHeigh指定源和目标矩形区域的逻辑宽
//度和高度;pSrcDC指定源设备上下文对象;xSrc和ySrc指定源矩形区域坐上角的坐标
// 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);
(6)BitBlt函数没有办法实现压缩和拉伸,因为它时1:1复制的,这个功能我们可以用另一个函数实现:StretchBlt
函数原型:BOOL StretchBlt(int x,int y,int nWidth,int nHeight,CDC* pSrcDC,int xSrc,int ySrc,int nSrcWidth,int nSrcHeight,DWORD dwRop);
// 该函数多了nSrcWidth和nSrcHeight两个参数,分别用来指示源矩形区域的宽度和高度
得到位图的高度和宽度可以用函数:GetBitmap
函数原型:int GetBitmap(BITMAP* pBitMap);
//该函数有一个指向BITMAP的结构体指针参数,该函数将用位图信息填充这个结构体