为什么我自画了一个窗体,重载OnEraseBkgnd,并在里面 pDC = GetWindowDC( ); 
 
可是为什么windows还会把那个border画出来,也就是非client区域。
注意:我已经重画了GETWINDOWDC的区域!!而且TRACE是这样:
------OnNCPaint
------OnEraseBkgnd再次注意:
BOOL CBorderDlg::OnEraseBkgnd(CDC* pDC)
{
    TRACE( "------OnEraseBkgnd\n" );
    // 重画整个窗体边框
    pDC = GetWindowDC( );
           // 
}问题:
为什么windows的边框,就是可以缩放大小的边框,在应用从前台切换到后台的时候还会自动画出来???????????第三次注意:
 1:按照TRACE来说,OnNCPaint发生在erasebk的前面。
 2:我在erasebkgnd中强行GetWindowDC了 谢谢~~~:)

解决方案 »

  1.   

    触发非客户区绘制的消息多的很,你还有好多没处理呢,当然不行。
    WM_NCPAINT
    WM_ACTIVE .....
      

  2.   

    OnEraseBkgnd(..)
    {
        // do yourself drawing at here    return TRUE; // Don't via Default process.
    }
      

  3.   

    BOOL CBorderDlg::OnEraseBkgnd(CDC* pDC)
    {
        TRACE( "------OnEraseBkgnd\n" );
        // 重画整个窗体边框
        pDC = GetWindowDC( ); //你这句是多余的,而且你使用了GetWindowDC还要记得释放.
               // 
    }
      

  4.   

    OnEraseBkgnd 传进来是clientDC!!
    怎么就多余了????????????????????????????????
    触发非客户区绘制的消息多的很,你还有好多没处理呢,当然不行。
    我管它那么多消息做什么,我现在就需要一个重画的最终入口点,
    而且TRACE是这样:
    ------OnNCPaint
    ------OnEraseBkgnd
      

  5.   

    To yjgx007(who's superior)
    当然是return TRUE!!!!
      

  6.   

    pDC = GetWindowDC( );
    你这句没有任何实际意义, 你改变的是参数值,不会影响到函数返回后外部的pDC数值
    形参和实参, 传值和传址
      

  7.   

    To captainwh(wh) 
    晕,我已经说过一遍了,
    pDC = GetWindowDC( );当然有意义,因为我需要对windowdc操作,我这么做,只不过稍定义了一个变量罢了。我本来也没有想去影响它的返回后的参数意义。To 
    我就是想要WS_BORDER,因为我要改变窗体的大小尺寸阿!!!
      

  8.   

    BOOL CBorderDlg::OnEraseBkgnd(CDC* pDC)这个函数已经传进了DC句柄,如果你用GetWindowDC这样就会导致重复操作,并且改变了传进来的DC句柄,因为它是指针.如果你用完不进行释放你的内存将会不断的增长...
      

  9.   

    OK,我修改了,我不用pDC了,但是我的问题谁来解决。问题:
    为什么windows的边框,就是可以缩放大小的边框,在应用从前台切换到后台的时候还会自动画出来???????????
      

  10.   

    To captainwh(wh) 我是很谦虚的,可是我不明白,有很多人为什么非得要在
    pDC = GetWindowDC( );
    这一句上做这么多研究,更何况我已经说过了,这个是没有问题的。好吧,我就再最后解释一遍,为什么pDC = GetWindowDC( );这句话没有任何毛病,
    如果再不清楚,我只能建议去看看参数,同时看看指针。首先:
    从OnEraseBkgnd传进来的pDC是ClientDC,而非WindowDC,
    但是我需要重画整个WindowDC,所以,我不能用OnEraseBkgnd传进来的DC。
    所以,我需要WindowDC重画,这没有任何问题!当然,我一定在程序末尾ReleaseDC。// 这就否定了这句
    BOOL CBorderDlg::OnEraseBkgnd(CDC* pDC)
    {
        TRACE( "------OnEraseBkgnd\n" );
        // 重画整个窗体边框
        pDC = GetWindowDC( ); //你这句是多余的,而且你使用了GetWindowDC还要记得释放.
               // 
    }
    其次:为什么pDC = GetWindowDC( ); 没有问题。
    因为传进来的pDC是一个指针变量,而GetWindowDC( );返回也是一个指针变量。
    这等于是一个变量的复值。如果你不明白,那么我式着还原这段代码,当然,我懒得去看MFC代码,因为我觉得这样已经可以说明:{ 
      //....调用OnEraseBkgnd的函数
      CDC* pDC = ClientDC( );   
         OnEraseBkgnd( pDC );
      pDC->ReleaseDC( );
    }稍微知道指针的人应该清楚,无论pDC怎么改变,形参都不会影响实参,
    所以,这个是没有问题的。在这里,我再假设这么写一下
    BOOL CBorderDlg::OnEraseBkgnd(CDC* pDC)
    {
     pDC = NULL;
     return true;
    }
    那么你觉得会有问题吗?呵呵~这当然没有任何问题……另外在OnEraseBkgnd里面,这一句,我再次说一下,因为pDC是一个指针,而GetWindowDC也是一个指针。所以这一句也没有任何问题。
    为什么?因为假设参数pDC指向的0x8888地址,而GetWindowDC返回的是0x9999地址,
    所以pDC的指针只不过把他的地址由0x8888指向了0x9999,没有人改变0x8888的内容,
    只不过这个地址不会被引用罢了!OnEraseBkgnd(CDC* pDC)
    pDC = GetWindowDC( );  // 这里并不是 *pDC = *GetWindowDC( );
    所以,这个没有问题,正如我以前所说,这样做,只不过是少定义了一个变量罢了。// 所以我也否定了这段,因为我确实没有改变参数pDC中的句柄,而仅仅是将指针的值改变了。
    BOOL CBorderDlg::OnEraseBkgnd(CDC* pDC)这个函数已经传进了DC句柄,如果你用GetWindowDC这样就会导致重复操作,并且改变了传进来的DC句柄,因为它是指针.如果你用完不进行释放你的内存将会不断的增长...
    ///////////////////////////////
    最后,我也不是不耐烦,就是感觉很奇怪。
    如果你觉得我不耐烦,我在此道歉,昨天确实有点烦,感觉我说了半天,
    你也没有明白,今天我写了上面的话,你好好研究研究,希望你把这个问题搞懂。
    /////////////
    我的问题就是:
    就是窗口失去交点,windows会自动绘制边框,但是没有调用
    OnEraseBkgnd, 所以我在OnEraseBkgnd里面是不行的,还需要扑获失去焦点的消息,再重绘,
    我想问的就是有没有一个优美的方法。
      

  11.   

    重载CMainFrame类的DefWindowProc函数LRESULT CMainFrame::DefWindowProc(UINT message, WPARAM wParam, LPARAM lParam) 
    {
    LRESULT ret=CFrameWnd::DefWindowProc(message, wParam, lParam); 
    if(!::IsWindow(m_hWnd))
    return ret;
    if(message==WM_NCPAINT ||message==WM_NCACTIVATE ||message==WM_PAINT)

    {
    CDC *pWinDC=GetWindowDC();
    if(pWinDC)
    {
    //重画标题栏和窗体边框

    }
    ReleaseDC(pWinDC);
    } return ret;
    }
      

  12.   

    你就是想在OnEraseBkgnd里面绘制窗口边框是吧
    感觉不好, 毕竟mfc有一套标准的做法, OnEraseBkgnd传递进来的就是客户区dc, 在这里不应该对非客户区做绘制如前面几位所说, 该处理哪个消息就处理哪个消息, 你根本不应该把绘制边框的动作放在OnEraseBkgnd函数里
      

  13.   

    之所以这么多人对你那句pDC = GetWindowDC( );
    有意见, 不是没道理的, 在OnEraseBkgnd函数里, 不应该涉及到非客户区
      

  14.   

    snow_light正解啊!楼主选择的方向确实有问题