我写了一个在CStatic控件上画图的程序,程序的功能是,运行后点击一个按钮,在CStatic控件上能画一个坐标轴。但是,遇到的问题是,点击按钮后CStatic控件仍然是一片灰色,除非把整个对话框拉出电脑显示窗口之外再拉回来,或者用另一个对话框把它遮住才能显示绘制的图形。我用了局部刷新的代码刷新整个CStatic控件,还是不行。我的程序如下: 
        1、添加一个CStatic控件,关联一个Control型变量m_Show(IDC_STATIC_SHOW)。添加一个按钮Btn。 
        2、添加一个函数void   Draw(),用来画坐标轴,代码如下: 
              
                  CPaintDC       dc(&m_Show);     
CBitmap     PtnBitmap; 
CBitmap*       pbmOld       =       NULL;       
CRect       rect,CirRect; 
CPoint     Point; m_Show.GetClientRect(&rect); 
CDC       dcMem;       
dcMem.CreateCompatibleDC(&dc);       
        
PtnBitmap.CreateCompatibleBitmap(&dc,       1000,       1000);       
pbmOld       =       dcMem.SelectObject(&PtnBitmap);       
        
//绘制操作       
CBrush   brush(RGB(255,   255,255)); 
dcMem.FillRect(CRect(0,0,1000,       1000),   &brush);//背景全白 dcMem.MoveTo(0,500);       
dcMem.LineTo(1000,500);//水平线 dcMem.MoveTo(500,0); 
dcMem.LineTo(500,1000);//垂直线   for   (int   i=50;i <1000;i+=50)//垂直小格 

dcMem.MoveTo(500,i); 
dcMem.LineTo(520,i); 
} for   (int   j=50;j <1000;j+=50)//水平小格 

dcMem.MoveTo(j,480); 
dcMem.LineTo(j,500); 

dc.StretchBlt(0,0,rect.Width(),rect.Height(),&dcMem,0,0,1000,       1000,SRCCOPY);   
PtnBitmap.DeleteObject(); 
dcMem.SelectObject(pbmOld); 
dcMem.DeleteDC(); 
        4、   给按钮Btn添加单击响应事件OnBtn()   ,代码如下: 
                void   CTestDlg::OnBtn()   
                { 
        DrawPicture=TRUE;//DrawPicture为TRUE时画图 
                        //这里我尝试了很多局部刷新的代码,可是都没用,例如: 
                            // CRect       rect;       
                        //     GetDlgItem(IDC_STATIC_PSHOW)-> GetWindowRect(rect);       
                        //     ScreenToClient(rect);       
                        //     InvalidateRect(rect);   
                        //或者: 
                          //   m_PShow.UpdateWindow();   
                      //或者: 
                          //     Invalidate();                 } 
        5、在OnPaint()中添加代码: 
                void   CTestDlg::OnPaint()   
              { 
                    if(...) 
                    { 
                            ... 
                    } 
    else 
    { 
if(DrawPicture) 

        Draw(); 

CDialog::OnPaint(); 
    } 
              } 
              用MoveWindow可以解决这个问题,但是当我连续画图的时候就闪烁的很厉害,希望大家有更好的解决办法。
             附件中是连续画图的情况,可下载看看运行结果再讨论此问题。

解决方案 »

  1.   

        可以在代码中重载的函数OnEraseBkgnd(CDC*   pDC)中直接返回TRUE,但是运行时对话框的背景也不刷新了。怎样才能只是不刷新CStatic控件的背景,而对其他部分不影响呢?
      

  2.   

    派生CStatic类,在它的OnPaint里画好,再用它的对象Invalidate就好了,我知道你想要的是什么样的结果,如果只是画个坐标,可以不用CStatic的,直接在对话框里的onPaint里画好就可以了,闪的话用双缓冲http://blog.csdn.net/livedeal/archive/2007/05/07/1598763.aspx
      

  3.   

       问题解决了,就是用  Invalidate(FALSE);但是我很奇怪,因为开始老在想着局部刷新,所以用的是下面3句
             GetDlgItem(IDC_STATIC_PSHOW)-> GetWindowRect(&rect);                               
            ScreenToClient(&rect);                               
            InvalidateRect(&rect);
       但是点击按钮后CStatic控件没有显示图形,但是用 Invalidate(FALSE);后点击按钮,图形就显示了。我不知道这两个有什么区别,到底是什么地方不同而导致这样的运行结果?如果怀念兄你能分析一下这里面的原因就好了。
      

  4.   

    这样说吧,InvalidateRect()如果是True的话,它首先会将区域无效化,然后发送wm_paint消息,如果没有再wm_paint里面绘制的话,肯定会被刷新掉的,而false着是区域有效,但是不会被刷新掉,
    msdn上面有更加详细的解释,lz可以去看看。
    Invalidates the client area within the given rectangle by adding that rectangle to the CWnd update region. The invalidated rectangle, along with all other areas in the update region, is ed for painting when the next WM_PAINT message is sent. The invalidated areas accumulate in the update region until the region is processed when the next WM_PAINT call occurs, or until the region is validated by the ValidateRect or ValidateRgn member function.The bErase parameter specifies whether the background within the update area is to be erased when the update region is processed. If bErase is TRUE, the background is erased when the BeginPaint member function is called; if bErase is FALSE, the background remains unchanged. If bErase is TRUE for any part of the update region, the background in the entire region is erased, not just in the given part.