📄 dockpagebar.cpp
字号:
m_biHide.Move(ptOrgBtn);
m_biHide.Paint(pDC, m_isActive);
ptOrgBtn.x -= 17;
m_stud.Move (ptOrgBtn);
m_stud.Paint(pDC, m_isActive);
}
void CDockPageBar::NcCalcClient(LPRECT pRc, UINT nDockBarID)
{
CRect rcBar(pRc); // save the bar rect
// subtract edges
baseCDockPageBar::NcCalcClient(pRc, nDockBarID);
if (!HasGripper()&&!m_PageList.GetCount())
return;
CRect rc(pRc); // the client rect as calculated by the base class
rc.DeflateRect(1,0,1,0);
BOOL bHorz = (nDockBarID == AFX_IDW_DOCKBAR_TOP) ||
(nDockBarID == AFX_IDW_DOCKBAR_BOTTOM);
if(!IsFloating()){
bHorz ? rc.DeflateRect(0, m_cyGripper-1, 2,0):
rc.DeflateRect(0, m_cyGripper-1, 0,0);
}
if(m_PageList.GetCount()>1)
rc.DeflateRect(0,0,0,ITEMBUTTON_HEIGHT);
DEFLECT_RECT_FOR_STATIC_LINK(rc);
*pRc = rc;
}
void CDockPageBar::OnNcLButtonUp(UINT nHitTest, CPoint point)
{
if (nHitTest == HTHIDE)
m_pDockSite->ShowControlBar(this, FALSE, FALSE); // hide
if (nHitTest == HTSTUD)
OnStudClick();
baseCDockPageBar::OnNcLButtonUp(nHitTest, point);
if(::IsWindow(m_hWnd))
SendMessage(WM_NCPAINT);
}
void CDockPageBar::OnStudClick()
{
//GetParentFrame()->PostMessage(WM_AUTOHIDE_ON, m_nDockBarID, (LPARAM)this);
//CDockPageBar * pWnd = (CDockPageBar *)lParam;
CAutoHideBar * pAutoHideBar;
switch(m_nDockBarID)
{
case AFX_IDW_DOCKBAR_TOP:
pAutoHideBar = (CAutoHideBar *)((CFrameWnd*)AfxGetMainWnd())->GetControlBar(AHBRS_TOP);
break;
case AFX_IDW_DOCKBAR_BOTTOM:
pAutoHideBar = (CAutoHideBar *)((CFrameWnd*)AfxGetMainWnd())->GetControlBar(AHBRS_BOTTOM);
break;
case AFX_IDW_DOCKBAR_LEFT:
pAutoHideBar = (CAutoHideBar *)((CFrameWnd*)AfxGetMainWnd())->GetControlBar(AHBRS_LEFT);
break;
case AFX_IDW_DOCKBAR_RIGHT:
pAutoHideBar = (CAutoHideBar *)((CFrameWnd*)AfxGetMainWnd())->GetControlBar(AHBRS_RIGHT);
break;
}
pAutoHideBar->HidePageBar(this);
((CFrameWnd*)AfxGetMainWnd())->RecalcLayout();
}
BOOL CDockPageBar::HasGripper() const
{
if (IsFloating())
return FALSE;
return TRUE;
}
LRESULT CDockPageBar::OnNcHitTest(CPoint point)
{
CRect rcBar;
GetWindowRect(rcBar);
UINT nRet = baseCDockPageBar::OnNcHitTest(point);
if (nRet != HTCLIENT)
return nRet;
CRect rc = m_biHide.GetRect();
rc.OffsetRect(rcBar.TopLeft());
if (rc.PtInRect(point))
return HTHIDE;
rc = m_stud.GetRect();
rc.OffsetRect(rcBar.TopLeft());
if (rc.PtInRect(point))
return HTSTUD;
GetItemGroupRect(&rc);
if(rc.PtInRect(point))
return HTITEMBUTTON;
GetCaptionRect(&rc);
if(rc.PtInRect(point))
return HTGRIPPER;
return HTCLIENT;
}
/////////////////////////////////////////////////////////////////////////////
// about PageIte
CPageItem* CDockPageBar::GetPageItem(int nIndex)
{
CPageItem *pItem = NULL;
POSITION pos = m_PageList.FindIndex(nIndex);
if(pos)
pItem = (CPageItem*)m_PageList.GetAt(pos);
return pItem;
}
void CDockPageBar::SetActivePage(int nIndex)
{
if(nIndex == m_nActivePage)
return;
CPageItem *pItem;
pItem = (CPageItem*)GetPageItem(nIndex);
if(!pItem) return;
m_nActivePage = nIndex;
m_Title = pItem->m_sText;
SetWindowText(m_Title);
SendMessage(WM_NCPAINT);
Invalidate();
}
void CDockPageBar::OnSize(UINT nType, int cx, int cy)
{
UpdateSize();
Invalidate();
SendMessage(WM_NCPAINT);
}
void CDockPageBar::UpdateSize()
{
UINT PageCount = m_PageList.GetCount();
if(PageCount < 1) return;
CPageItem *pItem;
CRect ClientRect;
if(PageCount == 1)
{
GetClientRect(ClientRect);
pItem = (CPageItem*)GetPageItem(0);;
if(pItem->m_pWnd)
{
pItem->m_pWnd->MoveWindow(ClientRect);
pItem->m_pWnd->ShowWindow(SW_SHOW);
}
return;
}
POSITION pos;
CRect rect,ItemRect,wndRect;
GetWindowRect(&wndRect);
GetClientRect(ClientRect);
//Note: Here the rect/ItemRect' coordinate is for NonClient painting,
// so it is referenced to the current window's topleft.
GetItemGroupRect(&rect);
rect.OffsetRect(-wndRect.TopLeft());
rect.DeflateRect(4,-3,4,3);
DEFLECT_RECT_FOR_STATIC_LINK(rect);
//rect.right-=10;
ItemRect = rect;
int AreaWidth = 0,ItemWidth,ItemIndex=0;
for(pos=m_PageList.GetHeadPosition();pos!=NULL;ItemIndex++)
{
pItem=(CPageItem*)m_PageList.GetNext(pos);
if(pItem)
{
ItemWidth = pItem->m_TabWidth;
AreaWidth += ItemWidth;
ItemRect.right = ItemRect.left+ItemWidth-1;
pItem->m_rect = ItemRect;
ItemRect.left = ItemRect.right + 1;
if(pItem->m_pWnd)
pItem->m_pWnd->MoveWindow(ClientRect);
}
}
if(AreaWidth > rect.Width())
{
ItemRect = rect;
int AreaWidth,MaxWidth = rect.Width()/PageCount;
for(pos=m_PageList.GetHeadPosition();pos!=NULL;)
{
pItem=(CPageItem*)m_PageList.GetNext(pos);
if(pItem)
{
AreaWidth = pItem->m_TabWidth;
ItemWidth = (MaxWidth < AreaWidth)?MaxWidth:AreaWidth;
ItemRect.right = ItemRect.left+ItemWidth;
pItem->m_rect = ItemRect;
ItemRect.left = ItemRect.right + 1;
}
}
}
}
void CDockPageBar::GetItemGroupRect(LPRECT lpRect)
{
CRect rcBar,cr;
GetWindowRect(rcBar);
rcBar.left+=1;
rcBar.right-=3;
rcBar.bottom-=1;
#ifdef STATIC_MFC_LINK
rcBar.top=rcBar.bottom-ITEMBUTTON_HEIGHT;//+2;
#else
rcBar.top=rcBar.bottom-ITEMBUTTON_HEIGHT+2;
#endif
//Note: Here we return the rect, which referenced to the screen
*lpRect=rcBar;
}
void CDockPageBar::GetCaptionRect(LPRECT lpRect)
{
CRect rcBar,cr;
GetWindowRect(rcBar);
rcBar.left+=1;
rcBar.right-=3;
rcBar.top-=1;
rcBar.bottom=rcBar.top+CAPTION_HEIGHT;
*lpRect=rcBar;
}
BOOL CDockPageBar::AddPage(CWnd *pWnd, LPCTSTR sText, UINT IconID)
{
ASSERT(IsWindow(pWnd->m_hWnd));
DWORD dwStyle=pWnd->GetStyle();
if(!(dwStyle&WS_CHILD)){
TRACE0("Force the dock page bar content to be WS_CHILD style!");
pWnd->ModifyStyle(WS_POPUP|WS_OVERLAPPED,WS_CHILD);
}
CPageItem *pItem;
pItem = new CPageItem();
pItem->m_pWnd = pWnd;
pItem->m_pWnd->SetParent (this);
pItem->m_sText = sText;
CClientDC dc(this);
pItem->m_TabWidth = dc.GetTextExtent (sText).cx;
if(IconID)
{
pItem->m_hIcon = AfxGetApp()->LoadIcon(IconID);
pItem->m_TabWidth += 18;
}
else
pItem->m_hIcon = NULL;
pItem->m_TabWidth += 9;
if(pWnd)
{
CRect rect;
GetClientRect(rect);
pWnd->MoveWindow(rect);
pWnd->ShowWindow(SW_HIDE);
}
m_PageList.AddTail(pItem);
UpdateWindow();
return TRUE;
}
BOOL CDockPageBar::AddPage(CPageItem *pPageItem)
{
pPageItem->m_pWnd->SetParent (this);
m_PageList.AddTail(pPageItem);
SetFocus();
//Fore the system to send WM_NCCALCSIZE to update the client rect
SetWindowPos(NULL,0,0,0,0,SWP_NOZORDER|SWP_NOMOVE|SWP_NOSIZE);
//Use the new size to update the window
UpdateWindow();
return TRUE;
}
BOOL CDockPageBar::AddPage(CDockPageBar *dockPageBar)
{
POSITION pos;
CPageItem* pItem;
for(pos = dockPageBar->m_PageList.GetHeadPosition();pos!=NULL;)
{
pItem=(CPageItem*)dockPageBar->m_PageList.GetNext(pos);
if(pItem)
{
AddPage(pItem);
SetActivePage(m_PageList.GetCount()-1);
}
}
dockPageBar->m_pDockContext->m_pDockSite->FloatControlBar(dockPageBar,CSize(0,0),0);
dockPageBar->m_PageList.RemoveAll();
dockPageBar->m_pDockContext->m_pDockSite->RemoveControlBar(dockPageBar);
UpdateWindow();
return dockPageBar->DestroyWindow ();
}
CPageItem* CDockPageBar::DeletePage()
{
CPageItem *pItem = NULL;
POSITION pos = m_PageList.FindIndex(m_nActivePage);
if(!pos)
{
return NULL;
}
pItem = (CPageItem*)m_PageList.GetAt(pos);
pItem->m_pWnd->ShowWindow(SW_HIDE);
m_PageList.RemoveAt (pos);
m_nActivePage = -1;
//Fore the system to send WM_NCCALCSIZE to update the client rect
if(m_PageList.GetCount()==1)
SetWindowPos(NULL,0,0,0,0,SWP_NOZORDER|SWP_NOMOVE|SWP_NOSIZE);
UpdateWindow();
return pItem;
}
void CDockPageBar::UpdateWindow()
{
if(m_nActivePage < 0)
SetActivePage(0);
UpdateSize();
Invalidate();
SendMessage(WM_NCPAINT);;
}
void CDockPageBar::DEFLECT_RECT_FOR_STATIC_LINK(CRect & rect)
{
#ifdef STATIC_MFC_LINK
switch(m_dwStyle&CBRS_ALIGN_ANY)
{
case CBRS_ALIGN_LEFT:
rect.DeflateRect(1,1,1,1);
break;
case CBRS_ALIGN_RIGHT:
rect.DeflateRect(1,1,0,1);
break;
case CBRS_ALIGN_TOP:
rect.DeflateRect(1,1,0,1);
break;
case CBRS_ALIGN_BOTTOM:
rect.DeflateRect(1,1,0,1);
break;
default:
ASSERT(FALSE);
}
#endif
}
void CDockPageBar::OnNcPaint()
{
//If you are drawing the plastic line to change the dock page bar'size,
//No painting will be done to avoid the dirty result
if(m_bTracking)
return;
// get window DC that is clipped to the non-client area
CWindowDC dc(this);
CRect rcClient, rcBar;
GetClientRect(rcClient);
ClientToScreen(rcClient);
rcClient.DeflateRect(-1,0,-1,0);
GetWindowRect(rcBar);
rcClient.OffsetRect(-rcBar.TopLeft());
rcBar.OffsetRect(-rcBar.TopLeft());
CDC mdc;
mdc.CreateCompatibleDC(&dc);
CBitmap bm;
bm.CreateCompatibleBitmap(&dc, rcBar.Width(), rcBar.Height());
CBitmap* pOldBm = mdc.SelectObject(&bm);
// draw borders in non-client area
CRect rcDraw = rcBar;
DrawBorders(&mdc, rcDraw);
// erase the NC background
mdc.FillRect(rcDraw, CBrush::FromHandle((HBRUSH) GetClassLong(m_hWnd, GCL_HBRBACKGROUND)));
if(!IsFloating()){
//Draw border edges
if (m_dwSCBStyle & SCBS_SHOWEDGES)
{
CRect rcEdge; // paint the sizing edges
for (int i = 0; i < 4; i++)
if (GetEdgeRect(rcBar, GetEdgeHTCode(i), rcEdge))
mdc.Draw3dRect(rcEdge, ::GetSysColor(COLOR_BTNHIGHLIGHT),
::GetSysColor(COLOR_BTNSHADOW));
}
//Draw Gripper(the caption bar)
CRect rc=rcClient;
DEFLECT_RECT_FOR_STATIC_LINK(rcClient);
NcPaintGripper(&mdc, rcClient);
rcClient=rc; //restore
//Draw Client Boarder
CRect clientBorderRc=rcBar;
clientBorderRc.left=rcClient.left-1;
clientBorderRc.right=rcClient.right;
DEFLECT_RECT_FOR_STATIC_LINK(clientBorderRc);
if (IsHorzDocked())
clientBorderRc.DeflateRect(0,m_cyGripper,0,3);
else
clientBorderRc.DeflateRect(0,m_cyGripper,0,3);
if(m_PageList.GetCount()>1)
clientBorderRc.DeflateRect(0,0,0,ITEMBUTTON_HEIGHT);
CPen penRect(PS_SOLID, 1, RGB(128,128,128));
HPEN oldPen = (HPEN)mdc.SelectObject (&penRect);
mdc.MoveTo(clientBorderRc.TopLeft());
mdc.LineTo(clientBorderRc.right,clientBorderRc.top);
mdc.LineTo(clientBorderRc.right,clientBorderRc.bottom);
mdc.LineTo(clientBorderRc.left,clientBorderRc.bottom);
mdc.LineTo(clientBorderRc.left,clientBorderRc.top);
mdc.SelectObject (oldPen);
}
//Draw item tab button
if(m_PageList.GetCount()>1)
{
CPageItem *pItem;
POSITION pos;
int nItemIndex = 0;
CRect rect,wndRect;
GetItemGroupRect(&rect);
GetWindowRect(&wndRect);
rect.OffsetRect(-wndRect.TopLeft());
rect.OffsetRect(0,-1);
DEFLECT_RECT_FOR_STATIC_LINK(rect);
//rect.DeflateRect(0,-2,0,0);
CBrush brush(RGB(247,243,233));
mdc.FillRect(rect,&brush);
CPen penButton(PS_SOLID,1,GetSysColor(COLOR_3DDKSHADOW));
HPEN oldPen = (HPEN)mdc.SelectObject (&penButton);
mdc.MoveTo (rect.TopLeft() );
mdc.LineTo (rect.right, rect.top);
mdc.SelectObject (oldPen);
HFONT oldFont = (HFONT)mdc.SelectObject (m_font);
// draw PageItem
for(pos=m_PageList.GetHeadPosition();pos!=NULL;nItemIndex++)
{
pItem=(CPageItem*)m_PageList.GetNext(pos);
if(pItem)
{
pItem->Draw(&mdc,(m_nActivePage==nItemIndex)?TRUE:FALSE);
}
}
mdc.SelectObject (oldFont);
}
// client area is not our bussiness :)
dc.IntersectClipRect(rcBar);
rcClient.DeflateRect(1,0,1,0);
dc.ExcludeClipRect(rcClient);
dc.BitBlt(0, 0, rcBar.Width(), rcBar.Height(), &mdc, 0, 0, SRCCOPY);
ReleaseDC(&dc);
mdc.SelectObject(pOldBm);
bm.DeleteObject();
mdc.DeleteDC();
}
/////////////////////////////////////////////////////////////////////////////
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -