📄 guidockcontext.cpp
字号:
pDockBar->ClientToScreen(&rect);
}
// dock it at the specified position, RecalcLayout will snap
m_pDockSite->ReDockControlBar(m_pBar, pDockBar, &rect);
m_pDockSite->RecalcLayout();
}
}
else
{
CPoint ptFloat = m_ptMRUFloatPos;
if (ptFloat.x < 0 || ptFloat.y < 0)
{
ptFloat = m_rectMRUDockPos.TopLeft();
m_pBar->GetParent()->ClientToScreen(&ptFloat);
}
m_pDockSite->FloatControlBar(m_pBar, ptFloat, m_dwMRUFloatStyle);
}
}
/////////////////////////////////////////////////////////////////////////////
// CGuiDockContext Operations
void CGuiDockContext::InitLoop()
{
// handle pending WM_PAINT messages
MSG msg;
while (::PeekMessage(&msg, NULL, WM_PAINT, WM_PAINT, PM_NOREMOVE))
{
if (!GetMessage(&msg, NULL, WM_PAINT, WM_PAINT))
return;
DispatchMessage(&msg);
}
// get styles from bar
m_dwDockStyle = m_pBar->m_dwDockStyle;
m_dwStyle = m_pBar->m_dwStyle & CBRS_ALIGN_ANY;
ASSERT(m_dwStyle != 0);
// initialize state
m_rectLast.SetRectEmpty();
m_sizeLast.cx = m_sizeLast.cy = 0;
m_bForceFrame = m_bFlip = m_bDitherLast = FALSE;
// lock window update while dragging
ASSERT(m_pDC == NULL);
CWnd* pWnd = CWnd::GetDesktopWindow();
if (pWnd->LockWindowUpdate())
m_pDC = pWnd->GetDCEx(NULL, DCX_WINDOW|DCX_CACHE|DCX_LOCKWINDOWUPDATE);
else
m_pDC = pWnd->GetDCEx(NULL, DCX_WINDOW|DCX_CACHE);
ASSERT(m_pDC != NULL);
}
void CGuiDockContext::CancelLoop()
{
DrawFocusRect(TRUE); // gets rid of focus rect
ReleaseCapture();
CWnd* pWnd = CWnd::GetDesktopWindow();
pWnd->UnlockWindowUpdate();
if (m_pDC != NULL)
{
pWnd->ReleaseDC(m_pDC);
m_pDC = NULL;
}
}
/////////////////////////////////////////////////////////////////////////////
// Implementation
void CGuiDockContext::DrawFocusRect(BOOL bRemoveRect)
{
ASSERT(m_pDC != NULL);
// default to thin frame
CSize size(CX_BORDER, CY_BORDER);
// determine new rect and size
CRect rect;
CBrush* pWhiteBrush = CBrush::FromHandle((HBRUSH)::GetStockObject(WHITE_BRUSH));
CBrush* pDitherBrush = CDC::GetHalftoneBrush();
CBrush* pBrush = pWhiteBrush;
CBrush cb;
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 (afxData.bWin4 &&
(HORZF(m_dwOverDockStyle) || VERTF(m_dwOverDockStyle)))
{
// looks better one pixel in (makes the bar look pushed down)
rect.InflateRect(-CX_BORDER, -CY_BORDER);
}
*/
// draw it and remember last size
//rect.DeflateRect(2,2);
if (bFirstClic==TRUE)
{
bFirstClic=FALSE;
}
else{
if (bSecondClic==TRUE)
{
m_pDC->DrawDragRect(&rect, size, &m_rectLast, m_sizeLast,
pBrush, m_bDitherLast ? pDitherBrush : pWhiteBrush);
m_bDitherLast = (pBrush == pDitherBrush);
m_pDC->DrawDragRect(&rect, size, &m_rectLast, m_sizeLast,
pBrush, m_bDitherLast ? pDitherBrush : pWhiteBrush);
bSecondClic=FALSE;
}
else
{
m_pDC->DrawDragRect(&rect, size, &m_rectLast, m_sizeLast,
pBrush, m_bDitherLast ? pDitherBrush : pWhiteBrush);
m_rectLast = rect;
m_sizeLast = size;
m_bDitherLast = (pBrush == pDitherBrush);
}
}
//m_pDC->DrawDragRect(&rect, size, &m_rectLast, m_sizeLast/*,
// pBrush, m_bDitherLast ? pDitherBrush : pWhiteBrush*/);
/* m_rectLast = rect;
m_sizeLast = size;
m_bDitherLast = (pBrush == pDitherBrush);*/
}
void CGuiDockContext::UpdateState(BOOL* pFlag, BOOL bNewValue)
{
if (*pFlag != bNewValue)
{
*pFlag = bNewValue;
m_bFlip = (HORZF(m_dwDockStyle) && VERTF(m_dwDockStyle) && m_bFlip); // shift key
m_dwOverDockStyle = (m_bForceFrame) ? 0 : CanDock();
DrawFocusRect();
}
}
DWORD CGuiDockContext::CanDock()
{
BOOL bStyleHorz;
DWORD dwDock = 0; // Dock Canidate
DWORD dwCurr = 0; // Current Orientation
// let's check for something in our current orientation first
// then if the shift key is not forcing our orientation then
// check for horizontal or vertical orientations as long
// as we are close enough
ASSERT(m_dwStyle != 0);
bStyleHorz = HORZF(m_dwStyle);
bStyleHorz = m_bFlip ? !bStyleHorz : bStyleHorz;
if (bStyleHorz && HORZF(m_dwDockStyle))
dwDock = CanDock(m_rectDragHorz,
m_dwDockStyle & ~CBRS_ORIENT_VERT);
else if (VERTF(m_dwDockStyle))
dwDock = CanDock(m_rectDragVert,
m_dwDockStyle & ~CBRS_ORIENT_HORZ);
if (!m_bFlip)
{
if (dwDock == 0 && HORZF(m_dwDockStyle))
{
dwCurr = CanDock(m_rectDragVert,
m_dwDockStyle & ~CBRS_ORIENT_VERT);
dwDock = CanDock(m_rectDragHorz,
m_dwDockStyle & ~CBRS_ORIENT_VERT);
dwDock = (dwDock == dwCurr) ? dwDock : 0;
}
if (dwDock == 0 && VERTF(m_dwDockStyle))
{
dwCurr = CanDock(m_rectDragHorz,
m_dwDockStyle & ~CBRS_ORIENT_HORZ);
dwDock = CanDock(m_rectDragVert,
m_dwDockStyle & ~CBRS_ORIENT_HORZ);
dwDock = (dwDock == dwCurr) ? dwDock : 0;
}
}
return dwDock;
}
DWORD CGuiDockContext::CanDock(CRect rect, DWORD dwDockStyle, CDockBar** ppDockBar)
{
// dwDockStyle -- allowable styles of bar
// don't allow to dock to floating unless multi is specified
BOOL bTipoToolBar=m_pBar->IsKindOf(RUNTIME_CLASS( CGuiToolBarWnd)) ||
m_pBar->IsKindOf(RUNTIME_CLASS( CMenuBar));
dwDockStyle &= CBRS_ALIGN_ANY|CBRS_FLOAT_MULTI;
if (ppDockBar != NULL)
*ppDockBar = NULL;
POSITION pos = m_pDockSite->m_listControlBars.GetHeadPosition();
while (pos != NULL)
{
CDockBar* pDockBar = (CDockBar*)m_pDockSite->m_listControlBars.GetNext(pos);
if (pDockBar->IsDockBar() && pDockBar->IsWindowVisible() &&
(pDockBar->m_dwStyle & dwDockStyle & CBRS_ALIGN_ANY) &&
(!pDockBar->m_bFloating ||
(dwDockStyle & pDockBar->m_dwStyle & CBRS_FLOAT_MULTI)))
{
int nSize=pDockBar->m_arrBars.GetSize();
for (int i=0;i <nSize; i++)
{
UINT m_nDockBarID = pDockBar->GetDlgCtrlID();
CControlBar* pBar;
pBar = (CControlBar*) pDockBar->m_arrBars[i];
if (HIWORD(pBar) == 0) continue; // placeholder
if (!pBar->IsVisible()) continue;
CRect rectBar;
pBar->GetWindowRect(&rectBar);
if (rectBar.Width() == 0)
rectBar.right++;
if (rectBar.Height() == 0)
rectBar.bottom++;
CRect rectBar1;
pDockBar->GetWindowRect(&rectBar1);
if (dwDockStyle==CBRS_ORIENT_VERT)
{
if (m_nDockBarID==AFX_IDW_DOCKBAR_LEFT)
rectBar1.right=rectBar1.left+20;
if(m_nDockBarID==AFX_IDW_DOCKBAR_RIGHT)
rectBar1.left=rectBar1.right-20;
}
else
{
if (m_nDockBarID==AFX_IDW_DOCKBAR_BOTTOM)
rectBar1.top=rectBar1.bottom-20;
if (m_nDockBarID==AFX_IDW_DOCKBAR_TOP)
rectBar1.bottom=rectBar1.top+20;
}
if (rectBar1.IntersectRect(rectBar1, rect))
{
if (ppDockBar != NULL)
*ppDockBar = pDockBar;
return pDockBar->m_dwStyle & dwDockStyle;
}
//***********************************************
if (rectBar.IntersectRect(rectBar, rect))
{
if (bTipoToolBar)
{
if (pBar->IsKindOf(RUNTIME_CLASS( CGuiControlBar)))
return 0;
}
if (ppDockBar != NULL)
*ppDockBar = pDockBar;
return pDockBar->m_dwStyle & dwDockStyle;
}
}//fin del for
CRect rectBar;
pDockBar->GetWindowRect(&rectBar);
if (rectBar.Width() == 0)
rectBar.right++;
if (rectBar.Height() == 0)
rectBar.bottom++;
if (rectBar.IntersectRect(rectBar, rect))
{
if (ppDockBar != NULL)
*ppDockBar = pDockBar;
return pDockBar->m_dwStyle & dwDockStyle;
}
}
}
return 0;
}
BOOL CGuiDockContext::Track()
{
// don't handle if capture already set
if (::GetCapture() != NULL)
return FALSE;
// set capture to the window which received this message
m_pBar->SetCapture();
ASSERT(m_pBar == CWnd::GetCapture());
// get messages until capture lost or cancelled/accepted
while (CWnd::GetCapture() == m_pBar)
{
MSG msg;
if (!::GetMessage(&msg, NULL, 0, 0))
{
AfxPostQuitMessage(msg.wParam);
break;
}
switch (msg.message)
{
case WM_LBUTTONUP:
if (m_bDragging)
EndDrag();
else
EndResize();
return TRUE;
case WM_MOUSEMOVE:
if (m_bDragging)
Move(msg.pt);
else
Stretch(msg.pt);
break;
case WM_KEYUP:
if (m_bDragging)
OnKey((int)msg.wParam, FALSE);
break;
case WM_KEYDOWN:
if (m_bDragging)
OnKey((int)msg.wParam, TRUE);
if (msg.wParam == VK_ESCAPE)
{
CancelLoop();
return FALSE;
}
break;
case WM_RBUTTONDOWN:
CancelLoop();
return FALSE;
// just dispatch rest of the messages
default:
DispatchMessage(&msg);
break;
}
}
CancelLoop();
return FALSE;
}
CDockBar* CGuiDockContext::GetDockBar(DWORD dwOverDockStyle)
{
DWORD dw = 0;
CDockBar* pBar;
if (HORZF(dwOverDockStyle))
{
dw = CanDock(m_rectDragHorz,
dwOverDockStyle & ~CBRS_ORIENT_VERT, &pBar);
ASSERT(dw != 0);
ASSERT(pBar != NULL);
return pBar;
}
if (VERTF(dwOverDockStyle))
{
dw =CanDock(m_rectDragVert,
dwOverDockStyle & ~CBRS_ORIENT_HORZ, &pBar);
ASSERT(dw != 0);
ASSERT(pBar != NULL);
return pBar;
}
return NULL;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -