////////////////// // Handle button-up: drop the data and return to home state (NONE). // BOOL CDragDropMgr::OnButtonUp(const MSG& msg) { if (!IsDragging()) { SetState(NONE); return FALSE; } if (IsTargetWnd(m_ddi.hwndTarget)) { CPoint pt = GETPOINT(msg.lParam); CWnd* pWndSource = CWnd::FromHandle(m_ddi.hwndSource); CWnd* pWndTarget = CWnd::FromHandle(m_ddi.hwndTarget); pWndSource->ClientToScreen(&pt); pWndTarget->ScreenToClient(&pt); m_ddi.pt = pt; SendDragMessage(WM_DD_DRAGDROP); } else { SendDragMessage(WM_DD_DRAGABORT); } SetState(NONE); return TRUE; }
////////////////// // detail: Note that this works for input only // UINT CDragDropMgr::ProcessMessage(const MSG* pMsg, BOOL bAllowNcDrag) { if (!m_pMainWnd) return FALSE; const MSG& msg = *pMsg; if (IsSourceWnd(msg.hwnd)) { if (msg.message == WM_LBUTTONDOWN || (bAllowNcDrag && msg.message == WM_NCLBUTTONDOWN) || msg.message == WM_RBUTTONDOWN || (bAllowNcDrag && msg.message == WM_NCRBUTTONDOWN)) return OnButtonDown(msg); else if (msg.message == WM_MOUSEMOVE) return OnMouseMove(msg); else if (msg.message == WM_LBUTTONUP || msg.message == WM_RBUTTONUP) return OnButtonUp(msg); else if (m_iState && ((msg.message == WM_KEYDOWN && msg.wParam == VK_ESCAPE) || msg.message == WM_CONTEXTMENU || msg.message == WM_KILLFOCUS)) { SendDragMessage(WM_DD_DRAGABORT); SetState(NONE); return TRUE; } } return FALSE; }
void CDragDropMgr::CancelDrag() { if (IsDragging()) { SendDragMessage(WM_DD_DRAGABORT); SetState(NONE); } }
bool TBarView::InvokeItem(const char* signature) { // sent from TeamMenuItem if (Dragging() && AppCanHandleTypes(signature)) { SendDragMessage(signature); // invoking okay to toss memory DragStop(true); return true; } return false; }
////////////////// // Handle button-down message: enter CAPTURED state. // BOOL CDragDropMgr::OnButtonDown(const MSG& msg) { ASSERT (IsSourceWnd(msg.hwnd)); // if we're already dragging then this must be a click with another mouse button // so we just abort if (IsDragging()) { SendDragMessage(WM_DD_DRAGABORT); SetState(NONE); return TRUE; } // convert m_ptOrg to client coords if (msg.message == WM_NCLBUTTONDOWN || msg.message == WM_NCRBUTTONDOWN) { // check we're not on a scrollbar UINT nHitTest = SendMessage(msg.hwnd, WM_NCHITTEST, 0, msg.lParam); if (nHitTest == HTHSCROLL || nHitTest == HTVSCROLL) return FALSE; CPoint pt = GETPOINT(msg.lParam); ::ScreenToClient(msg.hwnd, &pt); // or above or below the client area CRect rClient; ::GetClientRect(msg.hwnd, rClient); if (pt.y < rClient.top || pt.y > rClient.bottom) return FALSE; m_ptOrg = pt; } else m_ptOrg = GETPOINT(msg.lParam); m_hwndTracking = msg.hwnd; SetState(CAPTURED); return FALSE; }
void TBarView::HandleDeskbarMenu(BMessage* messagewithdestination) { if (!Dragging()) return; // in mini-mode if (fVertical && fState != kExpandoState) { // if drop is in the team menu, bail if (fBarMenuBar->CountItems() >= 2) { uint32 buttons; BPoint location; GetMouse(&location, &buttons); if (fBarMenuBar->ItemAt(1)->Frame().Contains(location)) return; } } if (messagewithdestination) { entry_ref ref; if (messagewithdestination->FindRef("refs", &ref) == B_OK) { BEntry entry(&ref, true); if (entry.IsDirectory()) { // if the ref received (should only be 1) is a directory // then add the drag refs to the directory AddRefsToDeskbarMenu(DragMessage(), &ref); } else SendDragMessage(NULL, &ref); } } else { // adds drag refs to top level in deskbar menu AddRefsToDeskbarMenu(DragMessage(), NULL); } // clean up drag message and types list DragStop(true); }
////////////////// // Handle mousemove: enter DRAGGING state. // BOOL CDragDropMgr::OnMouseMove(const MSG& msg) { if (!IsCaptured()) return FALSE; BOOL bLButtonDown = (GetKeyState(VK_LBUTTON) & 0x8000); BOOL bRButtonDown = (GetKeyState(VK_RBUTTON) & 0x8000); // check mouse button is still down if (!bLButtonDown && !bRButtonDown) { SetState(NONE); return FALSE; } CWnd* pWnd = CWnd::FromHandle(m_hwndTracking); CPoint pt = GETPOINT(msg.lParam); if (IsDragging()) { // already dragging: move drag image pWnd->ClientToScreen(&pt); // convert to screen coords // get new target window if any m_ddi.pt = pt; m_pMainWnd->ScreenToClient(&m_ddi.pt); // convert to main window coords HWND hwndTarget = ::ChildWindowFromPoint(*m_pMainWnd, m_ddi.pt); if (hwndTarget) { m_pMainWnd->ClientToScreen(&m_ddi.pt); // back to screen ScreenToClient(hwndTarget, &m_ddi.pt); // then to target client coords } else m_ddi.pt.x = m_ddi.pt.y = -10000; m_ddi.hwndTarget = hwndTarget; // m_ddi.pt is current pos in client coords of current target window SendDragMessage(WM_DD_PREDRAGMOVE); // now move drag image m_pDragImage->DragMove(pt); // update ui UINT nDropEffect = SendDragMessage(WM_DD_DRAGOVER); // set the cursor if (!(m_ddi.hwndTarget && IsTargetWnd(m_ddi.hwndTarget))) nDropEffect = DROPEFFECT_NONE; HCURSOR hCur = NULL; if (!m_hInstOle32) m_hInstOle32 = LoadLibrary(_T("Ole32.dll")); switch (nDropEffect) { case DD_DROPEFFECT_COPY: hCur = LoadCursor(m_hInstOle32, MAKEINTRESOURCE(3)); break; case DD_DROPEFFECT_MOVE: hCur = LoadCursor(m_hInstOle32, MAKEINTRESOURCE(2)); break; case DD_DROPEFFECT_LINK: hCur = LoadCursor(m_hInstOle32, MAKEINTRESOURCE(4)); break; case DD_DROPEFFECT_NONE: default: hCur = LoadCursor(m_hInstOle32, MAKEINTRESOURCE(1)); break; } if (hCur) SetCursor(hCur); } else // if (IsCaptured()) { // Not dragging yet: enter drag mode if mouse moves beyond threshhold. CPoint delta = pt - m_ptOrg; static CPoint jog(GetSystemMetrics(SM_CXDRAG), GetSystemMetrics(SM_CYDRAG)); if (abs(delta.x) > jog.x || abs(delta.y) > jog.y) { m_ddi.hwndSource = m_hwndTracking; m_ddi.pt = m_ptOrg; // start from ORIGINAL point, not where now m_ddi.hwndTarget = m_hwndTracking; m_ddi.pData = NULL; m_ddi.bLeftDrag = bLButtonDown; // Send main window a message: enter drag mode. BOOL bDrag = SendDragMessage(WM_DD_DRAGENTER); if (bDrag && m_ddi.pData) { SetState(bLButtonDown ? LDRAGGING : RDRAGGING); // I am now dragging OnMouseMove(msg); CRect rc; m_pDragImage = m_ddi.pData->CreateDragImage(pWnd, rc); m_pDragImage->BeginDrag(0, rc.BottomRight()); pWnd->ClientToScreen(&pt); m_pDragImage->DragEnter(NULL, pt); } else SetState(NONE); } } return TRUE; }