最近学习了一个画图程序,书里说,当画图板放大或缩小(即重新刷新后),画布上一般都变得干干净净,不会有你刚才在上面画的画存在,怎样才能在画布刷新后仍然保有自己刚才作的画存在呢?这就要用到MetaFile.
小弟对此的理解如下,不知对否,请高手不吝赐教

解决方案 »

  1.   

    使用MetaFile有以下几个步骤:
    1.在主类中申明
        CMetaFileDC * MF;2.在主类的构造函数中分配空间      
        MF=new MetaFileDC;3.在作画函数(如DrawShap())中将每个作画动作存入MF指向的元文件(MetaFile)中
    void 主类::DrawShape(bool stretch)
    {
      CClientDC dc(this);
      MF->SetAttribDC(dc);  //这句是获得当前设备的属性(我想问问,不要这句行不行?)
      dc.IntersectClipRect(m_Canvas);
      MF->IntersectClipRect(m_Canvas); //m_Cancvas 是存了画布大小的CRect变量  //Prepare the DC here
      dc.SelectObject(&m_Pen);  //m_Pen, m_Brush分别存了笔和画刷的样式
      dc.SelectObject(&m_Brush);
      MF->SelectObject(&m_Pen);  
      MF->SelectObject(&m_Brush);//自由画的动作
         dc.MoveTo(m_LineStart);
      dc.LineTo(m_LineEnd);
      MF->MoveTo(m_LineStart);//将自由画的动作存入MetaFile
      MF->LineTo(m_LineEnd);
      m_LineStart=m_LineEnd;
    ……
    }4.在OnPaint(),既刷新函数中“播放”MetaFile
    void CPaintORamaDlg::OnPaint() 
    {
     CPaintDC dc(this);
     HMETAFILE hmf=MF->Close();  //申明MetaFile的句柄
    //为什么句柄非得指向MF->Close()? 
    //有没有其他的申明法?
    //若之前我已有MF->Close()这句,还能这样申明hmf吗? dc.PlayMetaFile(hmf);  //“播放”MetaFile
     CMetaFileDC* temp=new CMetaFileDC;
     temp->Create();//将已“播放”的文件存入temp指向的MetaFile,
    //这样就可以继续将接着画的动作存入MetaFile,
    //又不至于将前面画的丢掉
     temp->PlayMetaFile(hmf); 
     DeleteMetaFile(hmf);
     delete MF;    
     MF=temp;
    }5.在OnDestroy()中删掉指针
    void 主类::OnDestroy() 
    {
    CDialog::OnDestroy();//后面这两句我曾经错误地加进OnCancel()函数而非OnDestroy()函数,
    //结果出现"read"错误,不知是怎么回事?请高手指教
    //OnCancel()函数和OnDestroy()函数有什么区别? 在什么情况下调用它们?
    MF->Close();
    delete MF;
    }这就是小弟的几点看法
      

  2.   

    MF->SetAttribDC(dc);  
    //这句的意思我不太了解。猜想是否和当前设备的MapMode,Pen,Brush等设置相关?
    //如果不要这句,是否会丢失一些信息?楼主实际试试吧。看结果如何。HMETAFILE hmf=MF->Close();  
    //MF->Close()返回指向metafile的句柄。可以将其保存到hmf,留备以后使用。
    //用其他函数也可以得到。
    //比如:HMETAFILE hmf=GetMetaFile(strPathName);
    //从文件中得到metafile的句柄。strPathName是文件路径全称。//执行Close()后,metafile关闭,再执行就无效了。
      

  3.   

    在此处使用MF->Close()是因为你下面的程序中,MF要指向新的temp,也需要把旧的metafile释放掉。
    其他也可以换其他方式,只是整个OnPaint()的程序结构就要改一改了。
      

  4.   

    OnDestory()函数中,不知道你为什么要使用OnCancel()。
    没试过,不了解。