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, len = vCont.size(); iCont < len; 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; } ClientRectToScreenRect(_dockData.hWnd, &rcCont); if (::PtInRect(&rcCont, pt) == TRUE) { if (rc != NULL) { ClientRectToScreenRect(_dockData.hWnd, rc); rc->right -= rc->left; rc->bottom -= rc->top; } return vCont[iWork]; } } } /* no docking area found */ return NULL; }
//---------------------------------------------- // Process function of dialog // BOOL CALLBACK DockingCont::run_dlgProc(UINT Message, WPARAM wParam, LPARAM lParam) { switch (Message) { case WM_NCACTIVATE: { // Note: lParam to identify the trigger window if ((int)lParam != -1) { ::SendMessage(_hParent, WM_NCACTIVATE, wParam, 0); } break; } case WM_INITDIALOG: { _hContTab = ::GetDlgItem(_hSelf, IDC_TAB_CONT); _hCaption = ::GetDlgItem(_hSelf, IDC_BTN_CAPTION); // intial subclassing of caption ::SetWindowLongPtr(_hCaption, GWLP_USERDATA, (LONG_PTR)this); _hDefaultCaptionProc = reinterpret_cast<WNDPROC>(::SetWindowLongPtr(_hCaption, GWLP_WNDPROC, (LONG_PTR)wndCaptionProc)); // intial subclassing of tab ::SetWindowLongPtr(_hContTab, GWLP_USERDATA, (LONG_PTR)this); _hDefaultTabProc = reinterpret_cast<WNDPROC>(::SetWindowLongPtr(_hContTab, GWLP_WNDPROC, (LONG_PTR)wndTabProc)); // set min tab width ::SendMessage(_hContTab, TCM_SETMINTABWIDTH, 0, (LPARAM)MIN_TABWIDTH); break; } case WM_NCCALCSIZE: case WM_SIZE: { onSize(); break; } case WM_DRAWITEM : { // draw tab or caption if (((DRAWITEMSTRUCT *)lParam)->CtlID == IDC_TAB_CONT) { drawTabItem((DRAWITEMSTRUCT *)lParam); return TRUE; } else { drawCaptionItem((DRAWITEMSTRUCT *)lParam); return TRUE; } break; } case WM_NCLBUTTONDBLCLK : { RECT rcWnd = {0}; RECT rcClient = {0}; POINT pt = {HIWORD(lParam), LOWORD(lParam)}; getWindowRect(rcWnd); getClientRect(rcClient); ClientRectToScreenRect(_hSelf, &rcClient); rcWnd.bottom = rcClient.top; // if in caption if ((rcWnd.top < pt.x) && (rcWnd.bottom > pt.x) && (rcWnd.left < pt.y) && (rcWnd.right > pt.y)) { NotifyParent(DMM_DOCKALL); return TRUE; } break; } case WM_SYSCOMMAND : { switch (wParam & 0xfff0) { case SC_MOVE: NotifyParent(DMM_MOVE); return TRUE; default: break; } return FALSE; } case WM_COMMAND : { switch (LOWORD(wParam)) { case IDCANCEL: doClose(); return TRUE; default : break; } break; } default: break; } return FALSE; }
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, len = vCont.size(); iCont < len; 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}; if (_hTab == NULL) { initTabInformation(); 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); ClientRectToScreenRect(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 (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)) { _tcItem.mask = TCIF_PARAM | (_hTab == _hTabSource ? TCIF_TEXT : 0); ::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; TCHAR str[128]; wsprintf(str, TEXT("Size: %i"), vCont.size()); ::SetWindowText(g_hMainWnd, str); #endif ::UpdateWindow(_hParent); }