本文共 11036 字,大约阅读时间需要 36 分钟。
CDC中
CDC->StretchBlt(int x,int y,int nWidth,int nHeight,CDC *pSrcDC, int xSrc, int ySrc, int nSrcWidth, int nSrcHeight,DWORD dwRop)
CDC->BitBlt(int x, int y, int nWidth,int nHeight,CDC *pSrcDC, int xSrc, int ySrc,DWORD dwRop)
HDC中
1.
HDC.StretchBlt(HDC hDestDC, int xDest,int yDest,int nDestWidth,int nDestHeight,DWORD dwRop)
2.
HDC.StretchBlt(HDC hDestDC, const RECT &rectDest,DWORD dwRop)
3.
HDC.StretchBlt(HDC hDestDC, int xDest,int yDest,int nDestWidth,int nDestHeight,, int xSrc, int ySrc, int nSrcWidth, int nSrcHeight, DWORD dwRop)
4.
HDC.StretchBlt(HDC hDestDC, const RECT &rectDest,const RECT &rectSrc, DWORD dwRop)
1.
HDC.BitBlt(HDC hDestDC, int xDest,int yDest,DWORD dwRop)
2.
HDC.BitBlt(HDC hDestDC, const POINT &pointDest,DWORD dwRop)
3.
HDC.BitBlt(HDC hDestDC, int xDest,int yDest,int nDestWidth,int nDestHeight,int xSrc, int ySrc, DWORD dwRop)
4.
HDC.BitBlt(HDC hDestDC, const RECT &rectDest, const POINT &pointSrc,DWORD dwRop)
//
pDC 是 类指针 HDC 是 windows句柄
/ 通过pDC获得hdc: HDC hdc=pDC->GetSafeHdc();
/ 通过hdc获得pDC: CDC *pDC=new CDC; pDC->Attach(hdc);
补充:CImage
CImage image; CRect m_rcShow;
CDC *pShowDC = m_bmpShow.GetDC(); //m_bmpShow为Picture控件变量 m_bmpShow.GetWindowRect(&m_rcShow); image.Load(TEXT("e:\1.jpg"));
//在picture控件里显示图片 image.Draw(pShowDC->m_hDC,0,0,m_rcShow.Width(),m_rcShow.Height(),
0,0,image.GetWidth(),image.GetHeight());
m_bmpShow.ReleaseDC(pShowDC);
//*************************
StretchBlt函数缩放图片后图片失真严重,所以要用SetStretchBltMode函数来设置 StretchBlt(或StretchDIBits)函数的伸缩模式。具体用法是 调用StretchBlt前调用: SetStretchBltMode(pDC->m_hDC,STRETCH_HALFTONE);
//***************************MFC画图
MFC画图类包含画图设备类和画图对象类 1 画图设备类 CDC类-父类是CObject,封装的是一般的画图设备,比如:显示器, 打印机等。 CWindowDC类-父类是CDC类。封装的是窗体对象,包含客户区和非 客户区。 CClientDC类-父类是CDC类,封装的仍然是窗体。可是仅仅包含客户区。CPaintDC类-父类是CDC类,封装的是窗体的客户区。可是,它仅仅用 在窗体的WM_PAINT消息处理函数中。 CMetaFileDC类-父类是CDC类,作用保存绘制命令。 2 使用 创建MFC AppWizard(exe)project,加入菜单项。然后使用类向导生成消息命令的函数体框架。 2.1 CDC::CreateDC()-创建画图设备 virtual BOOL CreateDC( LPCTSTR lpszDriverName,//设备的驱动名称 LPCTSTR lpszDeviceName,//设备名称 LPCTSTR lpszOutput,//接口 const void* lpInitData//设备的初始化參数 ); 设备为显示器时,("DISPLAY",NULL,NULL,NULL); 2.2 使用 .... 2.3 CDC::DeleteDC()-删除设备 2.4 CDC的子类CWindowDC、CClientDC、CPaintDC,在构造函数中 调用CreateDC(),在析构函数中调用DeleteDC(),所以,子类使用 仅仅须要构造对象就可以。 2.5 CMetaFileDC类的使用 2.5.1 创建 CMetaFileDC::Create 2.5.2 绘制 .... 2.5.3 关闭。返回句柄 HMETAFILE CMetaFileDC::Close 2.5.4 使用 CDC::PlayMetaFile 2.5.5 删除 DeleteMetaFile 3 画图对象类 3.1 CPen-画笔 3.2 CBrush-画刷 3.3 CFont-字体 3.4 CBitmap-位图 3.5 CRgn-区域 3.6 CPalette-调色板 RGB(0~255,0~255,0~255),每一个颜色值占3个字节。 彩色位图,800*600像素,位图大小是:800*600*3 字节 颜色表大小 48*3 +800*600*1 3.7 使用 3.7.1 CPen、CBrush、CFont的使用 3.7.2 CBitmap的使用 3.7.3 CRgn的使用 1 创建 CRgn::CreateXXX 2 将两个CRgn对象进行几何运算 CRgn::CombineRgn 3 填充 CDC::FillRgn 4 填充边框
CDC::FrameRgn
程序演示样例:
在****view类中,定义一个成员变量:
HMETAFILE m_hMetafile;
//功能实现部分主要代码
void CMFCdrawView::OnDcCwindowdc() { // TODO: Add your command handler code here CWindowDC dc(AfxGetMainWnd()); dc.TextOut(0,0,"Hello CWindowDC");}void CMFCdrawView::OnDcCmetafiledc() { // TODO: Add your command handler code here //创建 CMetaFileDC dc; dc.Create(); //绘制命令 dc.TextOut(100,100,"DcCmetafile"); dc.MoveTo(150,150); dc.LineTo(200,200); //关闭,并返回句柄 m_hMetafile= dc.Close(); CClientDC dc2(this); dc2.PlayMetaFile(m_hMetafile);}void CMFCdrawView::OnDcCclientdc() { // TODO: Add your command handler code here CClientDC dc(this); dc.TextOut(0,0,"Hello CClientDC");}void CMFCdrawView::OnDcCdc() { // TODO: Add your command handler code here CDC dc; dc.CreateDC("DISPLAY",NULL,NULL,NULL);//打印到屏幕上 RECT rc={0}; rc.left=0;rc.right=200;rc.top=0;rc.bottom=100; dc.DrawText("hello cdc",&rc,DT_MODIFYSTRING); dc.DeleteDC();}void CMFCdrawView::OnPaint() { CPaintDC dc(this); // device context for painting dc.TextOut(0,20,"Hell0 Paint"); //使用CMetaFile if(m_hMetafile) dc.PlayMetaFile(m_hMetafile); //OnGdiBitmap(); // Do not call CView::OnPaint() for painting messages}void CMFCdrawView::OnGdiBitmap() { // TODO: Add your command handler code here CClientDC dc(this); CDC dcBitmap;//内存dc dcBitmap.CreateCompatibleDC(&dc); CBitmap bmp;//位图对象 bmp.LoadBitmap(IDB_BITMAP1);//插入的图片资源 CBitmap*oldbmp=dcBitmap.SelectObject(&bmp);//放入内存dc //dc.BitBlt(300,300,110,37,&dcBitmap,0,0,SRCCOPY);//成像 RECT rc={0}; GetClientRect(&rc); //拉伸成像 dc.StretchBlt(0,0,rc.right,rc.bottom,&dcBitmap,0,0,101,37,SRCCOPY); dcBitmap.SelectObject(oldbmp); dcBitmap.DeleteDC();//删除内存dc bmp.DeleteObject();//删除位图对象 }void CMFCdrawView::OnGdiBrush() { // TODO: Add your command handler code here //CBrush brush(HS_CROSS,RGB(0,255,0));//普通画刷 CBitmap bmp;bmp.LoadBitmap(IDB_BITMAP2); CBrush brush(&bmp);//位图画刷 CClientDC dc(this); CBrush*oldbrush=dc.SelectObject(&brush); dc.RoundRect(50,50,220,220,2,2); dc.SelectObject(oldbrush); brush.DeleteObject(); }void CMFCdrawView::OnGdiFont() { // TODO: Add your command handler code here CFont font; font.CreatePointFont(500,"黑体"); CClientDC dc(this); CFont*oldfont=dc.SelectObject(&font); dc.TextOut(150,150,"OnGdiFont"); dc.SelectObject(oldfont); font.DeleteObject();}void CMFCdrawView::OnGdiPen() { // 创建画笔 CPen pen(PS_SOLID,5,RGB(255,0,0)); //将画笔选择当前设备 CClientDC dc(this); CPen * oldpen=dc.SelectObject(&pen); dc.TextOut(10,10,"OnGdiPen"); dc.RoundRect(100,100,200,200,2,2); dc.SelectObject(oldpen); pen.DeleteObject(); }void CMFCdrawView::OnGdiRgn() { CRgn rgn1,rgn2; //创建 rgn1.CreateEllipticRgn(100,100,300,300); rgn2.CreateEllipticRgn(150,100,350,300); //几何运算 rgn1.CombineRgn(&rgn1,&rgn2,RGN_XOR); //填充 CClientDC dc(this); CBrush brush(RGB(255,0,0)); CBrush brush2(RGB(0,0,255)); dc.FillRgn(&rgn1,&brush); //dc.FillRgn(&rgn2,&brush2); //填充边框 dc.FrameRgn(&rgn1,&brush2,5,1); //将窗体的区域设置成rgn1 AfxGetMainWnd()->SetWindowRgn(rgn1,TRUE);}
效果:
2、
简单的鼠标画图的样例
1 图形数据,1 起点和终点,CPoint; 2 使用整数变量确定当前绘制的图形 UINT m_nType; m_nType=1;直线 m_nType=2;矩形 m_nType=3;椭圆 m_nType=0;不绘制图形 3 BOOL m_bFlag;//标识是否開始画线 2 绘制过程 2.1 LBUTTONDOWN消息 m_bFlag=TRUE;//開始画图 m_ptBegin=m_ptEnd=point; //确定起点位置 2.2 MOUSEMOVE消息 if(m_bFlag) { //擦线 //画线 } 2.3 LBUTTONUP消息 m_bFlag=FALSE;//结束画线模拟画图软件,鼠标点下进行画图。放开则绘制指定的图形。
新建立 MFC 应用程序,并依照例如以下操作:
在****view 中,增加成员变量:
CPoint m_ptBegin;//起点坐标
CPoint m_ptEnd;//终点坐标 UINT m_nType;//类型:1-直线,2-距形。3-圆 BOOL m_bFlag;//是否開始画线
****view中主要实现代码:
//构造函数CMFCdraw2View::CMFCdraw2View(){ // TODO: add construction code here m_nType=0; m_bFlag=FALSE; m_ptBegin=m_ptEnd=0;}void CMFCdraw2View::OnDrawElipse() { // TODO: Add your command handler code here m_nType=3;}void CMFCdraw2View::OnDrawLine() { // TODO: Add your command handler code here m_nType=1;}void CMFCdraw2View::OnDrawRect() { // TODO: Add your command handler code here m_nType=2;}void CMFCdraw2View::OnLButtonDown(UINT nFlags, CPoint point) { // TODO: Add your message handler code here and/or call default m_bFlag=TRUE;//開始画图 m_ptBegin=m_ptEnd=point; //确定起点位置 CView::OnLButtonDown(nFlags,point);}void CMFCdraw2View::OnLButtonUp(UINT nFlags, CPoint point) { // TODO: Add your message handler code here and/or call default m_bFlag=FALSE;//结束画线 CView::OnLButtonUp(nFlags, point);}void CMFCdraw2View::OnMouseMove(UINT nFlags, CPoint point) { // TODO: Add your message handler code here and/or call default CClientDC dc(this); if(m_bFlag) { //擦线 DrawShape(&dc,m_ptBegin,m_ptEnd); //画线 DrawShape(&dc,m_ptBegin,point); //保存终点位置,为擦线准备 m_ptEnd=point; } CView::OnMouseMove(nFlags, point);}void CMFCdraw2View::DrawShape(CDC *pDC, CPoint p1, CPoint p2){ //设置画图模式,R2_NOT与当前画线处颜色相反 pDC->SetROP2(R2_NOT); //设置画刷为透明画刷 CBrush *pOldBrush= (CBrush*)pDC->SelectStockObject(NULL_BRUSH); switch (m_nType) { case 1://直线 pDC->MoveTo(p1); pDC->LineTo(p2); break; case 2://矩形 pDC->Rectangle(p1.x,p1.y,p2.x,p2.y); break; case 3://椭圆 pDC->Ellipse(p1.x,p1.y,p2.x,p2.y); break; } //恢复默认画刷 pDC->SelectObject(pOldBrush); }void CMFCdraw2View::OnUpdateDrawElipse(CCmdUI* pCmdUI) { // TODO: Add your command update UI handler code here pCmdUI->SetRadio(m_nType==3);//更改选中的状态}void CMFCdraw2View::OnUpdateDrawLine(CCmdUI* pCmdUI) { // TODO: Add your command update UI handler code here pCmdUI->SetRadio(m_nType==1);}void CMFCdraw2View::OnUpdateDrawRect(CCmdUI* pCmdUI) { // TODO: Add your command update UI handler code here pCmdUI->SetRadio(m_nType==2);}
//*********************************************
StretchBlt和BitBlt都用在双缓冲视图中,用来显示一幅图像
一、StretchBlt
函数从源矩形中复制一个位图到目标矩形,必要时按目标设备设置的模式进行图像的拉伸或压缩。也即是将内存中的位图拷贝到屏幕上,并且可以根据屏幕画图区的大小来进行伸缩,适应响应的屏幕(或图像控件)
BOOL StretchBlt( int x, int y, int nWidth, int nHeight, CDC* pSrcDC, int xSrc, int ySrc, int nSrcWidth, int nSrcHeight, DWORD dwRop );x :逻辑单元x轴左上角坐标; (获取图像控件的DC后,该值一般设为 0 ) y :逻辑单元y轴左上角坐标; (获取图像控件的DC后,该值一般设为 0 ) nWidth : 设备矩形宽度;(即是图像控件的宽度,通过int rcWidth = rc.right - rc.left;来获得,rc为保存了图像控件矩形区坐标信息)nHeight :设备矩形高度; (即是图像控件的高度,通过int rcHeight = rc.bottom - rc.top;来获得)pSrcDC : 源设备上下文; (就是我们定义的内存DC,然后取地址)xSrc :源矩形x轴左上角坐标; (一般都是整幅图片拷贝,所以该值为 0 )ySrc : 源矩形y轴左上角坐标; (一般都是整幅图片拷贝,所以该值为 0 )nSrcWidth:源矩形宽度;(如果我们定义了一个结构体BITMAP类型m_bmp保存位图信息,那么可以用m_bmp.bmWidth获取宽度)nSrcHeight:源矩形高度 ( 如果我们定义了一个结构体BITMAP类型m_bmp保存位图信息,那么可以用m_bmp.bmHeight获取宽度)dwRop :指定要进行的光栅操作。(这个有很多选择,我们一般选择SRCCOPY:将源矩形区域直接拷贝到目标矩形区域。)
二、BitBlt函数
该函数对指定的源设备环境区域中的像素进行位块(bit_block)转换,以传送到目标设备环境。
BOOL BitBlt( int x, int y, int nWidth, int nHeight, CDC* pSrcDC, int xSrc, int ySrc, DWORD dwRop );BitBlt函数和上面的STretchBlt函数的参数基本上差不多,只是少了倒数第二个和倒数第三个参数:nSrcWidth:源矩形宽度; 以及,nSrcHeight:源矩形高度 前面四个参数也是和目标矩形(也即是我们的图像控件区域)相关的,如果是图像控件的话,起点坐标也是(0,0),终点坐标就是矩形区的宽度和高度;对于源矩形区域(指内存DC中的位图),只需要给出拷贝的起点即可,
BitBlt函数不会对原来的位图进行拉伸或压缩,只会根据我们给定的nWidth,nHeight 值来决定该有多少部分进行显示
下面一段代码给出了这两个函数的具体用法:
void CEnvirMonibeta1View::ShowBitmap(CDC *pDC, CString TotalName, const RECT &rc){ //显示图片函数LoadImage 根据位图(或图片)的全路径名TotalName加载图片 HBITMAP m_hBitmap; m_hBitmap = (HBITMAP) LoadImage( NULL, TotalName, IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE|LR_DEFAULTSIZE|LR_CREATEDIBSECTION ); // 之前在类中定义了一个CBitmap 类的对象m_bitmap, if(m_bitmap.m_hObject){ m_bitmap.Detach(); // m_bitmap为创建的位图对象 } m_bitmap.Attach(m_hBitmap); // 让位图对象m_bitmap 和我们加载的位图相关联 //定义并创建一个内存设备环境 CDC m_dcMemory; if( !m_dcMemory.CreateCompatibleDC(pDC) ) // 创建兼容性的DC return; //定义一个位图结构体,将图片信息保存在位图结构体中 BITMAP bitmap; m_bitmap.GetBitmap(&bitmap); CBitmap *pbmpOld = NULL; m_dcMemory.SelectObject(&m_bitmap); // 将位图选入临时内存设备环境 //获取屏幕画图区域(图像控件)的宽度和高度 int rcWidth = rc.right - rc.left; int rcHeight = rc.bottom - rc.top; //图片显示调用函数BitBlt pDC->BitBlt(0,0,rcWidth,rcHeight,&dcBmp,0,0,SRCCOPY); // 如果希望图片和矩形区域能自动适配,可以用下面的函数 pDC->StretchBlt(0,0,rcWidth,rcHeight,&dcBmp,0,0,bitmap.bmWidth,bitmap.bmHeight,SRCCOPY); //下面是一些善后工作 dcBmp.SelectObject(pbmpOld); // 恢复临时DC的位图 DeleteObject(&m_bitmap); // 删除位图 dcBmp.DeleteDC(); // 删除后台DC // Invalidate(); // 一直调用OnDraw显示图片}
转载地址:http://qsmws.baihongyu.com/