图形的保存与重绘

1.创建图形

新建一个MFC单文档应用程序,仍然增加一个菜单,命名绘图,再添加几个菜单项:

IDM_POINT()IDM_LINE(直线)IDM_ RECTANGLE(矩形)IDM_ ELLIPSE (椭圆),并分别对这四个菜单项添加命令响应,并在CGraphic2View类中添加一个私有的成员变量UINT m_nDrawType;

并在构造方法中初始化:

CGraphic2View::CGraphic2View() 

    // TODO: add construction code here 
    m_nDrawType=0
    m_ptOrigin=0
    m_dcMetaFile.Create();//创建一个内存的CMetaFileDC对象
 

再编辑四个菜单项的命令响应:

void CGraphic2View::OnPoint()  

    // TODO: Add your command handler code here 
    m_nDrawType=1; 

 
void CGraphic2View::OnLine()  

m_nDrawType=2; 

 
void CGraphic2View::OnRectangle()  

    m_nDrawType=3; 

 
void CGraphic2View::OnEllipse()  

    m_nDrawType=4; 
}

再在CGraphic2View类中添加一个私有的成员变量m_ptOrigin用来保存原点坐标,并在构造函数中初始化,上面已列出。

接着再给CGraphic2View类添加两个WM_LBUTTONDOWNWM_LBUTTONUP消息响应函数,编辑:

void CGraphic2View::OnLButtonDown(UINT nFlags, CPoint point)  

m_ptOrigin=point;//将这个点保存起来 
    CView::OnLButtonDown(nFlags, point); 

 
void CGraphic2View::OnLButtonUp(UINT nFlags, CPoint point)  

    CClientDC dc(this); 
    CBrush *pBrush=CBrush::FromHandle((HBRUSH)GetStockObject(NULL_BRUSH)); 
    //
创建透明画刷 
    dc.SelectObject(pBrush);  
    } 
    switch(m_nDrawType) 
    { 
    case 1
        dc.SetPixel(point,RGB(0,0,0));         break
    case 2
        dc.MoveTo(m_ptOrigin); 
        dc.LineTo(point);         break
    case 3
        dc.Rectangle(CRect(m_ptOrigin,point));         break
    case 4
        dc.Ellipse(CRect(m_ptOrigin,point));         break
    } 

    CView::OnLButtonUp(nFlags, point); 
}

运行可以发现当窗口尺寸发现变化是,所绘制的图形也消失了!

 

2.图形重绘

新建一个Generic Class (name:CGraph),并在这个类当中增加3个成员变量,同时为了对这3个成员进行赋值,定义一个带参数的构造函数,如下:

public
    CPoint m_ptOrigin; 
    CPoint m_ptEnd; 
    UINT m_nDrawType; 
    CGraph(); 
    CGraph(UINT m_nDrawType,CPoint m_ptOrigin,CPoint m_ptEnd); 

并在源文件Graph.cpp当中,对这个类的成员变量赋值:

CGraph::CGraph(UINT m_nDrawType,CPoint m_ptOrigin,CPoint m_ptEnd) 

    //
对这个类的成员变量赋值 
    this->m_nDrawType=m_nDrawType;//
图形类型 
    this->m_ptOrigin=m_ptOrigin;//
图形原点 
    this->m_ptEnd=m_ptEnd;//
图形终点 
}
 

CGraphic2View类当中,新增加一个成员变量CPtrArray m_ptrArray; 这个集合类型的变量用来保存CGraph对象,并在CGraphic2View::OnLButtonUp添加:

CGraph graph(m_nDrawType,m_ptOrigin,point);//构造一个对象

//:此时graph是一个局部变量,为它分配的内存在栈中,当这个函数结束时,对象也会被析构

m_ptrArray.Add(&graph);//graph对象保存到集合类的对象m_ptArray当中

接下来在CGraphic2View::OnDraw函数中添加:

CBrush *pBrush=CBrush::FromHandle((HBRUSH)GetStockObject(NULL_BRUSH)); 
    //
创建透明画刷 
    pDC->SelectObject(pBrush); 
 
    //
将保存的图形对象取出来 
    for(int i=0;i    { 
        switch(((CGraph*)m_ptrArray.GetAt(i))->m_nDrawType) 
        { 
        case 1
            pDC->SetPixel(((CGraph*)m_ptrArray.GetAt(i))->m_ptEnd,RGB(0,0,0)); 
            break
        case 2
            pDC->MoveTo(((CGraph*)m_ptrArray.GetAt(i))->m_ptOrigin); 
            pDC->LineTo(((CGraph*)m_ptrArray.GetAt(i))->m_ptEnd); 
            break
        case 3
            pDC->Rectangle(CRect(((CGraph*)m_ptrArray.GetAt(i))->m_ptOrigin, 
                ((CGraph*)m_ptrArray.GetAt(i))->m_ptEnd)); 
            break
        case 4
            pDC->Ellipse(CRect(((CGraph*)m_ptrArray.GetAt(i))->m_ptOrigin, 
                ((CGraph*)m_ptrArray.GetAt(i))->m_ptEnd)); 
            break
        default
            break
        } 
    }

运行,当改变窗口大小时,图像仍然消息了,下面继续修改。

CGraphic2View::OnLButtonUp中修改:

//CGraph graph(m_nDrawType,m_ptOrigin,point);//构造一个对象 
    //
:此时graph是一个局部变量,为它分配的内存在栈中,当这个函数结束时,对象也会被析构 
    //m_ptrArray.Add(&graph);//
graph对象保存到集合类的对象m_ptArray当中 
    CGraph *pGraph;//
这也是一个局部的指针变量,内存在栈中 
    pGraph=new CGraph(m_nDrawType,m_ptOrigin,point); 
    //
这一句调用它的构造函数为pGraph指针类型的变量在堆中分配一个内存空间,构造一个CGraph类的对象 
    //
因为用new所分配的内存都是在堆中分配的,在堆中分配的对象的内存,如果不去显示的调用Delete去释放 
    //
这个对象内存,那么这个对象的生命周期是和应用程序保持一致的 
    m_ptrArray.Add(pGraph);//
将之前在堆中构造的CGraph类的对象地地址索引保存到集合类的对象m_ptArray当中

运行,绘制图形,改变窗口大小,图形没有消失,OK!

 

3.将图形输出放置到WM_PAINT消息响应函数中

CGraphic2View类上添加一个WM_PAINT消息处理,编辑:

void CGraphic2View::OnPaint()  

    CPaintDC dc(this); // device context for painting 
     
    // TODO: Add your message handler code here 
    OnPrepareDC(&dc); //
调整显示上下文的属性
    OnDraw(&dc);//调用
OnDraw 
    // Do not call CView::OnPaint() for painting messages 
}

4.给窗口添加滚动条

首先将CGraphic2View的基类CView手动改成CScorllView,CGraphic2View的头文件中和源文件中将所有的CView都替换成CScrollView,编译运行,会发现出现了非法操作,

    先介绍一下坐标空间的转换,下图

Coordinate Spaces and Transformations

Applications use coordinate spaces and transformations to scale, rotate, translate, shear, and reflect graphics output. A coordinate space is a planar space that locates two-dimensional objects by using two reference axes that are perpendicular to each other. There are four coordinate spaces: world, page, device, and physical device (client area, desktop, or page of printer paper).

A transformation is an algorithm that alters ("transforms") the size, orientation, and shape of objects. Transformations also transfer a graphics object from one coordinate space to another. Ultimately, the object appears on the physical device, which is usually a screen or printer.

一个例子:

Using Coordinate Spaces and Transformations

This section contains an example that demonstrates the following tasks:

  • Drawing graphics with predefined units.
  • Centering graphics in the application's client area.
  • Scaling graphics output to half its original size.
  • Translating graphics output 3/4 of an inch to the right.
  • Rotating graphics 30 degrees.
  • Shearing graphics output along the x-axis.
  • Reflecting graphics output about an imaginary horizontal axis drawn through its midpoint.

The following example was used to create the illustrations that appear earlier in this overview.

void TransformAndDraw(int iTransform, HWND hWnd)

{

HDC hDC;

XFORM xForm;

RECT rect;

 

// Retrieve a DC handle for the application's window.

 

hDC = GetDC(hWnd);

 

// Set the mapping mode to LOENGLISH. This moves the

// client area origin from the upper left corner of the

// window to the lower left corner (this also reorients

// the y-axis so that drawing operations occur in a true

// Cartesian space). It guarantees portability so that

// the object drawn retains its dimensions on any display.

 

SetGraphicsMode(hDC, GM_ADVANCED);

SetMapMode(hDC, MM_LOENGLISH);

 

// Set the appropriate world transformation (based on the

// user's menu selection).

 

switch (iTransform)

{

case SCALE: // Scale to 1/2 of the original size.

xForm.eM11 = (FLOAT) 0.5;

xForm.eM12 = (FLOAT) 0.0;

xForm.eM21 = (FLOAT) 0.0;

xForm.eM22 = (FLOAT) 0.5;

xForm.eDx = (FLOAT) 0.0;

xForm.eDy = (FLOAT) 0.0;

SetWorldTransform(hDC, &xForm);

break;

 

case TRANSLATE: // Translate right by 3/4 inch.

xForm.eM11 = (FLOAT) 1.0;

xForm.eM12 = (FLOAT) 0.0;

xForm.eM21 = (FLOAT) 0.0;

xForm.eM22 = (FLOAT) 1.0;

xForm.eDx = (FLOAT) 75.0;

xForm.eDy = (FLOAT) 0.0;

SetWorldTransform(hDC, &xForm);

break;

 

case ROTATE: // Rotate 30 degrees counterclockwise.

xForm.eM11 = (FLOAT) 0.8660;

xForm.eM12 = (FLOAT) 0.5000;

xForm.eM21 = (FLOAT) -0.5000;

xForm.eM22 = (FLOAT) 0.8660;

xForm.eDx = (FLOAT) 0.0;

xForm.eDy = (FLOAT) 0.0;

SetWorldTransform(hDC, &xForm);

break;

 

case SHEAR: // Shear along the x-axis with a

// proportionality constant of 1.0.

xForm.eM11 = (FLOAT) 1.0;

xForm.eM12 = (FLOAT) 1.0;

xForm.eM21 = (FLOAT) 0.0;

xForm.eM22 = (FLOAT) 1.0;

xForm.eDx = (FLOAT) 0.0;

xForm.eDy = (FLOAT) 0.0;

SetWorldTransform(hDC, &xForm);

break;

 

case REFLECT: // Reflect about a horizontal axis.

xForm.eM11 = (FLOAT) 1.0;

xForm.eM12 = (FLOAT) 0.0;

xForm.eM21 = (FLOAT) 0.0;

xForm.eM22 = (FLOAT) -1.0;

xForm.eDx = (FLOAT) 0.0;

xForm.eDy = (FLOAT) 0.0;

SetWorldTransform(hDC, &xForm);

break;

 

case NORMAL: // Set the unity transformation.

xForm.eM11 = (FLOAT) 1.0;

xForm.eM12 = (FLOAT) 0.0;

xForm.eM21 = (FLOAT) 0.0;

xForm.eM22 = (FLOAT) 1.0;

xForm.eDx = (FLOAT) 0.0;

xForm.eDy = (FLOAT) 0.0;

SetWorldTransform(hDC, &xForm);

break;

 

}

 

// Find the midpoint of the client area.

 

GetClientRect(hWnd, (LPRECT) &rect);

DPtoLP(hDC, (LPPOINT) &rect, 2);

 

// Select a hollow brush.

 

SelectObject(hDC, GetStockObject(HOLLOW_BRUSH));

 

// Draw the exterior circle.

 

Ellipse(hDC, (rect.right / 2 - 100), (rect.bottom / 2 + 100),

(rect.right / 2 + 100), (rect.bottom / 2 - 100));

 

// Draw the interior circle.

 

Ellipse(hDC, (rect.right / 2 -94), (rect.bottom / 2 + 94),

(rect.right / 2 + 94), (rect.bottom / 2 - 94));

 

// Draw the key.

 

Rectangle(hDC, (rect.right / 2 - 13), (rect.bottom / 2 + 113),

(rect.right / 2 + 13), (rect.bottom / 2 + 50));

Rectangle(hDC, (rect.right / 2 - 13), (rect.bottom / 2 + 96),

(rect.right / 2 + 13), (rect.bottom / 2 + 50));

 

// Draw the horizontal lines.

 

MoveToEx(hDC, (rect.right/2 - 150), (rect.bottom / 2 + 0), NULL);

LineTo(hDC, (rect.right / 2 - 16), (rect.bottom / 2 + 0));

 

MoveToEx(hDC, (rect.right / 2 - 13), (rect.bottom / 2 + 0), NULL);

LineTo(hDC, (rect.right / 2 + 13), (rect.bottom / 2 + 0));

 

MoveToEx(hDC, (rect.right / 2 + 16), (rect.bottom / 2 + 0), NULL);

LineTo(hDC, (rect.right / 2 + 150), (rect.bottom / 2 + 0));

 

// Draw the vertical lines.

 

MoveToEx(hDC, (rect.right/2 + 0), (rect.bottom / 2 - 150), NULL);

LineTo(hDC, (rect.right / 2 + 0), (rect.bottom / 2 - 16));

 

MoveToEx(hDC, (rect.right / 2 + 0), (rect.bottom / 2 - 13), NULL);

LineTo(hDC, (rect.right / 2 + 0), (rect.bottom / 2 + 13));

 

MoveToEx(hDC, (rect.right / 2 + 0), (rect.bottom / 2 + 16), NULL);

LineTo(hDC, (rect.right / 2 + 0), (rect.bottom / 2 + 150));

 

ReleaseDC(hWnd, hDC);

}

逻辑坐标与设备坐标的相互转换

DMM_TEXT映射方式下逻辑坐标与设备坐标的相互转换

 

接下来,在CGraphic2View类上添加一个虚函数,编辑:

void CGraphic2View::OnInitialUpdate()  

    CView::OnInitialUpdate(); 
     
    // TODO: Add your specialized code here and/or call the base class 
    SetScrollSizes(MM_TEXT,CSize(1000,800));//
设置一个滚动条 
}

运行,可以发现多了滚动条,当把窗口滚动条拖到最下方时,再画一图形,切换窗口,再切回来,发现图形上移,下面解决这个问题。

视口和窗口原点的改变

关于图形错位的说明

解决方法

CGraphic2View::OnLButtonUp中编辑:

    //CGraph graph(m_nDrawType,m_ptOrigin,point);//构造一个对象 
    //
:此时graph是一个局部变量,为它分配的内存在栈中,当这个函数结束时,对象也会被析构 
    //m_ptrArray.Add(&graph);//
graph对象保存到集合类的对象m_ptArray当中 
 
    OnPrepareDC(&dc);//
调整图形设备显示 
    dc.DPtoLP(&m_ptOrigin);//
将设备点转换成逻辑点 
    dc.DPtoLP(&point);//
将设备点转换成逻辑点
 
 
    CGraph *pGraph;//
这也是一个局部的指针变量,内存在栈中 
    pGraph=new CGraph(m_nDrawType,m_ptOrigin,point); 
    //
这一句调用它的构造函数为pGraph指针类型的变量在堆中分配一个内存空间,构造一个CGraph类的对象 
    //
因为用new所分配的内存都是在堆中分配的,在堆中分配的对象的内存,如果不去显示的调用Delete去释放 
    //
这个对象内存,那么这个对象的生命周期是和应用程序保持一致的 
    m_ptrArray.Add(pGraph);//
将之前在堆中构造的CGraph类的对象地地址索引保存到集合类的对象m_ptArray当中

说明:OnPrepareDC会随时根据滚动窗口的位置来调整视口的原点。

 

5.保存图形和重绘图形的另两种方式

先在CGraphic2View类上添加一个私有的成员变量CMetaFileDC m_dcMetaFile;

然后在构造函数当中:

CGraphic2View::CGraphic2View()

{

    m_nDrawType=0;

    m_ptOrigin=0;

    m_dcMetaFile.Create();//创建一个内存的CMetaFileDC对象

}

然后在CGraphic2View::OnLButtonUp函数中修改:

void CGraphic2View::OnLButtonUp(UINT nFlags, CPoint point)  

    // TODO: Add your message handler code here and/or call default 
    CClientDC dc(this); 
    CBrush *pBrush=CBrush::FromHandle((HBRUSH)GetStockObject(NULL_BRUSH)); 
    //
创建透明画刷 
    //dc.SelectObject(pBrush); 
    m_dcMetaFile.SelectObject(pBrush); 
     
    switch(m_nDrawType) 
    { 
    case 1
        //dc.SetPixel(point,RGB(0,0,0)); 
        m_dcMetaFile.SetPixel(point,RGB(0,0,0));//m_dcMetaFile
元文件 
        //m_dcCompatible.SetPixel(point,RGB(0,0,0));//m_dcCompatible
兼容DC 
        break
    case 2
        //dc.MoveTo(m_ptOrigin); 
        //dc.LineTo(point); 
        m_dcMetaFile.MoveTo(m_ptOrigin); 
        m_dcMetaFile.LineTo(point);
 
        //m_dcCompatible.MoveTo(m_ptOrigin); 
        //m_dcCompatible.LineTo(point); 
        break
    case 3
        //dc.Rectangle(CRect(m_ptOrigin,point)); 
        m_dcMetaFile.Rectangle(CRect(m_ptOrigin,point)); 
        //m_dcCompatible.Rectangle(CRect(m_ptOrigin,point)); 
        break
    case 4
        //dc.Ellipse(CRect(m_ptOrigin,point)); 
        m_dcMetaFile.Ellipse(CRect(m_ptOrigin,point)); 
        //m_dcCompatible.Ellipse(CRect(m_ptOrigin,point)); 
        break
    } 
     CView::OnLButtonUp(nFlags, point); 
}

并在CGraphic2View::OnDraw函数中修改:

void CGraphic2View::OnDraw(CDC* pDC) 

    CGraphic2Doc* pDoc = GetDocument(); 
    ASSERT_VALID(pDoc); 
    // TODO: add draw code for native data here 
/* 
    CBrush *pBrush=CBrush::FromHandle((HBRUSH)GetStockObject(NULL_BRUSH)); 
    //
创建透明画刷 
    pDC->SelectObject(pBrush); 
 
    //
将保存的图形对象取出 
    for(int i=0;i
    
        switch(((CGraph*)m_ptrArray.GetAt(i))->m_nDrawType) 
        
        case 1: 
            pDC->SetPixel(((CGraph*)m_ptrArray.GetAt(i))->m_ptEnd,RGB(0,0,0)); 
            break; 
        case 2: 
            pDC->MoveTo(((CGraph*)m_ptrArray.GetAt(i))->m_ptOrigin); 
            pDC->LineTo(((CGraph*)m_ptrArray.GetAt(i))->m_ptEnd); 
            break; 
        case 3: 
            pDC->Rectangle(CRect(((CGraph*)m_ptrArray.GetAt(i))->m_ptOrigin, 
                ((CGraph*)m_ptrArray.GetAt(i))->m_ptEnd)); 
            break; 
        case 4: 
            pDC->Ellipse(CRect(((CGraph*)m_ptrArray.GetAt(i))->m_ptOrigin, 
                ((CGraph*)m_ptrArray.GetAt(i))->m_ptEnd)); 
            break; 
        default: 
            break; 
        
    
*/ 
    HMETAFILE hmetaFile; 
    hmetaFile=m_dcMetaFile.Close();//
关闭元文件DC,并获得它的句柄 
    pDC->PlayMetaFile(hmetaFile);//
播放元文件 
    m_dcMetaFile.Create();//
再次创建一个元文件 
    m_dcMetaFile.PlayMetaFile(hmetaFile);//
去播放先前的元文件,在元文件DC中绘制 
    DeleteMetaFile(hmetaFile);//
删除元文件 

运行,绘制图形,改变窗口大小后,图形显示出来了。

 

6.将绘制的元文件保存到元文件当中和打开保存的元文件

方式一:利用元文件

先给IDR_MAINFRAME菜单的保存和打开子项添加命令响应,编辑:

void CGraphic2View::OnFileSave()  

//保存元文件 
    HMETAFILE hmetaFile; 
    hmetaFile=m_dcMetaFile.Close(); 
    CopyMetaFile(hmetaFile,"meta.wmf");//
拷贝元文件 
    m_dcMetaFile.Create();//
重新创建元文件,以便下一次绘画 
    DeleteMetaFile(hmetaFile);//
删除元文件 

 void CGraphic2View::OnFileOpen()  

//打开元文件 
    HMETAFILE hmetaFile; 
    hmetaFile=GetMetaFile("meta.wmf");//
得到元文件句柄 
    m_dcMetaFile.PlayMetaFile(hmetaFile);//
播放元文件 
    DeleteMetaFile(hmetaFile);//
删除元文件句柄 
    Invalidate();//
引起窗口的重画 

方式二:利用兼容DC

首先在CGraphic2View类当中增加一个私有成员变量    CDC m_dcCompatible; 然后在CGraphic2View::OnLButtonUp函数中修改:

void CGraphic2View::OnLButtonUp(UINT nFlags, CPoint point)  

    // TODO: Add your message handler code here and/or call default 
    CClientDC dc(this); 
    CBrush *pBrush=CBrush::FromHandle((HBRUSH)GetStockObject(NULL_BRUSH)); 
    //
创建透明画刷 
    //dc.SelectObject(pBrush); 
    m_dcMetaFile.SelectObject(pBrush); 
     
    if(!m_dcCompatible.m_hDC)//
判断兼容DC是否被创建 
    { 
        m_dcCompatible.CreateCompatibleDC(&dc);//
创建一个与当前DC兼容的兼容DC 
        CRect rect; 
        GetClientRect(&rect);//
获取客户区域大小 
        CBitmap bitmap;//
创建一个bitmap对象 
        bitmap.CreateCompatibleBitmap(&dc,rect.Width(),rect.Height());//
创建兼容位图 
        m_dcCompatible.SelectObject(&bitmap);//
将位图选进兼容DC 
        m_dcCompatible.BitBlt(0,0,rect.Width(),rect.Height(),&dc,0,0,SRCCOPY);//
将源DC的设备表拷贝到兼容DC 
        m_dcCompatible.SelectObject(pBrush);//
将透明的画刷选到兼容DC 
 
    } 
    switch(m_nDrawType) 
    { 
    case 1
        //dc.SetPixel(point,RGB(0,0,0)); 
        //m_dcMetaFile.SetPixel(point,RGB(0,0,0));//m_dcMetaFile
元文件 
        m_dcCompatible.SetPixel(point,RGB(0,0,0));//m_dcCompatible
兼容DC 
        break
    case 2
        //dc.MoveTo(m_ptOrigin); 
        //dc.LineTo(point); 
        //m_dcMetaFile.MoveTo(m_ptOrigin); 
        //m_dcMetaFile.LineTo(point); 
        m_dcCompatible.MoveTo(m_ptOrigin); 
        m_dcCompatible.LineTo(point);
 
        break
    case 3
        //dc.Rectangle(CRect(m_ptOrigin,point)); 
        //m_dcMetaFile.Rectangle(CRect(m_ptOrigin,point)); 
        m_dcCompatible.Rectangle(CRect(m_ptOrigin,point)); 
        break
    case 4
        //dc.Ellipse(CRect(m_ptOrigin,point)); 
        //m_dcMetaFile.Ellipse(CRect(m_ptOrigin,point)); 
        m_dcCompatible.Ellipse(CRect(m_ptOrigin,point)); 
        break
    } 
    CView::OnLButtonUp(nFlags, point); 
}

并在CGraphic2View::OnDraw函数中编辑:

void CGraphic2View::OnDraw(CDC* pDC) 

    CGraphic2Doc* pDoc = GetDocument(); 
    ASSERT_VALID(pDoc); 
/* 
    CBrush *pBrush=CBrush::FromHandle((HBRUSH)GetStockObject(NULL_BRUSH)); 
    //
创建透明画刷 
    pDC->SelectObject(pBrush); 
 
    //
将保存的图形对象取出来 
    for(int i=0;i
    
        switch(((CGraph*)m_ptrArray.GetAt(i))->m_nDrawType) 
        
        case 1: 
            pDC->SetPixel(((CGraph*)m_ptrArray.GetAt(i))->m_ptEnd,RGB(0,0,0)); 
            break; 
        case 2: 
            pDC->MoveTo(((CGraph*)m_ptrArray.GetAt(i))->m_ptOrigin); 
            pDC->LineTo(((CGraph*)m_ptrArray.GetAt(i))->m_ptEnd); 
            break; 
        case 3: 
            pDC->Rectangle(CRect(((CGraph*)m_ptrArray.GetAt(i))->m_ptOrigin, 
                ((CGraph*)m_ptrArray.GetAt(i))->m_ptEnd)); 
            break; 
        case 4: 
            pDC->Ellipse(CRect(((CGraph*)m_ptrArray.GetAt(i))->m_ptOrigin, 
                ((CGraph*)m_ptrArray.GetAt(i))->m_ptEnd)); 
            break; 
        default: 
            break; 
        
    
*/ 
/* 
    HMETAFILE hmetaFile; 
    hmetaFile=m_dcMetaFile.Close();//
关闭元文件DC,并获得它的句柄 
    pDC->PlayMetaFile(hmetaFile);//
播放元文件 
    m_dcMetaFile.Create();//
再次创建一个元文件 
    m_dcMetaFile.PlayMetaFile(hmetaFile);//
去播放先前的元文件,在元文件DC中绘制 
    DeleteMetaFile(hmetaFile);//
删除元文件 
*/ 
    CRect rect; 
    GetClientRect(&rect);//得到客户的大小 
    pDC->BitBlt(0,0,rect.Width(),rect.Height(),&m_dcCompatible,0,0,SRCCOPY); 
    //将位图贴到客户区当中
 

}

运行, OK!! ^_^

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

罗哥分享

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值