1.有时候,我们需要包装窗口的标题栏,同时又不想让窗口的非客户区全部由自己来控制刷新,比如边框,菜单。
从WM_NCPAINT中的参数wParam可以得到需要刷新的区域:
hrgn = (HRGN) wParam; // handle of update region
因此,可以重载WndProc函数,对此区域中剔除标题栏所占的区域,代码如下:
case WM_NCPAINT: {
HRGN hrgnSrc; // handle to Src WindowDC update region HRGN hRgnCaption; // handle to Combine region HRGN hRgnNew; // handle to New WindowDC update region hrgnSrc = (HRGN) Msg.WParam;
TRect *winrect =new TRect(); GetWindowRect(ParentForm->Handle,winrect); TRect rc; rc= TRect(winrect->left,winrect->top,winrect->right,winrect->top+ GetSystemMetrics(SM_CYCAPTION)+3); hRgnCaption = CreateRectRgnIndirect(&rc); hRgnNew = CreateRectRgnIndirect(&rc); if ((WORD)hrgnSrc > 1 && !RectInRegion(hrgnSrc, &rc)) { DeleteObject(hRgnNew ); DeleteObject(hRgnCaption); DeleteObject(hrgnSrc); delete winrect; break; } if ((WORD)hrgnSrc>1) { CombineRgn(hRgnNew ,hrgnSrc,hRgnCaption,RGN_DIFF); } else { HRGN hRgnAll = ::CreateRectRgnIndirect(winrect); CombineRgn(hRgnNew, hRgnAll, hRgnCaption, RGN_DIFF); DeleteObject(hRgnAll); } Msg.Result = DefWindowProc( ParentForm->Handle, Msg.Msg,(int)hRgnNew, Msg.LParam); DrawCaption();// custom draw caption DeleteObject(hRgnNew ); DeleteObject(hRgnCaption); DeleteObject(hrgnSrc); delete winrect; return; } 2.怎么调整标题栏的宽度
换言之,也就是调整窗口客户区的大小,自然也就修改了非客户区的大小。我们可以对WM_NCCALCSIZE消息进行处理,注意的是此方法不适用于窗口有主菜单的情况。
WM_NCCALCSIZE参数wParam和lParam的意义:
fCalcValidRects = (BOOL) wParam; // valid area flag lpncsp = (LPNCCALCSIZE_PARAMS) lParam; // points to size calculation data or lpncsp = (LPRECT) lParam; // points to new window coordinates
具体代码:
case WM_NCCALCSIZE: {// calculate window's client bool fCalcValidRects = (bool) Msg.WParam; if (fCalcValidRects) { RECT rtSave; CopyRect(&rtSave,(LPRECT)Msg.LParam); rtSave.top+=TitleHeight - GetSystemMetrics(SM_CYCAPTION)-yEdge; if (HaveBorder) { rtSave.left +=4 -xEdge; rtSave.right-=4- xEdge; rtSave.bottom -=4- yEdge; } CopyRect((LPRECT)Msg.LParam,&rtSave); } else { RECT rtSave; LPRECT prtClt; LPNCCALCSIZE_PARAMS pNC; pNC=(LPNCCALCSIZE_PARAMS)Msg.LParam; prtClt=&(pNC->rgrc[0]); CopyRect(&rtSave,prtClt); CopyRect( &(pNC->rgrc[2]), &(pNC->rgrc[1])); (pNC->rgrc[2]).top+=TitleHeight - GetSystemMetrics(SM_CYCAPTION)-yEdge; rtSave.top+=TitleHeight - GetSystemMetrics(SM_CYCAPTION)-yEdge-1; if (HaveBorder) { (pNC->rgrc[2]).left +=4 -xEdge; (pNC->rgrc[2]).right-=4- xEdge; (pNC->rgrc[2]).bottom -=4- yEdge; rtSave.left +=4 -xEdge; rtSave.right-=4- xEdge; rtSave.bottom -=4- yEdge; } CopyRect(prtClt,&rtSave); } break; }

|