为什么我自画了一个窗体,重载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了 谢谢~~~:)
可是为什么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了 谢谢~~~:)
WM_NCPAINT
WM_ACTIVE .....
{
// do yourself drawing at here return TRUE; // Don't via Default process.
}
{
TRACE( "------OnEraseBkgnd\n" );
// 重画整个窗体边框
pDC = GetWindowDC( ); //你这句是多余的,而且你使用了GetWindowDC还要记得释放.
//
}
怎么就多余了????????????????????????????????
触发非客户区绘制的消息多的很,你还有好多没处理呢,当然不行。
我管它那么多消息做什么,我现在就需要一个重画的最终入口点,
而且TRACE是这样:
------OnNCPaint
------OnEraseBkgnd
当然是return TRUE!!!!
你这句没有任何实际意义, 你改变的是参数值,不会影响到函数返回后外部的pDC数值
形参和实参, 传值和传址
晕,我已经说过一遍了,
pDC = GetWindowDC( );当然有意义,因为我需要对windowdc操作,我这么做,只不过稍定义了一个变量罢了。我本来也没有想去影响它的返回后的参数意义。To
我就是想要WS_BORDER,因为我要改变窗体的大小尺寸阿!!!
为什么windows的边框,就是可以缩放大小的边框,在应用从前台切换到后台的时候还会自动画出来???????????
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里面是不行的,还需要扑获失去焦点的消息,再重绘,
我想问的就是有没有一个优美的方法。
{
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;
}
感觉不好, 毕竟mfc有一套标准的做法, OnEraseBkgnd传递进来的就是客户区dc, 在这里不应该对非客户区做绘制如前面几位所说, 该处理哪个消息就处理哪个消息, 你根本不应该把绘制边框的动作放在OnEraseBkgnd函数里
有意见, 不是没道理的, 在OnEraseBkgnd函数里, 不应该涉及到非客户区