四、小结 本实例通过灵活运用CsplitterWnd类,实现了窗口的任意拆分。另外,需要补充的内容是,在具体应用中可以通过对CSplitterWnd原有方法的覆盖或者增加新的方法来扩展CSplitterWnd。 我们在此仅举两个方面的例子,一是锁定切分条;二是定制自己的切分条。对于锁定切分条,不希望用户通过拖动切分条来调节窗口的大小这个问题,最简单的解决方法莫过于不让CSplitterWnd来处理WM_LBUTTONDOWN,WM_MOUSEMOVE,WM_SETCURSOR消息,而是将这些消息交给CWnd窗口进行处理,从而屏蔽掉这些消息。那么如何定制自己的切分条呢?通过重载CSplitterWnd的虚方法OnDrawSplitter()和OnInvertTracker()可以达到这样的目的。下面的代码生成的效果是分割窗口的边界颜色为红色,分割条的颜色为绿色代码如下: void CSplitterWndEx::OnDrawSplitter(CDC *pDC, ESplitType nType, const CRect &rectArg) { CSplitterWnd::OnDrawSplitter(pDC, nType, rectArg); int CX_BORDER=1,CY_BORDER=1; if(pDC==NULL) { RedrawWindow(rectArg,NULL,RDW_INVALIDATE|RDW_NOCHILDREN); return; } ASSERT_VALID(pDC); CRect rc=rectArg; switch(nType) { case splitBorder: //重画分割窗口边界,使之为红色 pDC->Draw3dRect(rc,RGB(255,0,0),RGB(255,0,0)); rc.InflateRect(-CX_BORDER,-CY_BORDER); pDC->Draw3dRect(rc,RGB(255,0,0),RGB(255,0,0)); return; case splitBox: pDC->Draw3dRect(rc,RGB(0,0,0),RGB(0,0,0)); rc.InflateRect(-CX_BORDER,-CY_BORDER); pDC->Draw3dRect(rc,RGB(0,0,0),RGB(0,0,0)); rc.InflateRect(-CX_BORDER,-CY_BORDER); pDC->FillSolidRect(rc,RGB(0,0,0)); pDC->Draw3dRect(rc,RGB(0,0,0),RGB(0,0,0)); return; case splitBar: //重画分割条,使之为绿色 pDC->FillSolidRect(rc,RGB(255,255,255)); rc.InflateRect(-5,-5); pDC->Draw3dRect(rc,RGB(255,0,0),RGB(255,0,0)); return; default: ASSERT(FALSE); } pDC->FillSolidRect(rc,RGB(0,0,255)); }
void CSplitterWndEx::OnInvertTracker(CRect &rect) //此函数在切割窗口大小变化时调用,在onlbuttonup()函数中添加invalidate()函数,刷屏 { CSplitterWnd::OnInvertTracker(rect); ASSERT_VALID(this); ASSERT(!rect.IsRectEmpty()); ASSERT((GetStyle()&WS_CLIPCHILDREN)==0); CRect rc=rect; rc.InflateRect(1,1); CDC* pDC=GetDC(); CBrush* pBrush=CDC::GetHalftoneBrush(); HBRUSH hOldBrush=NULL; if(pBrush!=NULL) hOldBrush=(HBRUSH)SelectObject(pDC->m_hDC,pBrush->m_hObject); pDC->PatBlt(rc.left,rc.top,rc.Width(),rc.Height(),WHITENESS);
if(hOldBrush!=NULL) SelectObject(pDC->m_hDC,hOldBrush); ReleaseDC(pDC); }
|