📄 dockpagebar.cpp
字号:
//
void CDockPageBar::OnNcLButtonDown(UINT nFlags, CPoint point)
{
UINT nItemIndex=0;
POSITION pos;
CPageItem *pItem;
CRect rect;
//Note: Here the rect coordinate is for NonClient painting,
// so it is referenced to the current window's topleft.
GetWindowRect(&rect);
point.Offset(-rect.TopLeft());
if (HTITEMBUTTON==nFlags){
for(pos=m_PageList.GetHeadPosition();pos!=NULL;nItemIndex++)
{
pItem=(CPageItem*)m_PageList.GetNext(pos);
if(pItem)
{
if(pItem->m_rect.PtInRect(point))
{
SetFocus();
SetActivePage(nItemIndex);
CanDrag(point); // drag PageItem
return;
}
}
}
}
//Note: Here the rect coordinate is referenced to the screen
point.Offset(rect.TopLeft());
if ((nFlags >= HTSIZEFIRST) && (nFlags <= HTSIZELAST))
{
baseCDockPageBar::OnNcLButtonDown(nFlags, point);
return;
}
((CDockPageBarContext*)m_pDockContext)->m_isPage = FALSE;
if (m_pDockBar != NULL&&HTGRIPPER==nFlags)
{
// start the drag
SetFocus();
ASSERT(m_pDockContext != NULL);
m_pDockContext->StartDrag(point);
}
else
CWnd::OnNcLButtonDown(nFlags, point);
}
void CDockPageBar::OnNcLButtonDblClk(UINT nFlags, CPoint point)
{
if (HTGRIPPER==nFlags&&m_pDockBar != NULL)
{
// start the drag
ASSERT(m_pDockContext != NULL);
m_pDockContext->ToggleDocking();
}
else
CWnd::OnNcLButtonDblClk(nFlags, point);
}
void CDockPageBar::EnableDocking(DWORD dwDockStyle)
{
// must be CBRS_ALIGN_XXX or CBRS_FLOAT_MULTI only
ASSERT((dwDockStyle & ~(CBRS_ALIGN_ANY|CBRS_FLOAT_MULTI)) == 0);
// cannot have the CBRS_FLOAT_MULTI style
ASSERT((dwDockStyle & CBRS_FLOAT_MULTI) == 0);
// the bar must have CBRS_SIZE_DYNAMIC style
ASSERT((m_dwStyle & CBRS_SIZE_DYNAMIC) != 0);
m_dwDockStyle = dwDockStyle;
if (m_pDockContext == NULL)
{
m_pDockContext = new CDockPageBarContext(this);
m_pDPBContext.AddTail(m_pDockContext); //hengai
}
// permanently wire the bar's owner to its current parent
if (m_hWndOwner == NULL)
m_hWndOwner = ::GetParent(m_hWnd);
}
void CDockPageBar::CanDrag(CPoint pt)
{
SetCapture();
// get messages until capture lost or cancelled/accepted
while (CWnd::GetCapture() == this)
{
MSG msg;
if (!::GetMessage(&msg, NULL, 0, 0))
{
AfxPostQuitMessage(msg.wParam);
break;
}
switch (msg.message)
{
case WM_LBUTTONUP:
ReleaseCapture();
break;
case WM_MOUSEMOVE:
Move(msg.pt);
break;
default:
DispatchMessage(&msg);
break;
}
}
}
void CDockPageBar::Move(CPoint pt)
{
CRect rect,wndRect;
//Note: Here the rect coordinate is for NonClient painting,
// so it is referenced to the current window's topleft.
GetWindowRect(&wndRect);
GetItemGroupRect(&rect);
rect.OffsetRect(-wndRect.TopLeft());
pt.Offset(-wndRect.TopLeft());
if(rect.PtInRect(pt))
{
int nItemIndex=0;
POSITION pos;
CPageItem *pItem;
for(pos=m_PageList.GetHeadPosition();pos!=NULL;nItemIndex++)
{
pItem=(CPageItem*)m_PageList.GetNext(pos);
if(pItem)
{
if(pItem->m_rect.PtInRect(pt))
{
if(nItemIndex != m_nActivePage)
{
POSITION oldPos = m_PageList.FindIndex(m_nActivePage);
POSITION curPos = m_PageList.FindIndex(nItemIndex);
CPageItem *pOldItem = (CPageItem*)m_PageList.GetAt(oldPos);
// exchange PageItem
m_PageList.SetAt(oldPos, pItem);
m_PageList.SetAt(curPos, pOldItem);
m_nActivePage = nItemIndex;
UpdateWindow();
break;
}
}
}
}
}
else
{
ReleaseCapture();
StartDrag(pt);
}
}
void CDockPageBar::StartDrag(CPoint pt)
{
ClientToScreen(&pt);
((CDockPageBarContext*)m_pDockContext)->m_isPage = TRUE;
m_pDockContext->StartDrag(pt);
((CDockPageBarContext*)m_pDockContext)->m_isPage = FALSE;
}
/////////////////////////////////////////////////////////////////////////////
// CDockPageBarContext
#define _AfxGetDlgCtrlID(hWnd) ((UINT)(WORD)::GetDlgCtrlID(hWnd))
#define CX_BORDER 1
#define CY_BORDER 1
#define CBRS_ALIGN_INSERT_PAGE 0x0001L // drag to another CDockPageBar
#define HORZF(dw) (dw & CBRS_ORIENT_HORZ)
#define VERTF(dw) (dw & CBRS_ORIENT_VERT)
static void AFXAPI _AfxAdjustRectangle(CRect& rect, CPoint pt)
{
int nXOffset = (pt.x < rect.left) ? (pt.x - rect.left) :
(pt.x > rect.right) ? (pt.x - rect.right) : 0;
int nYOffset = (pt.y < rect.top) ? (pt.y - rect.top) :
(pt.y > rect.bottom) ? (pt.y - rect.bottom) : 0;
rect.OffsetRect(nXOffset, nYOffset);
}
void CDockPageBarContext::StartDrag(CPoint pt)
{
ASSERT_VALID(m_pBar);
m_bDragging = TRUE;
InitLoop();
// GetWindowRect returns screen coordinates(not mirrored),
// so if the desktop is mirrored then turn off mirroring
// for the desktop dc so that we get correct focus rect drawn.
// This layout change should be remembered, just in case ...
//if (m_pDC->GetLayout() & LAYOUT_RTL)
if (m_pDC->GetLayout() & LAYOUT_LTR)
m_pDC->SetLayout(LAYOUT_LTR);
if (m_pBar->m_dwStyle & CBRS_SIZE_DYNAMIC)
{
// get true bar size (including borders)
CRect rect;
m_pBar->GetWindowRect(rect);
m_ptLast = pt;
CSize sizeHorz = m_pBar->CalcDynamicLayout(0, LM_HORZ | LM_HORZDOCK);
CSize sizeVert = m_pBar->CalcDynamicLayout(0, LM_VERTDOCK);
CSize sizeFloat = m_pBar->CalcDynamicLayout(0, LM_HORZ | LM_MRUWIDTH);
m_rectDragHorz = CRect(rect.TopLeft(), sizeHorz);
m_rectDragVert = CRect(rect.TopLeft(), sizeVert);
// calculate frame dragging rectangle
m_rectFrameDragHorz = CRect(rect.TopLeft(), sizeFloat);
m_rectFrameDragVert = CRect(rect.TopLeft(), sizeFloat);
CMiniFrameWnd::CalcBorders(&m_rectFrameDragHorz);
CMiniFrameWnd::CalcBorders(&m_rectFrameDragVert);
m_rectFrameDragHorz.InflateRect(-afxData.cxBorder2, -afxData.cyBorder2);
m_rectFrameDragVert.InflateRect(-afxData.cxBorder2, -afxData.cyBorder2);
}
else if (m_pBar->m_dwStyle & CBRS_SIZE_FIXED)
{
// get true bar size (including borders)
CRect rect;
m_pBar->GetWindowRect(rect);
m_ptLast = pt;
CSize sizeHorz = m_pBar->CalcDynamicLayout(-1, LM_HORZ | LM_HORZDOCK);
CSize sizeVert = m_pBar->CalcDynamicLayout(-1, LM_VERTDOCK);
// calculate frame dragging rectangle
m_rectFrameDragHorz = m_rectDragHorz = CRect(rect.TopLeft(), sizeHorz);
m_rectFrameDragVert = m_rectDragVert = CRect(rect.TopLeft(), sizeVert);
CMiniFrameWnd::CalcBorders(&m_rectFrameDragHorz);
CMiniFrameWnd::CalcBorders(&m_rectFrameDragVert);
m_rectFrameDragHorz.InflateRect(-afxData.cxBorder2, -afxData.cyBorder2);
m_rectFrameDragVert.InflateRect(-afxData.cxBorder2, -afxData.cyBorder2);
}
else
{
// get true bar size (including borders)
CRect rect;
m_pBar->GetWindowRect(rect);
m_ptLast = pt;
BOOL bHorz = HORZF(m_dwStyle);
DWORD dwMode = !bHorz ? (LM_HORZ | LM_HORZDOCK) : LM_VERTDOCK;
CSize size = m_pBar->CalcDynamicLayout(-1, dwMode);
// calculate inverted dragging rect
if (bHorz)
{
m_rectDragHorz = rect;
m_rectDragVert = CRect(CPoint(pt.x - rect.Height()/2, rect.top), size);
}
else // vertical orientation
{
m_rectDragVert = rect;
m_rectDragHorz = CRect(CPoint(rect.left, pt.y - rect.Width()/2), size);
}
// calculate frame dragging rectangle
m_rectFrameDragHorz = m_rectDragHorz;
m_rectFrameDragVert = m_rectDragVert;
CMiniFrameWnd::CalcBorders(&m_rectFrameDragHorz);
CMiniFrameWnd::CalcBorders(&m_rectFrameDragVert);
m_rectFrameDragHorz.InflateRect(-afxData.cxBorder2, -afxData.cyBorder2);
m_rectFrameDragVert.InflateRect(-afxData.cxBorder2, -afxData.cyBorder2);
}
// adjust rectangles so that point is inside
_AfxAdjustRectangle(m_rectDragHorz, pt);
_AfxAdjustRectangle(m_rectDragVert, pt);
_AfxAdjustRectangle(m_rectFrameDragHorz, pt);
_AfxAdjustRectangle(m_rectFrameDragVert, pt);
// initialize tracking state and enter tracking loop
m_dwOverDockStyle = CanDock();
Move(pt); // call it here to handle special keys
Track();
}
CDockPageBarContext::~CDockPageBarContext(void)
{
}
//hengai
void CDockPageBarContext::FreeAll()
{
for(POSITION pos = m_pDPBar.GetHeadPosition(); pos;)
{
CDockPageBar* pBar = (CDockPageBar*)m_pDPBar.GetNext(pos);
ASSERT(pBar != NULL);
delete pBar->m_pDockBar; pBar->m_pDockBar = NULL;
delete pBar; pBar = NULL;
}
m_pDPBar.RemoveAll (); // cuick 2004/04/08
}
BOOL CDockPageBarContext::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;
}
CDockPageBar * CDockPageBarContext::TryToGetDockPageBar(POINT pt)
{
CFrameWnd * pFrameWnd=(CFrameWnd *)AfxGetMainWnd();
POSITION pos = pFrameWnd->m_listControlBars.GetHeadPosition();
while (pos != NULL)
{
CControlBar* pBar = (CControlBar*)pFrameWnd->m_listControlBars.GetNext(pos);
ASSERT(pBar != NULL);
if (pBar->IsKindOf(RUNTIME_CLASS(CDockPageBar)))
{
CRect rect;
pBar->GetWindowRect(&rect);
if(rect.PtInRect(pt)&&!pBar->IsFloating())
return (CDockPageBar*)pBar;
}
}
return NULL;
}
//////////////////////////////////////////////////////////////////////
// drag and draw focus rect
void CDockPageBarContext::Move(CPoint pt)
{
CPoint ptOffset = pt - m_ptLast;
if(TRUE == isDockPage(pt))
{
m_dwOverDockStyle = CBRS_ALIGN_INSERT_PAGE;
}
else
{
//MACRO Definition for the adavnced docking
//#define CBRS_ALIGN_INSERT_PAGE 0x0001L
#define DOCK_ALIGN_INSERT_PAGE CBRS_ALIGN_INSERT_PAGE
#define DOCK_IN_FRAME_CLIENT 0x02
#define DOCK_IN_FRAME_BORDER 0x04
#define DOCK_IN_DOCK_PAGE_BAR 0x08
#define HOR_BORDER_DETECT_PIXELS max(CAPTION_HEIGHT+8,ITEMBUTTON_HEIGHT+8)
#define VER_BORDER_DETECT_PIXELS 16
#define BORDER_DETECT_LEFT 0x0100
#define BORDER_DETECT_RIGHT 0x0200
#define BORDER_DETECT_TOP 0x0400
#define BORDER_DETECT_BOTTOM 0x0800
//POINT pt;
//GetCursorPos(&pt);
CWnd *pCurWnd= CWnd::FromHandle(::WindowFromPoint(pt));
CDockPageBar *pDockPageBarWnd;
DWORD borderDetect=0;
CRect mainFrameRect,mainFrameClientRect;
DWORD dwDockStyle=0;
m_bAdvancedDock=FALSE;
m_endDragDockStruct.dwDockStyle=0;
CWnd *pMainFrameWnd=AfxGetMainWnd();
pMainFrameWnd->GetWindowRect(&mainFrameRect);
//Try to find a docking position
if(mainFrameRect.PtInRect(pt))
{
//Get the pure client rect of the frame wnd
GET_MAIN_FRAME_PURE_CLIENT(pMainFrameWnd,mainFrameClientRect);
if((pDockPageBarWnd=TryToGetDockPageBar(pt))!=NULL){
pDockPageBarWnd->GetWindowRect(&m_curRect);
m_endDragDockStruct.dwDockStyle=dwDockStyle=DOCK_IN_DOCK_PAGE_BAR;
m_bAdvancedDock=TRUE;
}else if(mainFrameClientRect.PtInRect(pt)){
m_curRect=mainFrameClientRect;
m_endDragDockStruct.dwDockStyle=dwDockStyle=DOCK_IN_FRAME_CLIENT;
m_bAdvancedDock=TRUE;
}else{ //the bar is move to the non client area (tool bar for example)
CRect rc=mainFrameClientRect;
rc.DeflateRect(-VER_BORDER_DETECT_PIXELS,-HOR_BORDER_DETECT_PIXELS);
if(rc.PtInRect(pt)){
m_curRect=rc;
m_endDragDockStruct.dwDockStyle=dwDockStyle=DOCK_IN_FRAME_BORDER;
m_bAdvancedDock=TRUE;
}else{
const CRuntimeClass * pRunTimeClass=pCurWnd->GetRuntimeClass();
TRACE0("Unprocessed window type:");
TRACE0(pRunTimeClass->m_lpszClassName);
TRACE0("\r\n");
m_bAdvancedDock=FALSE;
}
}
}else{
CRect rc=mainFrameRect;
rc.DeflateRect(-VER_BORDER_DETECT_PIXELS,-HOR_BORDER_DETECT_PIXELS);
if(rc.PtInRect(pt)){
m_curRect=rc;
m_endDragDockStruct.dwDockStyle=dwDockStyle=DOCK_IN_FRAME_BORDER;
m_bAdvancedDock=TRUE;
}else{
const CRuntimeClass * pRunTimeClass=pCurWnd->GetRuntimeClass();
TRACE0("Unprocessed window type:");
TRACE0(pRunTimeClass->m_lpszClassName);
TRACE0("\r\n");
m_bAdvancedDock=FALSE;
}
}
//Check whether the current position can be used for the advanced docking :-)
if(m_bAdvancedDock&&
m_curRect.Width()>VER_BORDER_DETECT_PIXELS*2+1&&
m_curRect.Height()>HOR_BORDER_DETECT_PIXELS*2+1)
{
//Init the current detection border rect
CRect rectLeft(m_curRect.TopLeft(),CSize(VER_BORDER_DETECT_PIXELS,m_curRect.Height())),
rectTop(m_curRect.TopLeft(),CSize(m_curRect.Width(),HOR_BORDER_DETECT_PIXELS));
CRect rectRight=rectLeft,rectBottom=rectTop;
rectRight.OffsetRect(m_curRect.Width()-VER_BORDER_DETECT_PIXELS,0);
rectBottom.OffsetRect(0,m_curRect.Height()-HOR_BORDER_DETECT_PIXELS);
borderDetect|=rectLeft.PtInRect(pt) ? BORDER_DETECT_LEFT:0;
borderDetect|=rectRight.PtInRect(pt) ? BORDER_DETECT_RIGHT:0;
borderDetect|=rectTop.PtInRect(pt) ? BORDER_DETECT_TOP:0;
borderDetect|=rectBottom.PtInRect(pt) ? BORDER_DETECT_BOTTOM:0;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -