WM_NCCALCSIZE的解释就不再赘述,主要说下网上对这个消息的处理方法。
第一种:
LRESULT CMainFrame::OnNcCalcSizeNewUI( WPARAM wParam, LPARAM lParam)
{
NCCALCSIZE_PARAMS* pNcsp = (NCCALCSIZE_PARAMS*)lParam;
RECT aRect; // 改变前窗口大小
RECT bRect; // 改变后窗口大小
RECT bcRect // 改变后客户区大小
CopyRect(&aRect, &pNcsp.rgrc[1]);
CopyRect(&bRect, &pNcsp.rgrc[0]);
bcRect.left = bRect.left + 4;
bcRect.right = bRect.right - 4;
bcRect.top = bRect.top + 4;
bcRect.bottom = bcRect.bottom - 4;
CopyRect(&pNcsp.rgrc[0], &bcRect);
CopyRect(&pNcsp.rgrc[1], &bRect);
CopyRect(&pNcsp.rgrc[2], &aRect);
return 0;
}
以上面的方法处理,会有两个问题,一是bcRect的right和bottom并不是右下角的坐标,而是右下角的下一个坐标点,和通过GetWindowRect()方法得到的坐标点相同。所以如果想要4个像素宽的边框那就要用right和bottom减一后在减四。
第二个问题是,以上述方法执行后,窗口会不停重绘,导致窗口界面变的很乱。将返回值改为WVR_REDRAW可解决,但是标题栏的按钮就不会再被绘制。
第二种方法是:
LRESULT CMainFrame::OnNcCalcSizeNewUI( WPARAM wParam, LPARAM lParam)
{
NCCALCSIZE_PARAMS* lpncsp = (NCCALCSIZE_PARAMS*)lParam;
CRect bRect;
CRect bcRect;
bRect = lpncsp->rgrc[0];
bcRect.left = bRect.left + FrameCfgFileManage::m_framecornerwidth;
bcRect.top = bRect.top + FrameCfgFileManage::m_framecornerheight;
bcRect.right = bRect.right - 1 - FrameCfgFileManage::m_framecornerwidth;
bcRect.bottom = bRect.bottom - 1 - FrameCfgFileManage::m_framecornerheight;
if (bCaptionOn)
bcRect.top += FrameCfgFileManage::m_captionheight - FrameCfgFileManage::m_framecornerheight;
lpncsp->rgrc[0] = bcRect;
return 0;
}
只改变数组的第一个数值,同时返回0,可以解决窗口重绘和标题栏按钮不绘制的问题。
然后就可以在NcPaint里进行自绘了。
可以先将HDC的客户区剪切掉,然后在剩下的区域里绘制。
HDC hdc = GetWindowDC();
hdc->ExcludeClipRect(&rcClient);
由于时间匆促, 还没找到出现上述原因的问题。
有知道的朋友可以告诉下。