我在打开菜单中调用如下函数显示一个数值图像,
怎么在SDI的客户区显示时,有时有图,有时没有图显示啊!
而且窗口被覆盖的地方的图也没有了。???求高手指点。
我原来用VB在PICTURE控件中用如下方法显示图时就没有这个问题啊!
BOOL CQViewView::ReadDatFile(CString FName)
{
  FILE *ip;
  int x=0,y=0;
  char buf[1024];
  if((ip=fopen((LPSTR)(LPCTSTR)FName,"rb"))==NULL)
  {
     AfxMessageBox("LoadImage failed");
     return FALSE;  
  }
  CPaintDC dc(this); 
  while(!feof(ip))
  {
     fread(buf,1024,1,ip);
     y++;//帧计数
     for(x=0;x<1024;x++)
     {
dc.SetPixel(x,y,RGB(buf[x],buf[x],buf[x]);
     }
  }  fclose(ip); 
  return TRUE;
}

解决方案 »

  1.   

    你应该在OnDraw里调用这个函数。
      

  2.   

    什么意思啊!我没在VC中作过图像处理啊!
    正在为MFC头晕中呢!
      

  3.   

    view 里面有个函数叫OnDraw 
    里面pDC
    就相当于你用的 CPaintDC dc(this); 给你个小例子吧!http://www.vckbase.com/code/listcode.asp?mclsid=7&sclsid=701
      

  4.   

    改为
    CDC *dc=GetDC(this);
    后图像正常显示了,
    但是还是窗口一被别的窗口覆盖或最小化后图像就没有了
      

  5.   

    你要得到当前View的DC才能绘制的
      

  6.   

    听说是先开一个内存BMP,在内存BMP中绘图,
    在paint中draw到View中,
    但我不知如何去做啊?
      

  7.   

    图像失踪的主要原因是窗口重画的问题。
    WINDOWS机制使得一个窗口在作被令一个窗口覆盖后又重新出现或者最小化、最大化等动作时都需要重画。然而重画时必需要有相应的数据才能画出您需要的东西来。
    你在点菜单时画好了图,同时也关掉了存有图片数据的文件,这样当窗口重画时自然找不到图象数据,也只能画出白白的一片。
    解决这个问题有两种途径,其一,将你的这段代码转移到CQViewView的OnDraw函数(应该VC已经给你添加了这个函数,找找看)里,这样一来每次重画窗口时都会读文件画图,就不会出现白画面了,缺点是它不会理你的菜单操作,自己早早的就把图画出来了。第二种方法就麻烦了,你要先把图象文件里的内容读到程序中来,放到某个能贮存它们的地方,比如说文档类,然后在View类里将这些数据画出来;画图代码可以在OnDraw里实现,读取图片信息可以在你的菜单响应函数里实现,至于各函数间如何共享图片数据,那方法就更多了,这里就不多讲了。
      

  8.   

    还要说明一点,OnDraw函数有一个参数叫pDC(CDC类),你应当直接利用它来画图,不要再自己声明什么CDC之类的临时变量了。
      

  9.   

    为什么不在ONPAINT里 画呢 ?
      

  10.   


          当窗口变化时,windows 总会调用Ondraw 函数, 如果你不在里面调用,那么再好看
      的图片也会被重画命令覆盖掉
      

  11.   

    我明白啦!是在Ondraw或OnPaint中绘图啦!
    可以我的程序是通过菜单打开CFileDIALOG后
    选一个文件,然后显示啊!这个功能不能写在ONDRAW或ONPAINT中啊!
    而且,显示图时是向上滚动显示的。
    晕晕。。
      

  12.   

    我想你应该看看有关MFC的书了,这是很简单的问题啊。你的问题是根本就不清楚MFC在CVIEW类里画图的机制。
    其实最好的办法是利用“文档——视图”结构来实现画图(此处不熬述),因为这样你可以利用很多文档类的良好性质(比如说永久性存贮)。如果你的目的仅仅是画图,那也可以不用文档类。
    你可以直接在你的CQViewView(它应当是继承于CView的)类里添加一个成员变量:m_buff,
    把你的菜单响应函数(BOOL CQViewView::ReadDatFile)里的画图部分删除,替换成给m_buff附值的语句(具体怎么实现你应当知道了,我认为m_buff应当是一个二维数组,来存放像素的颜色信息),在函数的末尾加一句Invalidate();。接下来你应当在OnDraw函数里利用SetPixel把m_buff的信息画到屏幕上来就行了。其效果完全等同于你原来的做法,而且也解决了图片失踪的问题。
      

  13.   

    我真是应该看看有关MFC的书了但真是没时间啊!
    原来用BCB时是在内存在NEW一个BITMAP对象,
    再设置BITMAP对象的象素位,再动态根据窗口的
    TRECT大小设置BITMAP的Width与Height,就可以用setpixel
    在BITMAP中绘图了,在BCB的OnPaint()中将BITMAP给
    Form1->Canvas->Draw(...)上。但是在VC中我
    一直想也用如上方法,但没完成这个功能。
    CClientDC dc(this);
    CDC MemDC;//声明内存设备文本对象
    MemDC.CreateCompatibleDC(&dc);//创建兼容内存设备
    将位图选入内存设备文本对象
    CBitmap*pbmpOld=MemDC.SelectObject(&m_Bitmap);《《--这里是否要选定一张位图(白底)
    pDC->StretchBlt(0,0,m_Width,m_Height,&MemDC,
    0,0,m_Width,m_Height,SRCCOPY);//显示位图
    CRect rcClientRect;//定义一个矩形对象
    GetClientRect(&rcClientRect);//取得窗口客户区尺寸
    pDC->StretchBlt(0,0,rcClientRect.right,rcClientRect.bottom,
    &MemDC,0,0,m_Width,m_Height,SRCCOPY);//显示改变后的位图
    MemDC.SelectObject(pbmpOld);//恢复原状
    没试成啊!滚动:就是象电影字幕向上滚动那样。我是在窗口的最下面一行绘图,再用StretchBlt
    将图像COPY到RECT(0,0,Width,Heigh-1)的位置,接下来再在最后一行象素绘新数据,
    之后,再将图像COPY到RECT(0,0,Width,Heigh-1)的位置,循环下去就是滚动显示图像了。
      

  14.   

    这是因为窗口动了后系统会发ON_PAINT消息让程序重绘客户区,解决方法为
    重载OnPaint()函数,你把显示图片的函数放到OnPaint()里,然后定义全局变量
    BOOL m_DrawFlag=FALSE;
    在加一个响应显示图片消息的函数
    比如
    void CQViewView::OnShow()
    {
         m_DrawFlag=TRUE;
    S    endMessage(WM_PAINT);
    }
    void CQViewView::OnPaint()
    {
        if(m_DrawFlag)
           ReadDatFile(CString FName);
    }
    BOOL CQViewView::ReadDatFile(CString FName)
    {
      FILE *ip;
      int x=0,y=0;
      char buf[1024];
      if((ip=fopen((LPSTR)(LPCTSTR)FName,"rb"))==NULL)
      {
         AfxMessageBox("LoadImage failed");
         return FALSE;  
      }
      CPaintDC dc(this); 
      while(!feof(ip))
      {
         fread(buf,1024,1,ip);
         y++;//帧计数
         for(x=0;x<1024;x++)
         {
    dc.SetPixel(x,y,RGB(buf[x],buf[x],buf[x]);
         }
      }  fclose(ip); 
      return TRUE;
    }