热情软件屋

 

为什么兼容位图的内容无法绘制出来


编号:QA004258
建立日期: 2001年6月19日 最后修改日期:2001年6月19日
所属类别:

蓝鸟八哥:
    操作系统:Windows 98
    编程工具:VC++6.00
    问题:一、设想:
    在位图中作画,然后将画显示在屏幕上,显示前将屏幕内容保存。
    二、出现问题:
     屏幕上没有任何反应
    三、建立方法如下:
    1.建立 2 个位图对象
     CBitmap MapA; //用于保存屏幕内容
     CBitmap MapB; //用于作画、写字
    2.创建位图
     void CreateBitMap(CDC* pDC)
     {
     MapA.CreateCompatibleBitmap(pDC,Width,Height);
     MapB.CreateCompatibleBitmap(pDC,Width,Height);
     }
     3.保存屏幕内容
     void GetScnMap(CDC* pDC)
     {
     CDC MemDC;
     MemDC.CreateCompatibleDC(pDC);
     MemDC.SelectObject(&MapA);
     MemDC.BitBlt(0,0,Width,Height,pDC,0,0,SRCCOPY);
     }
     4.作图函数
     void DrawMap(CDC* pDc)
     {
     pDC->TextOut(1,1,"AAAAAAA");
     }
     5.在位图 MapB 中作图
     void DrawMapInMap(CDC* pDC)
     {
     CDC MemDC;
     MemDC.CreateCompatibleDC(pDC);
     MemDC.SelectObject(&MapB);
     DrawMap(&MemDC);
     }
     6.将位图内容向屏幕输出
     void ShowMap(CDC* pDC,CBitmap* pMap)
     {
     CDC MemDC;
     MemDC.CreateCompatibleDC(pDC);
     MemDC.SelectObject(pMap);
     pDC->BitBlt(0,0,Width,Height,&MemDC,0,0,SRCCOPY);
     }
    
    完成了以上准备后,我们就可以在 OnDraw(...) 函数内进行了:
     void OnDraw(CDC* pDC)
     {
     GetScnMap(pDC); //将屏幕某区域内容保存到位图 MapA 中
     DrawMapInMap(pDC); //在位图 MapB 中作图
     ShowMap(pDC,&MapB); //将位图 MapB 中内容输出到屏幕
     }
    
    四、调试方案
     1.在函数 DrawMapInMap(...) 体内的函数
     DrawMap(&MemDC);
     改成
     DrawMap(pDC);
    
     后,在屏幕上正常显示。pDC 是屏幕设备情景对象指针,而MemDC是与位图 MapB 相连的内存设备情景对象,这种改变的正确显示似乎预示着在内存作图存在着问题。
     2.为了验证在位图内作图是否存在问题,将 OnDraw(..) 函数改成如下:
     void OnDraw(CDC* pDC)
     {
     DrawMapInMap(pDC); //在位图 MapB 中作图
     CDC MemDC;
     MemDC.CreateCompatibleDC(pDC);
     MemDC.SelectObject(&MapB);
     GetScnMap(&MemDC); //将位图 MapB 内容保存到位图 MapA 中
     ShowMap(pDC,&MapA); //将位图 MapA 中内容输出到屏幕
     }
    结果一切正常。这个设计的意思是首先在位图 MapB 中作图,然后用函数GetScnMap(...)将位图 MapB 中内容复制到位图 MapA 中,最后将位图 MapA中的内容输出到屏幕。这说明在位图 MapB 中作图也是正确在,这样就非常令人困惑,为何从 MapB 传到 MapA 成功,而 MapB 传到屏幕就不成功呢?而更令人困惑的是从 MapA 传到屏幕却是成功的。唯一的问题便是设备情景对象 MapA 与 MapB兼容、MapA 与屏幕兼容,而 MapB 与屏幕不兼容。但从整个设计上却看不出MapB与屏幕不兼容的地方。
    本人已思考了很久,怎么也想不出个所以然来,只好向各位大侠请教了。谢谢!
    水平: 中级

回答:

    为什么定义了CreateBitMap(**),却未在OnDraw中调用呢?
    CreateCompatibleBitmap函数在内部调用了Attach,如果一个GDI对象句柄为空,BitBlt是不会在上面作图的。另外,如果Attach后,未Detach,那么再次Attach时便会ASSERT,所以这里要定义一个释放句柄函数
    void CBitmapView::DetachBitmap()
    {
     MapA.Detach();
     MapB.Detach();
    }
    修改之后的OnDraw函数如下
    void OnDraw(CDC* pDC)
    {
     CreateBitMap( pDC );
    
     GetScnMap(pDC); //将屏幕某区域内容保存到位图 MapA 中
     DrawMapInMap(pDC); //在位图 MapB 中作图
     ShowMap(pDC,&MapB); //将位图 MapB 中内容输出到屏幕
    
     DetachBitmap();
    }
    这样,程序运行便正常了。在向位图B中画的时候,应该先重出位图背景,否则,会看到一堆乱乱的内存映象。在函数 DrawMapInMap(...) 体内的函数DrawMap(&MemDC)不要改为DrawMap(pDC),如果按你所改了,传递pDC,那么只是在视类的DC上直接作图,并非在位图B上作图。

此问题由王加宝回答。

 
把这个问题推荐给朋友
   
   
您的意见类别
您的名字
您的电子邮件
您的建议(请尽可能详细)
 
 

版权所有 1997-2008 热情软件屋
如果您有任何建议和意见, 请给我发个电子邮件 askpro@china-askpro.com
Web Designed by ZebraStudio