📄 gripper.cpp
字号:
else if (_pCont != pDockCont)
{
/* change location of toolbars */
if ((_startMovingFromTab == TRUE) && (::SendMessage(_hTabSource, TCM_GETITEMCOUNT, 0, 0) != 1))
{
/* when tab is moved */
_pDockMgr->toggleActiveTb(_pCont, pDockCont);
}
else
{
/* when all windows are moved */
_pDockMgr->toggleVisTb(_pCont, pDockCont);
}
}
}
void Gripper::doTabReordering(POINT pt)
{
vector<DockingCont*> vCont = _pDockMgr->getContainerInfo();
BOOL inTab = FALSE;
HWND hTab = NULL;
HWND hTabOld = _hTab;
int iItem = -1;
int iItemOld = _iItem;
/* search for every tab entry */
for (size_t iCont = 0; iCont < vCont.size(); iCont++)
{
hTab = vCont[iCont]->getTabWnd();
/* search only if container is visible */
if (::IsWindowVisible(hTab) == TRUE)
{
RECT rc = {0};
::GetWindowRect(hTab, &rc);
/* test if cursor points in tab window */
if (::PtInRect(&rc, pt) == TRUE)
{
TCHITTESTINFO info = {0};
TCITEM tcItem = {0};
if (_hTab == NULL)
{
initTabInformation(pt);
hTabOld = _hTab;
iItemOld = _iItem;
}
/* get pointed tab item */
info.pt = pt;
::ScreenToClient(hTab, &info.pt);
iItem = ::SendMessage(hTab, TCM_HITTEST, 0, (LPARAM)&info);
if (iItem != -1)
{
/* prevent flickering of tabs with different sizes */
::SendMessage(hTab, TCM_GETITEMRECT, iItem, (LPARAM)&rc);
ClientToScreen(hTab, &rc);
if ((rc.left + (_rcItem.right - _rcItem.left)) < pt.x)
{
return;
}
_iItem = iItem;
}
else if ((hTab != _hTab) || (_iItem == -1))
{
/* test if cusor points after last tab */
int iLastItem = ::SendMessage(hTab, TCM_GETITEMCOUNT, 0, 0) - 1;
::SendMessage(hTab, TCM_GETITEMRECT, iLastItem, (LPARAM)&rc);
if ((rc.left + rc.right) < pt.x)
{
_iItem = iLastItem + 1;
}
}
_hTab = hTab;
inTab = TRUE;
break;
}
}
}
/* set and remove tabs correct */
if ((inTab == TRUE) && (iItemOld != _iItem))
{
if (_hTab == _hTabSource)
{
/* delete item if switching back to source tab */
int iSel = ::SendMessage(_hTab, TCM_GETCURSEL, 0, 0);
::SendMessage(_hTab, TCM_DELETEITEM, iSel, 0);
}
else if (_hTab == hTabOld)
{
/* delete item on switch between tabs */
::SendMessage(_hTab, TCM_DELETEITEM, iItemOld, 0);
}
else
{
if (_hTab == hTabOld)
{
/* delete item on switch between tabs */
::SendMessage(_hTab, TCM_DELETEITEM, iItemOld, 0);
}
}
}
else if (inTab == FALSE)
{
if (hTabOld != _hTabSource)
{
::SendMessage(hTabOld, TCM_DELETEITEM, iItemOld, 0);
}
_iItem = -1;
}
/* insert new entry when mouse doesn't point to current hovered tab */
if ((_hTab != hTabOld) || (_iItem != iItemOld))
{
::SendMessage(_hTab, TCM_INSERTITEM, _iItem, (LPARAM)&_tcItem);
}
/* select the tab only in source tab window */
if ((_hTab == _hTabSource) && (_iItem != -1))
{
::SendMessage(_hTab, TCM_SETCURSEL, _iItem, 0);
}
#if 0
extern HWND g_hMainWnd;
char str[128];
sprintf(str, "Size: %i", vCont.size());
::SetWindowText(g_hMainWnd, str);
#endif
::UpdateWindow(_hParent);
}
void Gripper::drawRectangle(POINT pt)
{
HANDLE hbrushOrig = NULL;
RECT rc = {0};
//BOOL isRcTab = FALSE;
//RECT rcTab = {0};
if (!_hdc)
_hdc = ::GetDC(NULL);
// Create a brush with the appropriate bitmap pattern to draw our drag rectangle
if (!_hbm)
_hbm = ::CreateBitmap(8, 8, 1, 1, DotPattern);
if (!_hbrush)
_hbrush = ::CreatePatternBrush(_hbm);
// Determine whether to draw a solid drag rectangle or checkered
getMovingRect(pt, &rc);
::SetBrushOrgEx(_hdc, rc.left, rc.top, 0);
hbrushOrig = ::SelectObject(_hdc, _hbrush);
// line: left
::PatBlt(_hdc, rc.left, rc.top, 3, rc.bottom - 3, PATINVERT);
// line: top
::PatBlt(_hdc, rc.left + 3, rc.top, rc.right - 3, 3, PATINVERT);
// line: right
::PatBlt(_hdc, rc.left + rc.right - 3, rc.top + 3, 3, rc.bottom - 3, PATINVERT);
// line: bottom
::PatBlt(_hdc, rc.left, rc.top + rc.bottom - 3, rc.right - 3, 3, PATINVERT);
// destroy resources
::SelectObject(_hdc, hbrushOrig);
}
void Gripper::getMousePoints(POINT* pt, POINT* ptPrev)
{
*ptPrev = _ptOld;
_ptOld = *pt;
}
void Gripper::getMovingRect(POINT pt, RECT *rc)
{
RECT rcCorr = {0};
DockingCont* pContHit = NULL;
/* test if mouse hits a container */
pContHit = contHitTest(pt);
if (pContHit != NULL)
{
/* get rect of client */
::GetWindowRect(pContHit->getHSelf(), rc);
/* get rect for correction */
if (_pCont->isFloating() == TRUE)
rcCorr = _pCont->getDataOfActiveTb()->rcFloat;
else
_pCont->getClientRect(rcCorr);
ShrinkRcToSize(rc);
ShrinkRcToSize(&rcCorr);
/* correct rectangle position when mouse is not within */
DoCalcGripperRect(rc, rcCorr, pt);
}
else
{
/* test if mouse is within work area */
pContHit = workHitTest(pt, rc);
/* calcutlates the rect and its position */
if (pContHit == NULL)
{
/* calcutlates the rect and draws it */
if (!_pCont->isFloating())
*rc = _pCont->getDataOfActiveTb()->rcFloat;
else
_pCont->getWindowRect(*rc);
_pCont->getClientRect(rcCorr);
CalcRectToScreen(_dockData.hWnd, rc);
CalcRectToScreen(_dockData.hWnd, &rcCorr);
rc->left = pt.x - _ptOffset.x;
rc->top = pt.y - _ptOffset.y;
/* correct rectangle position when mouse is not within */
DoCalcGripperRect(rc, rcCorr, pt);
}
}
}
DockingCont* Gripper::contHitTest(POINT pt)
{
vector<DockingCont*> vCont = _pDockMgr->getContainerInfo();
HWND hWnd = ::WindowFromPoint(pt);
for (UINT iCont = 0; iCont < vCont.size(); iCont++)
{
/* test if within caption */
if (hWnd == vCont[iCont]->getCaptionWnd())
{
if (vCont[iCont]->isFloating())
{
RECT rc = {0};
vCont[iCont]->getWindowRect(rc);
if ((rc.top < pt.y) && (pt.y < (rc.top + 24)))
{
/* when it is the same container start moving immediately */
if (vCont[iCont] == _pCont)
{
return NULL;
}
else
{
return vCont[iCont];
}
}
}
else
{
return vCont[iCont];
}
}
/* test only tabs that are visible */
if (::IsWindowVisible(vCont[iCont]->getTabWnd()) == TRUE)
{
/* test if within tab (rect test is used, because of drag and drop behaviour) */
RECT rc = {0};
::GetWindowRect(vCont[iCont]->getTabWnd(), &rc);
if (::PtInRect(&rc, pt) == TRUE)
{
return vCont[iCont];
}
}
}
/* doesn't hit a container */
return NULL;
}
DockingCont* Gripper::workHitTest(POINT pt, RECT *rc)
{
RECT rcCont = {0};
vector<DockingCont*> vCont = _pDockMgr->getContainerInfo();
/* at first test if cursor points into a visible container */
for (size_t iCont = 0; iCont < vCont.size(); iCont++)
{
if (vCont[iCont]->isVisible())
{
vCont[iCont]->getWindowRect(rcCont);
if (::PtInRect(&rcCont, pt) == TRUE)
{
/* when it does, return with non found docking area */
return NULL;
}
}
}
/* now search if cusor hits a possible docking area */
for (int iWork = 0; iWork < DOCKCONT_MAX; iWork++)
{
if (!vCont[iWork]->isVisible())
{
rcCont = _dockData.rcRegion[iWork];
rcCont.right += rcCont.left;
rcCont.bottom += rcCont.top;
if (rc != NULL)
{
*rc = rcCont;
}
/* set fix hit test with */
switch(iWork)
{
case CONT_LEFT:
rcCont.right = rcCont.left + HIT_TEST_THICKNESS;
rcCont.left -= HIT_TEST_THICKNESS;
break;
case CONT_RIGHT:
rcCont.left = rcCont.right - HIT_TEST_THICKNESS;
rcCont.right += HIT_TEST_THICKNESS;
break;
case CONT_TOP:
rcCont.bottom = rcCont.top + HIT_TEST_THICKNESS;
rcCont.top -= HIT_TEST_THICKNESS;
break;
case CONT_BOTTOM:
rcCont.top = rcCont.bottom - HIT_TEST_THICKNESS;
rcCont.bottom += HIT_TEST_THICKNESS;
break;
default:
break;
}
ClientToScreen(_dockData.hWnd, &rcCont);
if (::PtInRect(&rcCont, pt) == TRUE)
{
if (rc != NULL)
{
ClientToScreen(_dockData.hWnd, rc);
rc->right -= rc->left;
rc->bottom -= rc->top;
}
return vCont[iWork];
}
}
}
/* no docking area found */
return NULL;
}
void Gripper::initTabInformation(POINT pt)
{
/* for tab reordering */
/* remember handle */
_hTabSource = _pCont->getTabWnd();
_startMovingFromTab = _pCont->startMovingFromTab();
if ((_startMovingFromTab == FALSE) && (::SendMessage(_hTabSource, TCM_GETITEMCOUNT, 0, 0) == 1))
{
_startMovingFromTab = TRUE;
_iItem = 0;
}
else
{
/* get active tab item */
_iItem = ::SendMessage(_hTabSource, TCM_GETCURSEL, 0, 0);
}
/* get size of item */
_hTab = _hTabSource;
::SendMessage(_hTabSource, TCM_GETITEMRECT, _iItem, (LPARAM)&_rcItem);
/* store item data */
static char szText[64];
_tcItem.mask = TCIF_PARAM | TCIF_TEXT;
_tcItem.pszText = szText;
_tcItem.cchTextMax = 64;
::SendMessage(_hTabSource, TCM_GETITEM, _iItem, (LPARAM)&_tcItem);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -