//----------------------------------------------------- STDMETHODIMP nsNativeDragTarget::DragOver(DWORD grfKeyState, POINTL ptl, LPDWORD pdwEffect) { if (DRAG_DEBUG) printf("DragOver %d x %d\n", ptl.x, ptl.y); if (!mDragService) { return ResultFromScode(E_FAIL); } // without the AddRef() |this| can get destroyed in an event handler this->AddRef(); // Drag and drop image helper if (mDropTargetHelper) { POINT pt = { ptl.x, ptl.y }; mDropTargetHelper->DragOver(&pt, *pdwEffect); } mDragService->FireDragEventAtSource(NS_DRAGDROP_DRAG); if (!mDragCancelled) { // Now process the native drag state and then dispatch the event ProcessDrag(nsnull, NS_DRAGDROP_OVER, grfKeyState, ptl, pdwEffect); } this->Release(); return S_OK; }
STDMETHODIMP nsNativeDragTarget::DragEnter(LPDATAOBJECT pIDataSource, DWORD grfKeyState, POINTL ptl, DWORD* pdwEffect) { if (DRAG_DEBUG) printf("DragEnter hwnd:%x\n", mHWnd); if (!mDragService) { return ResultFromScode(E_FAIL); } // Drag and drop image helper if (mDropTargetHelper) { POINT pt = { ptl.x, ptl.y }; mDropTargetHelper->DragEnter(mHWnd, pIDataSource, &pt, *pdwEffect); } // save a ref to this, in case the window is destroyed underneath us NS_ASSERTION(!mTookOwnRef, "own ref already taken!"); this->AddRef(); mTookOwnRef = PR_TRUE; // tell the drag service about this drag (it may have come from an // outside app). mDragService->StartDragSession(); // Remember if this operation allows a move. mCanMove = (*pdwEffect) & DROPEFFECT_MOVE; void* tempOutData = nsnull; PRUint32 tempDataLen = 0; nsresult loadResult = nsClipboard::GetNativeDataOffClipboard( pIDataSource, 0, ::RegisterClipboardFormat(CFSTR_PREFERREDDROPEFFECT), nsnull, &tempOutData, &tempDataLen); if (NS_SUCCEEDED(loadResult) && tempOutData) { NS_ASSERTION(tempDataLen == 2, "Expected word size"); WORD preferredEffect = *((WORD*)tempOutData); // Mask effect coming from function call with effect preferred by the source. mMovePreferred = (preferredEffect & DROPEFFECT_MOVE) != 0; } else mMovePreferred = mCanMove; // Set the native data object into drag service // // This cast is ok because in the constructor we created a // the actual implementation we wanted, so we know this is // a nsDragService. It should be a private interface, though. nsDragService * winDragService = static_cast<nsDragService *>(mDragService); winDragService->SetIDataObject(pIDataSource); // Now process the native drag state and then dispatch the event ProcessDrag(pIDataSource, NS_DRAGDROP_ENTER, grfKeyState, ptl, pdwEffect); return S_OK; }
//----------------------------------------------------- STDMETHODIMP nsNativeDragTarget::Drop(LPDATAOBJECT pData, DWORD grfKeyState, POINTL aPT, LPDWORD pdwEffect) { if (!mDragService) { return ResultFromScode(E_FAIL); } // Drag and drop image helper if (mDropTargetHelper) { POINT pt = { aPT.x, aPT.y }; mDropTargetHelper->Drop(pData, &pt, *pdwEffect); } // Set the native data object into the drag service // // This cast is ok because in the constructor we created a // the actual implementation we wanted, so we know this is // a nsDragService (but it should still be a private interface) nsDragService * winDragService = static_cast<nsDragService *>(mDragService); winDragService->SetIDataObject(pData); // Note: Calling ProcessDrag can destroy us; don't touch members after that. nsCOMPtr<nsIDragService> serv = mDragService; // Now process the native drag state and then dispatch the event ProcessDrag(pData, NS_DRAGDROP_DROP, grfKeyState, aPT, pdwEffect); // Let the win drag service know whether this session experienced // a drop event within the application. Drop will not oocur if the // drop landed outside the app. (used in tab tear off, bug 455884) winDragService->SetDroppedLocal(); // tell the drag service we're done with the session // Use GetMessagePos to get the position of the mouse at the last message // seen by the event loop. (Bug 489729) DWORD pos = ::GetMessagePos(); POINT cpos; cpos.x = GET_X_LPARAM(pos); cpos.y = GET_Y_LPARAM(pos); winDragService->SetDragEndPoint(nsIntPoint(cpos.x, cpos.y)); serv->EndDragSession(PR_TRUE); // release the ref that was taken in DragEnter NS_ASSERTION(mTookOwnRef, "want to release own ref, but not taken!"); if (mTookOwnRef) { this->Release(); mTookOwnRef = PR_FALSE; } return S_OK; }
void CTexViewer::OnMouseMove(UINT nFlags, CPoint point) { if (m_bDrag && (MK_LBUTTON & nFlags)) { if (EDITMODE_SELECT == m_eEditMode) { // 화면 스크롤 체크 CRect rcClient; GetClientRect(&rcClient); CPoint ptOffset(0,0); int iBorder = 20; // 화면 가장자리 20 이내있으면 1씩 증감 if (point.x < rcClient.left+iBorder) ptOffset.x = -1; else if (point.x > rcClient.right-iBorder) ptOffset.x = 1; if (point.y < rcClient.top+iBorder) ptOffset.y = -1; else if (point.y > rcClient.bottom-iBorder) ptOffset.y = 1; iBorder = 10; // 10 이내있으면 5씩 증감 if (point.x < rcClient.left+iBorder) ptOffset.x = -5; else if (point.x > rcClient.right-iBorder) ptOffset.x = 5; if (point.y < rcClient.top+iBorder) ptOffset.y = -5; else if (point.y > rcClient.bottom-iBorder) ptOffset.y = 5; iBorder = 5; // 5 이내있으면 20씩 증감 if (point.x < rcClient.left+iBorder) ptOffset.x = -20; else if (point.x > rcClient.right-iBorder) ptOffset.x = 20; if (point.y < rcClient.top+iBorder) ptOffset.y = -20; else if (point.y > rcClient.bottom-iBorder) ptOffset.y = 20; if (CPoint(0,0) != ptOffset) SetLeftTopInImage(m_ptLeftTopInImage+ptOffset); if (DRAGTYPE_SELECT == m_eDragType) { // 선택 영역 갱신 CPoint pt = point; ScreenToImage(&pt); // image 좌표로 변환 m_rcSelectedRect.right = pt.x; m_rcSelectedRect.bottom = pt.y; m_bDeselect = FALSE; // deselect 해제 } else { // 영역 변형일 경우 다음과 같이 처리 ProcessDrag(point); } Invalidate(); } else if (EDITMODE_HAND == m_eEditMode) { CPoint ptDiff = m_ptMouseOld - point; ptDiff.x = (int)(ptDiff.x / m_fScale); ptDiff.y = (int)(ptDiff.y / m_fScale); SetLeftTopInImage(m_ptLeftTopInImage+ptDiff); } } m_ptMouseOld = point; GetParent()->PostMessage(UM_UPDATE_INFO, TRUE, MAKELPARAM((short)point.y,(short)point.x)); CWnd::OnMouseMove(nFlags, point); }
void CTexViewer::OnLButtonUp(UINT nFlags, CPoint point) { if (m_bDrag) { m_bDrag = FALSE; if (EDITMODE_SELECT == m_eEditMode) { if (DRAGTYPE_SELECT == m_eDragType) { if (m_bDeselect) m_rcSelectedRect.SetRect(-1,-1,-1,-1); // deselect else { CPoint pt = point; ScreenToImage(&pt); // image 좌표로 변환 // 사각형의 left,top은 작은 좌표 right, bottom은 큰 좌표로 정리하기 if (m_rcSelectedRect.left > pt.x) { m_rcSelectedRect.right = m_rcSelectedRect.left; m_rcSelectedRect.left = pt.x; } else m_rcSelectedRect.right = pt.x; if (m_rcSelectedRect.top > pt.y) { m_rcSelectedRect.bottom = m_rcSelectedRect.top; m_rcSelectedRect.top = pt.y; } else m_rcSelectedRect.bottom = pt.y; } } else { ProcessDrag(point); } m_eDragType = DRAGTYPE_NONE; if (m_iCurSelectedImage>=0) m_ImageRects[m_iCurSelectedImage] = m_rcSelectedRect; // 만약 ImageType별로 저장한다면 선택된 사각형을 copy해주기 Invalidate(); } else if (EDITMODE_ZOOM == m_eEditMode) { if (m_ptMouseOld == point) { CRect rc; GetClientRect(&rc); CPoint ptPrev = point; ScreenToImage(&ptPrev); // zoom 하기 전의 image좌표 저장 Zoom((GetAsyncKeyState(VK_MENU) & 0xff00) ? FALSE : TRUE); CPoint ptNext = ptPrev; ImageToScreen(&ptNext); // zoom 한 후의 image좌표를 screen좌표로 전환 ptNext.x = int((ptNext.x-rc.CenterPoint().x)/m_fScale); //화면 가운데로 오게끔 설정 ptNext.y = int((ptNext.y-rc.CenterPoint().y)/m_fScale); SetLeftTopInImage( m_ptLeftTopInImage + ptNext); //차이만큼 옮기기 } else { } } else if (EDITMODE_HAND == m_eEditMode) { CPoint ptDiff = m_ptMouseOld - point; ptDiff.x = (int)(ptDiff.x / m_fScale); ptDiff.y = (int)(ptDiff.y / m_fScale); SetLeftTopInImage(m_ptLeftTopInImage+ptDiff); } } m_ptMouseOld = point; ReleaseCapture(); GetParent()->PostMessage(UM_UPDATE_INFO, TRUE, MAKELPARAM((short)point.y,(short)point.x)); CWnd::OnLButtonUp(nFlags, point); }