📄 dockpagebar.cpp
字号:
ASSERT(!((borderDetect&BORDER_DETECT_LEFT)&&(borderDetect&BORDER_DETECT_RIGHT)));
ASSERT(!((borderDetect&BORDER_DETECT_TOP)&&(borderDetect&BORDER_DETECT_BOTTOM)));
if(borderDetect&BORDER_DETECT_LEFT)
{
borderDetect=BORDER_DETECT_LEFT;
if(DOCK_IN_FRAME_CLIENT==dwDockStyle||DOCK_IN_FRAME_BORDER==dwDockStyle)
dwDockStyle=CBRS_ALIGN_LEFT;
else
dwDockStyle=pDockPageBarWnd->m_dwStyle;
}else if(borderDetect&BORDER_DETECT_RIGHT){
borderDetect=BORDER_DETECT_RIGHT;
if(DOCK_IN_FRAME_CLIENT==dwDockStyle||DOCK_IN_FRAME_BORDER==dwDockStyle)
dwDockStyle=CBRS_ALIGN_RIGHT;
else
dwDockStyle=pDockPageBarWnd->m_dwStyle;
}else if(borderDetect&BORDER_DETECT_TOP){
borderDetect=BORDER_DETECT_TOP;
if(DOCK_IN_FRAME_CLIENT==dwDockStyle||DOCK_IN_FRAME_BORDER==dwDockStyle)
dwDockStyle=CBRS_ALIGN_TOP;
else
dwDockStyle=pDockPageBarWnd->m_dwStyle;
}else if(borderDetect&BORDER_DETECT_BOTTOM){
borderDetect=BORDER_DETECT_BOTTOM;
if(DOCK_IN_FRAME_CLIENT==dwDockStyle||DOCK_IN_FRAME_BORDER==dwDockStyle)
dwDockStyle=CBRS_ALIGN_BOTTOM;
else
dwDockStyle=pDockPageBarWnd->m_dwStyle;
}
CRect rc;
m_pBar->GetWindowRect(&rc);
INT hightWidth;
if(DOCK_IN_FRAME_BORDER==m_endDragDockStruct.dwDockStyle)
{
m_curRect.DeflateRect(VER_BORDER_DETECT_PIXELS,HOR_BORDER_DETECT_PIXELS);
if(borderDetect&(BORDER_DETECT_LEFT|BORDER_DETECT_RIGHT)){
if(m_curRect==mainFrameClientRect)
(borderDetect&BORDER_DETECT_LEFT ? m_curRect.left:m_curRect.right)=
(borderDetect&BORDER_DETECT_LEFT ? mainFrameClientRect.left:mainFrameClientRect.right);
else
(borderDetect&BORDER_DETECT_LEFT ? m_curRect.left:m_curRect.right)=
(borderDetect&BORDER_DETECT_LEFT ? mainFrameRect.left:mainFrameRect.right);
m_curRect.top=mainFrameRect.top;
m_curRect.bottom=mainFrameRect.bottom;
}else{
if(m_curRect==mainFrameClientRect)
(borderDetect&BORDER_DETECT_TOP ? m_curRect.top:m_curRect.bottom)=
(borderDetect&BORDER_DETECT_TOP ? mainFrameClientRect.top:mainFrameClientRect.bottom);
else
(borderDetect&BORDER_DETECT_TOP ? m_curRect.top:m_curRect.bottom)=
(borderDetect&BORDER_DETECT_TOP ? mainFrameRect.top:mainFrameRect.bottom);
m_curRect.left=mainFrameRect.left;
m_curRect.right=mainFrameRect.right;
}
hightWidth=borderDetect&(BORDER_DETECT_LEFT|BORDER_DETECT_RIGHT) ? rc.Width():rc.Height();//mainFrameRect.Width():mainFrameRect.Height();
}else
hightWidth=borderDetect&(BORDER_DETECT_LEFT|BORDER_DETECT_RIGHT) ? rc.Width():rc.Height();
switch(borderDetect)
{
case BORDER_DETECT_LEFT:
m_curRect.right=m_curRect.left+min(hightWidth,m_curRect.Width()/2);
break;
case BORDER_DETECT_RIGHT:
m_curRect.left=m_curRect.right-min(hightWidth,m_curRect.Width()/2);
break;
case BORDER_DETECT_TOP:
m_curRect.bottom=m_curRect.top+min(hightWidth,m_curRect.Height()/2);
break;
case BORDER_DETECT_BOTTOM:
m_curRect.top=m_curRect.bottom-min(hightWidth,m_curRect.Height()/2);
break;
default:
m_bAdvancedDock=FALSE;
}
}else
m_bAdvancedDock=FALSE;
if(m_bAdvancedDock){
ASSERT(VERTF(dwDockStyle)||HORZF(dwDockStyle));
m_dwOverDockStyle=dwDockStyle;
if(DOCK_IN_DOCK_PAGE_BAR==m_endDragDockStruct.dwDockStyle){
m_endDragDockStruct.pDockPageBar=pDockPageBarWnd;
m_endDragDockStruct.dwDockStyle|=borderDetect;
}
else
m_endDragDockStruct.pDockPageBar=NULL;;
m_rectDragVert.OffsetRect(ptOffset);
m_rectDragHorz.OffsetRect(ptOffset);
m_rectFrameDragHorz.OffsetRect(ptOffset);
m_rectFrameDragVert.OffsetRect(ptOffset);
}else{
// offset all drag rects to new position
m_rectDragHorz.OffsetRect(ptOffset);
m_rectFrameDragHorz.OffsetRect(ptOffset);
m_rectDragVert.OffsetRect(ptOffset);
m_rectFrameDragVert.OffsetRect(ptOffset);
m_dwOverDockStyle = 0;/*m_bForceFrame ? 0 : CanDock();*/
}
}
m_ptLast = pt;
// update feedback
if(FALSE == m_isMe)
DrawFocusRect();
else
DrawFocusRect(TRUE);
}
// get the target CDockPageBar on mouse move
BOOL CDockPageBarContext::isDockPage(CPoint pt)
{
m_isMe = FALSE;
HWND hWnd = WindowFromPoint(pt);
CWnd * pWnd=CWnd::FromHandle (hWnd);
if(pWnd->IsKindOf (RUNTIME_CLASS(CDockPageBar)))
{
CDockPageBar* pBar = (CDockPageBar*)pWnd;
if(pBar != m_pBar)
{
CRect rectCaption,rectItem;
pBar->GetWindowRect (&rectCaption);
rectItem=rectCaption;
rectCaption.bottom = rectCaption.top + pBar->m_cyGripper;
rectItem.top=rectItem.bottom-ITEMBUTTON_HEIGHT;
if(rectCaption.PtInRect (pt)||
(pBar->m_PageList.GetCount()>1)&&(rectItem.PtInRect(pt)))
{
m_pTgDockPage = pBar;
pBar->GetWindowRect (&m_addRect);
return TRUE;
}
}
else
{
m_isMe = TRUE;
}
}else if(pWnd->IsKindOf(RUNTIME_CLASS(CMiniDockFrameWnd))){ //Docking in the float window
CMiniDockFrameWnd * pFrameWnd=(CMiniDockFrameWnd *)pWnd;
//Get the DockPageBar on the Floating MiniDockFrameWnd
CDockPageBar* pBar = (CDockPageBar* )CWnd::FromHandle(pWnd->m_hWndOwner);
ASSERT(pBar->IsKindOf(RUNTIME_CLASS(CDockPageBar)));
if(pBar != m_pBar)
{
CRect rectCaption,rectItem;
pFrameWnd->GetWindowRect (&rectCaption);
pBar->GetWindowRect(&rectItem);
rectCaption.bottom = rectCaption.top + pBar->m_cyGripper;
rectItem.top=rectItem.bottom-ITEMBUTTON_HEIGHT;
if(rectCaption.PtInRect (pt)||
(pBar->m_PageList.GetCount()>1)&&(rectItem.PtInRect(pt)))
{
m_pTgDockPage = pBar;
pBar->GetWindowRect (&m_addRect);
return TRUE;
}
}
else
{
m_isMe = TRUE;
}
}
m_pTgDockPage = NULL;
return FALSE;
}
BOOL CDockPageBarContext::GetDockBarZOrderList(HWND hParent, int zOrderList[4])
{
HWND hWndTop,hWndBottom,hWndLeft,hWndRight;
hWndTop= ::GetDlgItem(hParent,AFX_IDW_DOCKBAR_TOP);
hWndBottom= ::GetDlgItem(hParent,AFX_IDW_DOCKBAR_BOTTOM);
hWndLeft= ::GetDlgItem(hParent,AFX_IDW_DOCKBAR_LEFT);
hWndRight= ::GetDlgItem(hParent,AFX_IDW_DOCKBAR_RIGHT);
HWND hCurWnd=GetTopWindow(hParent),hPreWnd;
int i=0,zOrder=0;
do{
if(hCurWnd==hWndTop){
zOrderList[0]=zOrder;
i++;
}
if(hCurWnd==hWndBottom){
zOrderList[1]=zOrder;
i++;
}
if(hCurWnd==hWndLeft){
zOrderList[2]=zOrder;
i++;
}
if(hCurWnd==hWndRight){
zOrderList[3]=zOrder;
i++;
}
hPreWnd=hCurWnd;
hCurWnd=GetNextWindow(hPreWnd,GW_HWNDNEXT);
zOrder++;
} while(i<4&&NULL!=hCurWnd);
if(i<4)
return FALSE;
else
return TRUE;
}
void CDockPageBarContext::EndDrag()
{
CancelLoop();
if(TRUE == m_isMe)
return;
// drag to another CDockPageBar
if((NULL != m_pTgDockPage) && (m_dwOverDockStyle == CBRS_ALIGN_INSERT_PAGE))
{
if(TRUE == m_isPage) // drag PageItem
{
CPageItem * pItem = (CPageItem *)((CDockPageBar*)m_pBar)->DeletePage ();
m_pTgDockPage->AddPage(pItem);
}
else // drag a CDockPageBar object to another CDockPageBar
{
m_pTgDockPage->AddPage((CDockPageBar*)m_pBar);
}
return;
}
// if drag a PageItem, create a new bar which contains the PageItem
CControlBar* pBar;
if(TRUE == m_isPage) // drag PageItem (dock or float)
pBar = CreateNewBar();
else
pBar = m_pBar; // drag CDockPageBar
if(NULL == pBar)
return;
if (m_dwOverDockStyle != 0)
{
CDockBar* pDockBar;
CFrameWnd * pFrameWnd=(CFrameWnd *)AfxGetMainWnd();
//Find the specific docking bar
POSITION pos = pFrameWnd->m_listControlBars.GetHeadPosition();
while (pos != NULL)
{
pDockBar = (CDockBar*)pFrameWnd->m_listControlBars.GetNext(pos);
if (pDockBar->IsDockBar() && pDockBar->IsWindowVisible() &&
(pDockBar->m_dwStyle & m_dwOverDockStyle & CBRS_ALIGN_ANY) &&
(!pDockBar->m_bFloating ||
(m_dwOverDockStyle & pDockBar->m_dwStyle & CBRS_FLOAT_MULTI)))
{
break;
}
}
ASSERT(pDockBar != NULL);
CRect rect;
if(m_bAdvancedDock){
rect=m_curRect;
if(m_endDragDockStruct.dwDockStyle&DOCK_IN_DOCK_PAGE_BAR)
{
ASSERT(m_endDragDockStruct.pDockPageBar);
ASSERT(m_endDragDockStruct.pDockPageBar->IsKindOf(RUNTIME_CLASS(CDockPageBar)));
CRect rc;
m_endDragDockStruct.pDockPageBar->GetWindowRect(&rc);
if(VERTF(m_endDragDockStruct.pDockPageBar->m_dwStyle))
{
if(m_endDragDockStruct.dwDockStyle&BORDER_DETECT_RIGHT)
rect.OffsetRect(rc.Width()/2,0);
else if(m_endDragDockStruct.dwDockStyle&BORDER_DETECT_LEFT)
rect.OffsetRect(-rc.Width()/2,0);
}else if(HORZF(m_endDragDockStruct.pDockPageBar->m_dwStyle))
{
if(m_endDragDockStruct.dwDockStyle&BORDER_DETECT_TOP)
rect.OffsetRect(0,-rc.Width()/2);
else if(m_endDragDockStruct.dwDockStyle&BORDER_DETECT_BOTTOM)
rect.OffsetRect(0,rc.Width()/2);
}else
ASSERT(FALSE);
}
//Advanced docking :)
if(VERTF(m_dwOverDockStyle))
{
((CDockPageBar*)pBar)->GetVerSize().cx=rect.Width();
((CDockPageBar*)pBar)->GetVerSize().cy=rect.Height();
}else if(HORZF(m_dwOverDockStyle))
{
((CDockPageBar*)pBar)->GetHorSize().cx=rect.Width();
((CDockPageBar*)pBar)->GetHorSize().cy=rect.Height();
}else
ASSERT(FALSE);
}else
rect= (m_dwOverDockStyle & CBRS_ORIENT_VERT) ? m_rectDragVert : m_rectDragHorz;
UINT uID = _AfxGetDlgCtrlID(pDockBar->m_hWnd);
if (uID >= AFX_IDW_DOCKBAR_TOP &&
uID <= AFX_IDW_DOCKBAR_BOTTOM)
{
m_uMRUDockID = uID;
m_rectMRUDockPos = rect;
pDockBar->ScreenToClient(&m_rectMRUDockPos);
//find the max or min value from the three
//set func to max or min
#define TRI_COMPARE(func,a,b,c) func(func(a,b),c)==c ? c:func(a,b)
#define ZORDER_INDEX_TOP 0
#define ZORDER_INDEX_BOTTOM 1
#define ZORDER_INDEX_LEFT 2
#define ZORDER_INDEX_RIGHT 3
int zOrderList[4];
int minMaxZOrder;
CRect clientRect;
pFrameWnd->GetClientRect(&clientRect);
HWND hWndTop,hWndBottom,hWndLeft,hWndRight;
hWndTop= ::GetDlgItem(pFrameWnd->m_hWnd,AFX_IDW_DOCKBAR_TOP);
hWndBottom= ::GetDlgItem(pFrameWnd->m_hWnd,AFX_IDW_DOCKBAR_BOTTOM);
hWndLeft= ::GetDlgItem(pFrameWnd->m_hWnd,AFX_IDW_DOCKBAR_LEFT);
hWndRight= ::GetDlgItem(pFrameWnd->m_hWnd,AFX_IDW_DOCKBAR_RIGHT);
VERIFY(GetDockBarZOrderList(pFrameWnd->m_hWnd,zOrderList));
switch(uID){
case AFX_IDW_DOCKBAR_TOP:
{
if(m_rectMRUDockPos.Width()>clientRect.Width()){
minMaxZOrder=TRI_COMPARE(min,zOrderList[ZORDER_INDEX_LEFT],zOrderList[ZORDER_INDEX_RIGHT],zOrderList[ZORDER_INDEX_BOTTOM]);
if(minMaxZOrder==zOrderList[ZORDER_INDEX_LEFT])
::SetWindowPos(hWndTop,::GetNextWindow(hWndLeft,GW_HWNDPREV),0,0,0,0,SWP_NOSIZE);
else if(minMaxZOrder==zOrderList[ZORDER_INDEX_RIGHT])
::SetWindowPos(hWndTop,::GetNextWindow(hWndRight,GW_HWNDPREV),0,0,0,0,SWP_NOSIZE);
else if(minMaxZOrder==zOrderList[ZORDER_INDEX_BOTTOM])
::SetWindowPos(hWndTop,::GetNextWindow(hWndBottom,GW_HWNDPREV),0,0,0,0,SWP_NOSIZE);
else
{ASSERT(FALSE);}
}
}
break;
case AFX_IDW_DOCKBAR_BOTTOM:
{
if(m_rectMRUDockPos.Width()>clientRect.Width()){
minMaxZOrder=TRI_COMPARE(min,zOrderList[ZORDER_INDEX_LEFT],zOrderList[ZORDER_INDEX_RIGHT],zOrderList[ZORDER_INDEX_TOP]);
if(minMaxZOrder==zOrderList[ZORDER_INDEX_LEFT])
::SetWindowPos(hWndBottom,::GetNextWindow(hWndLeft,GW_HWNDPREV),0,0,0,0,SWP_NOSIZE);
else if(minMaxZOrder==zOrderList[ZORDER_INDEX_RIGHT])
::SetWindowPos(hWndBottom,::GetNextWindow(hWndRight,GW_HWNDPREV),0,0,0,0,SWP_NOSIZE);
else if(minMaxZOrder==zOrderList[ZORDER_INDEX_TOP])
::SetWindowPos(hWndBottom,::GetNextWindow(hWndTop,GW_HWNDPREV),0,0,0,0,SWP_NOSIZE);
else
{ASSERT(FALSE);}
}
}
break;
case AFX_IDW_DOCKBAR_LEFT:
{
if(m_rectMRUDockPos.Height()>clientRect.Height()){
minMaxZOrder=TRI_COMPARE(min,zOrderList[ZORDER_INDEX_RIGHT],zOrderList[ZORDER_INDEX_TOP],zOrderList[ZORDER_INDEX_BOTTOM]);
if(minMaxZOrder==zOrderList[ZORDER_INDEX_TOP])
::SetWindowPos(hWndLeft,::GetNextWindow(hWndTop,GW_HWNDPREV),0,0,0,0,SWP_NOSIZE);
else if(minMaxZOrder==zOrderList[ZORDER_INDEX_RIGHT])
::SetWindowPos(hWndLeft,::GetNextWindow(hWndRight,GW_HWNDPREV),0,0,0,0,SWP_NOSIZE);
else if(minMaxZOrder==zOrderList[ZORDER_INDEX_BOTTOM])
::SetWindowPos(hWndLeft,::GetNextWindow(hWndBottom,GW_HWNDPREV),0,0,0,0,SWP_NOSIZE);
else
{ASSERT(FALSE);}
}
}
break;
case AFX_IDW_DOCKBAR_RIGHT:
{
if(m_rectMRUDockPos.Height()>clientRect.Height()){
minMaxZOrder=TRI_COMPARE(min,zOrderList[ZORDER_INDEX_LEFT],zOrderList[ZORDER_INDEX_TOP],zOrderList[ZORDER_INDEX_BOTTOM]);
if(minMaxZOrder==zOrderList[ZORDER_INDEX_LEFT])
::SetWindowPos(hWndRight,::GetNextWindow(hWndLeft,GW_HWNDPREV),0,0,0,0,SWP_NOSIZE);
else if(minMaxZOrder==zOrderList[ZORDER_INDEX_TOP])
::SetWindowPos(hWndRight,::GetNextWindow(hWndTop,GW_HWNDPREV),0,0,0,0,SWP_NOSIZE);
else if(minMaxZOrder==zOrderList[ZORDER_INDEX_BOTTOM])
::SetWindowPos(hWndRight,::GetNextWindow(hWndBottom,GW_HWNDPREV),0,0,0,0,SWP_NOSIZE);
else
{ASSERT(FALSE);}
}
}
break;
}
}
// dock it at the specified position, RecalcLayout will snap
m_pDockSite->DockControlBar(pBar, pDockBar, &rect);
m_pDockSite->RecalcLayout();
if(DOCK_IN_DOCK_PAGE_BAR==m_endDragDockStruct.dwDockStyle)
m_endDragDockStruct.pDockPageBar->SetFocus();
}else if ((m_dwStyle & CBRS_SIZE_DYNAMIC) || (HORZF(m_dwStyle) && !m_bFlip) ||
(VERTF(m_dwStyle) && m_bFlip))
{
m_dwMRUFloatStyle = CBRS_ALIGN_TOP | (m_dwDockStyle & CBRS_FLOAT_MULTI);
m_ptMRUFloatPos = m_rectFrameDragHorz.TopLeft();
m_pDockSite->FloatControlBar(pBar, m_ptMRUFloatPos, m_dwMRUFloatStyle);
}else // vertical float
{
m_dwMRUFloatStyle = CBRS_ALIGN_LEFT | (m_dwDockStyle & CBRS_FLOAT_MULTI);
m_ptMRUFloatPos = m_rectFrameDragVert.TopLeft();
m_pDockSite->FloatControlBar(pBar, m_ptMRUFloatPos, m_dwMRUFloatStyle);
}
}
CDockPageBar* CDockPageBarContext::CreateNewBar()
{
CPageItem * pItem = (CPageItem *)((CDockPageBar*)m_pBar)->DeletePage ();
CDockPageBar* pBar = new CDockPageBar();
if (!(pBar->Create(_T("New Bar"), m_pDockSite, 12345)))
{
TRACE0("Failed to create mybar\n");
return NULL; // fail to create
}
pBar->SetBarStyle(m_pBar->GetBarStyle() |
CBRS_TOOLTIPS | CBRS_FLYBY | CBRS_SIZE_DYNAMIC);
pBar->EnableDocking(CBRS_ALIGN_ANY);
pBar->AddPage (pItem);
m_pDPBar.AddTail(pBar);
return pBar;
}
void CDockPageBarContext::DrawFocusRect(BOOL bRemoveRect)
{
ASSERT(m_pDC != NULL);
// default to thin frame
CSize size(3,3);
// determine new rect and size
CRect rect;
CBrush* pWhiteBrush = CBrush::FromHandle((HBRUSH)::GetStockObject(WHITE_BRUSH));
CBrush* pDitherBrush = CDC::GetHalftoneBrush();
CBrush* pBrush = pDitherBrush;
if(m_bAdvancedDock)
{
rect=m_curRect;;
}else{
if (HORZF(m_dwOverDockStyle))
rect = m_rectDragHorz;
else if (VERTF(m_dwOverDockStyle))
rect = m_rectDragVert;
else
{
// use thick frame instead
size.cx = GetSystemMetrics(SM_CXFRAME) - CX_BORDER;
size.cy = GetSystemMetrics(SM_CYFRAME) - CY_BORDER;
if ((HORZF(m_dwStyle) && !m_bFlip) || (VERTF(m_dwStyle) && m_bFlip))
rect = m_rectFrameDragHorz;
else
rect = m_rectFrameDragVert;
pBrush = pDitherBrush;
}
}
if (bRemoveRect)
size.cx = size.cy = 0;
if(m_dwOverDockStyle == CBRS_ALIGN_INSERT_PAGE)
rect = m_addRect; // rect of target CDockPageBar
// draw it and remember last size
m_pDC->DrawDragRect(&rect, size, &m_rectLast, m_sizeLast,
pBrush, m_bDitherLast ? pDitherBrush : pWhiteBrush);
m_rectLast = rect;
m_sizeLast = size;
m_bDitherLast = (pBrush == pDitherBrush);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -