DRAGDROP.CPP

/* 
* DRAGDROP.CPP
* Patron Chapter 22
*
* Member functions of the CPages class concerned with drag-drop
* and other object-placement functionality. Moved here to clean
* up CPAGES.CPP somewhat.
*
* Copyright (c)1993-1995 Microsoft Corporation, All Rights Reserved
*
* Kraig Brockschmidt, Microsoft
* Internet : kraigb@microsoft.com
* Compuserve: >INTERNET:kraigb@microsoft.com
*/


#include "patron.h"


/*
* CPages::UTestDroppablePoint
*
* Purpose:
* Returns if the point in pptl is on the paper in the current page
* and alternately if it's within horizontal or vertical inset
* regions.
*
* Parameters:
* pptl PPOINTL containing the point in screen
* coordinates.
*
* Return Value:
* UINT A UDROP_* value.
*/

UINT CPages::UTestDroppablePoint(PPOINTL pptl)
{
POINT pt;
RECT rc, rcT, rcC;
UINT uRet;

POINTFROMPOINTL(pt, *pptl);
ScreenToClient(m_hWnd, &pt);

CalcBoundingRect(&rc, FALSE);

GetClientRect(m_hWnd, &rcC);
IntersectRect(&rcT, &rc, &rcC);

//Check for at least a client area hit.
if (!PtInRect(&rcT, pt))
return UDROP_NONE;

uRet=UDROP_CLIENT;

//Scroll checks happen on client area, not document area
if (PtInRect(&rcC, pt))
{
//Check horizontal inset
if (pt.x <= rcC.left+(int)m_uScrollInset)
uRet |= UDROP_INSETLEFT;
else if (pt.x >= rcC.right-(int)m_uScrollInset)
uRet |= UDROP_INSETRIGHT;

//Check vertical inset
if (pt.y <= rcC.top+(int)m_uScrollInset)
uRet |= UDROP_INSETTOP;
else if (pt.y >= rcC.bottom-(int)m_uScrollInset)
uRet |= UDROP_INSETBOTTOM;
}

return uRet;
}




/*
* CPages::DrawDropTargetRect
*
* Purpose:
* Draws a dotted rectangle on the Pages window to show where
* a drop might occur. This is a toggle function.
*
* Parameters:
* pptl PPOINTL containing the upper-left point
* in screen coordinates.
* pszl LPSIZEL containing the rect extents in device
* units.
*
* Return Value:
* None
*/

void CPages::DrawDropTargetRect(PPOINTL pptl, LPSIZEL pszl)
{
POINT pt;
RECT rc, rcT;
HDC hDC;

if (NULL==pptl && NULL==pszl)
{
/*
* This case is used from WM_PAINT in pagewin.cpp so we can
* control the proper visibility of the drag rectangle when
* we're scrolling. If drag-drop happens between two apps,
* then any ScrollWindow will cause a WM_PAINT after we
* leave DragOver, so that paint would normally overwrite
* the last drawn rectangle. To alleviate that, WM_PAINT
* will remove the last rect by sending us NULLs, paint,
* then reinstate the rectangle.
*/
pptl=&m_ptlRect;
pszl=&m_szlRect;
}
else
{
m_ptlRect.x=pptl->x;
m_ptlRect.y=pptl->y;
m_szlRect.cx=pszl->cx;
m_szlRect.cy=pszl->cy;

//Flag is only affected from IDropTarget, not WM_PAINT calls
m_fDragRectShown=!m_fDragRectShown;
}

POINTFROMPOINTL(pt, *pptl);
ScreenToClient(m_hWnd, &pt);
SetRect(&rc, pt.x, pt.y, pt.x+(int)pszl->cx
, pt.y+(int)pszl->cy);

CalcBoundingRect(&rcT, FALSE);
IntersectRect(&rc, &rc, &rcT);

if (!IsRectEmpty(&rc))
{
hDC=GetDC(m_hWnd);
DrawFocusRect(hDC, &rc);
ReleaseDC(m_hWnd, hDC);
}

return;
}




/*
* CPages::AdjustPosition
*
* Purpose:
* Adjusts a point for the scrolling offset and then converts it
* and a size from device into LOMETRIC units.
*
* Parameters:
* pptl PPOINTL to adjust and convert
* pszl LPSIZEL to convert
*
* Return Value:
* None
*/

void CPages::AdjustPosition(PPOINTL pptl, LPSIZEL pszl)
{
RECT rc;

SetRect(&rc, m_xPos+(int)pptl->x
, m_yPos+(int)pptl->y, (int)pszl->cx, (int)pszl->cy);

RectConvertMappings(&rc, NULL, FALSE);

pptl->x=rc.left;
pptl->y=rc.top;

pszl->cx=rc.right;
pszl->cy=rc.bottom;

return;
}