我从CWnd派生了一个类CPicWnd用来显示图片然后放到CView上,现在当CView改变大小的时候,CPicWnd会重绘图片,请问怎么不让它重绘,我看了以前的帖子,说是CView的“窗口类”有两个属性CS_HREDRAW,CS_VREDRAW,怎么把它去掉呢?或者其它的办法也行,不过我想双缓冲的办法可能不适合我这个问题,我想怎么样能避免改变窗口大小的时候重绘子窗口可能能解决我的问题。谢谢!

解决方案 »

  1.   

    要去掉这两个属性,应当在CYourView的PreCreateWindow函数里面改成
    cs.lpszClass = AfxRegisterWndClass(0);
    return TRUE;
    就可以了。
      

  2.   

    使用CWnd的这个成员函数pView->SetRedraw(FALSE);void SetRedraw( BOOL bRedraw = TRUE );
      

  3.   

    重绘是View刷窗口背景造成的,它会把view上的窗口全部破坏,然后这些子窗口不得不重新再画一遍,造成闪烁。
    重载View的OnEraseBkgnd函数,直接return TRUE应该就不会闪了。
    不过这样view的背景就会出问题,所以你还要处理一下view的背景。如果你知道view上的窗口大小和位置,那么可以刷这个窗口之外的所有地方。比如:BOOL CXXXView::OnEraseBkgnd(CDC* pDC) 
    {
       extern CRect rectWnd;//你窗口的位置,自己想办法获得,应该很容易
       CRect rectClient;//view的客户区
       GetClientRect(rectClient);
       
       //创建两个rgn
       CRgn rgn1,rgn2;
       rgn1.CreateRectRgn(rectClient.left,rectClient.top,rectClient.right,rectClient.bottom);
       rgn2.CreateRectRgn(rectWnd.left,rectWnd.top,rectWnd.right,rectWnd.bottom);
       //做异或操作,使rgn1只包含你的wnd位置之外的view客户区范围
       if(rgn1.CombineRgn(&rgn1,&rgn2,RGN_XOR) == ERROR)
       {
    ASSERT(FALSE);
    return FALSE;
       }
       //创建一个刷子刷背景
       CBrush brushWhite;
       brushWhite.CreateSolidBrush(RGB(255,255,255));
       pDC->FillRgn(&rgn1,&brushWhite);
       brushWhite.DeleteObject();
       return TRUE;//原来调用基类的OnEraseBkgnd一定记得去掉,它就是引起闪烁的根本原因
    }
      

  4.   

    很遗憾chenzhou35(vcworm.51.net)没有解决楼猪的问题。楼猪要的是当SIZE改变时不重绘,而你的只是解决重绘时的问题,晚了。
      

  5.   

    他是改变view的大小时,子窗口不重绘,不是改变子窗口大小的时候,如果子窗口不随父窗口的大小变化而改变,上面就够了。
      

  6.   

    如果子窗口始终充满父窗口(也就是说完全随父窗口大小改变而改变),那么不重绘子窗口的需求是很奇怪的,虽然也很好做。你想,如果窗口被拉大,你不重绘,右下角不是就出空白?所以最多缩小时不重绘,放大是肯定要重绘的。如果你放大缩小都不重绘,在onsize里设置一个标记,在OnPaint检查并清除这个标记,如果被标记了那么认为是Onsize引发重绘,强制跳过Onpaint(甚至OnEraseBkgnd)并清除标记就ok了。如果缩小时不重绘放大时重绘在Onsize里判断一下再决定是否做标记就ok了。
      

  7.   

    拜托chenzhou35(vcworm.51.net)先了解一下CS_HREDRAW和CS_VREDRAW的性质。
      

  8.   

    窗口类有CS_HREDRAW,CS_VREDRAW属性时,无论窗口变大变小都会引发整个窗口的全部重绘,当没有这两个属性时,窗口变小不会重绘,窗口变大时只重绘新增加的部分,原有部分不会重绘。
      

  9.   

    感谢各位及时的回答,是这样的,我想做一个简单的图片浏览器,类似于Acdsee,就是很多幅小图放在一个视图上,可以直接画的,但是我想画在CWnd上,可能便于响应消息。我试了a_kun(狂人日记)的方法,修改了view的属性,可还是不能防止子窗口重绘,不过倒是可以防止背景重绘。OnEraseBKGnd的方法也是同样的,看来我只有考虑直接画在View上了,难道父窗口改变大小,子窗口就注定要重绘?
      

  10.   

    我觉得你应该检查一下CPicWnd的绘制代码,必要的时候在其中使用双缓冲
    你说 “双缓冲的办法可能不适合我这个问题”不知道你是什么意思
      

  11.   

    建议你好好研究一下AcdSee3.0的版本, 它可不是在CWnd上显示多个小图的。你的那种显示方法估计会把你慢慢累晕(总是有些BUG要改), 这玩意我去年自己做过。
      HUST,很亲切的地方,老弟。
      

  12.   

    Happy197212(Wright)是师兄吗?小弟这厢有礼啦!我是在一个CWnd只显示一张小图,然后在create很多个放到view上,能说的详细点吗?我的信箱是[email protected],我的acdsee是5.0的,好象也不是这么干的,我想还是直接画在view上算了,谢谢啦!
      

  13.   

    ACDSee5.0太花了,不实用,实际功能不比ACDSee3.0多什么。ACDSee3.0显示多个小图是放在CListView或CListCtrl 上的(当然它是用SDK做的), 你的小图用CImageList加入就是了, 可以为你省很多的事情,象滚动处理等等..
      

  14.   

    我也想过这样做,但是你知道ACDSee里面连小图下面的文字也进行了装饰,我原以为用ownerdraw风格可以实现,后来发现IconView风格的Listctrl是不能ownerdraw的,而且点到某个小图的时候,画焦点的时候也是不一样的,我现在时间挺充裕,想再多试试,实在不行了,只好这样做了,你是怎么做的?留个email吧!谢谢!