summaryrefslogtreecommitdiffstats
path: root/private/oleutest/simpdnd/idt.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'private/oleutest/simpdnd/idt.cpp')
-rw-r--r--private/oleutest/simpdnd/idt.cpp851
1 files changed, 851 insertions, 0 deletions
diff --git a/private/oleutest/simpdnd/idt.cpp b/private/oleutest/simpdnd/idt.cpp
new file mode 100644
index 000000000..db83df09a
--- /dev/null
+++ b/private/oleutest/simpdnd/idt.cpp
@@ -0,0 +1,851 @@
+//**********************************************************************
+// File name: IDT.CPP
+//
+// Implementation file for CDropTarget
+//
+// Functions:
+//
+// See IDT.H for class definition
+//
+// Copyright (c) 1992 - 1993 Microsoft Corporation. All rights reserved.
+//**********************************************************************
+
+#include "pre.h"
+#include "iocs.h"
+#include "ias.h"
+#include "app.h"
+#include "site.h"
+#include "doc.h"
+#include "idt.h"
+
+extern CLIPFORMAT g_cfObjectDescriptor;
+
+
+//**********************************************************************
+//
+// CDropTarget::QueryDrop
+//
+// Purpose:
+//
+// Check if the desired drop operation (identified by the given key
+// state) is possible at the current mouse position (pointl).
+//
+// Parameters:
+//
+// DWORD grfKeyState - current key state
+// POINTL pointl - position of mouse
+// BOOL fDragScroll - TRUE if drag scrolling cursor should
+// be shown.
+// LPDWORD pdwEffect - (OUT) drag effect that should occur
+//
+// Return Value:
+//
+// BOOL - TRUE if drop could take place,
+// else FALSE
+//
+// Function Calls:
+// Function Location
+//
+// OleStdGetDropEffect OLE2UI API
+//
+//
+//********************************************************************
+
+BOOL CDropTarget::QueryDrop (
+ DWORD grfKeyState,
+ POINTL pointl,
+ BOOL fDragScroll,
+ LPDWORD pdwEffect
+)
+{
+ DWORD dwScrollEffect = 0L;
+ DWORD dwOKEffects = m_pDoc->m_lpApp->m_dwTargetEffect & *pdwEffect;
+
+ /* check if the cursor is in the active scroll area, if so need the
+ ** special scroll cursor.
+ */
+ if (fDragScroll)
+ dwScrollEffect = DROPEFFECT_SCROLL;
+
+ /* if we have already determined that the source does NOT have any
+ ** acceptable data for us, the return NO-DROP
+ */
+ if (! m_fCanDropCopy && ! m_fCanDropLink)
+ goto dropeffect_none;
+
+ /* OLE2NOTE: determine what type of drop should be performed given
+ ** the current modifier key state. we rely on the standard
+ ** interpretation of the modifier keys:
+ ** no modifier -- DROPEFFECT_MOVE or whatever is allowed by src
+ ** SHIFT -- DROPEFFECT_MOVE
+ ** CTRL -- DROPEFFECT_COPY
+ ** CTRL-SHIFT -- DROPEFFECT_LINK
+ */
+
+ *pdwEffect = OleStdGetDropEffect(grfKeyState);
+ if (*pdwEffect == 0)
+ {
+ // No modifier keys given. Try in order MOVE, COPY, LINK.
+ if ((DROPEFFECT_MOVE & dwOKEffects) && m_fCanDropCopy)
+ *pdwEffect = DROPEFFECT_MOVE;
+ else if ((DROPEFFECT_COPY & dwOKEffects) && m_fCanDropCopy)
+ *pdwEffect = DROPEFFECT_COPY;
+ else if ((DROPEFFECT_LINK & dwOKEffects) && m_fCanDropLink)
+ *pdwEffect = DROPEFFECT_LINK;
+ else
+ goto dropeffect_none;
+ }
+ else
+ {
+ /* OLE2NOTE: we should check if the drag source application allows
+ ** the desired drop effect.
+ */
+ if (!(*pdwEffect & dwOKEffects))
+ goto dropeffect_none;
+
+ if ((*pdwEffect == DROPEFFECT_COPY || *pdwEffect == DROPEFFECT_MOVE)
+ && ! m_fCanDropCopy)
+ goto dropeffect_none;
+
+ if (*pdwEffect == DROPEFFECT_LINK && ! m_fCanDropLink)
+ goto dropeffect_none;
+ }
+
+ *pdwEffect |= dwScrollEffect;
+ return TRUE;
+
+dropeffect_none:
+
+ *pdwEffect = DROPEFFECT_NONE;
+ return FALSE;
+}
+
+
+//**********************************************************************
+//
+// CDropTarget::QueryDrop
+//
+// Purpose:
+//
+// Check to see if Drag scroll operation should be initiated.
+//
+// Parameters:
+//
+// POINTL pointl - position of mouse
+//
+// Return Value:
+//
+// BOOL - TRUE if scroll cursor should be given
+// else FALSE
+//
+// Function Calls:
+// Function Location
+//
+// ScreenToClient WINDOWS API
+// GetClientRect WINDOWS API
+//
+// Comments:
+// A Drag scroll operation should be initiated when the mouse has
+// remained in the active scroll area (11 pixels frame around border
+// of window) for a specified amount of time (50ms).
+//
+//********************************************************************
+
+BOOL CDropTarget::DoDragScroll (POINTL pointl)
+{
+ DWORD dwScrollDir = SCROLLDIR_NULL;
+ DWORD dwTime = GetCurrentTime();
+ int nScrollInset = m_pDoc->m_lpApp->m_nScrollInset;
+ int nScrollDelay = m_pDoc->m_lpApp->m_nScrollDelay;
+ int nScrollInterval = m_pDoc->m_lpApp->m_nScrollInterval;
+ POINT point;
+ RECT rect;
+
+ point.x = (int)pointl.x;
+ point.y = (int)pointl.y;
+
+ ScreenToClient( m_pDoc->m_hDocWnd, &point);
+ GetClientRect ( m_pDoc->m_hDocWnd, (LPRECT) &rect );
+
+ if (rect.top <= point.y && point.y<=(rect.top+nScrollInset))
+ dwScrollDir = SCROLLDIR_UP;
+ else if ((rect.bottom-nScrollInset) <= point.y && point.y <= rect.bottom)
+ dwScrollDir = SCROLLDIR_DOWN;
+ else if (rect.left <= point.x && point.x <= (rect.left+nScrollInset))
+ dwScrollDir = SCROLLDIR_LEFT;
+ else if ((rect.right-nScrollInset) <= point.x && point.x <= rect.right)
+ dwScrollDir = SCROLLDIR_RIGHT;
+
+ if (m_dwTimeEnterScrollArea)
+ {
+ /* cursor was already in Scroll Area */
+
+ if (! dwScrollDir)
+ {
+ /* cusor moved OUT of scroll area.
+ ** clear "EnterScrollArea" time.
+ */
+ m_dwTimeEnterScrollArea = 0L;
+ m_dwNextScrollTime = 0L;
+ m_dwLastScrollDir = SCROLLDIR_NULL;
+
+ }
+ else
+ if (dwScrollDir != m_dwLastScrollDir)
+ {
+ /* cusor moved into a different direction scroll area.
+ ** reset "EnterScrollArea" time to start a new 50ms delay.
+ */
+ m_dwTimeEnterScrollArea = dwTime;
+ m_dwNextScrollTime = dwTime + (DWORD)nScrollDelay;
+ m_dwLastScrollDir = dwScrollDir;
+
+ }
+ else
+ if (dwTime && dwTime >= m_dwNextScrollTime)
+ {
+ m_pDoc->Scroll ( dwScrollDir ); // Scroll document now
+ m_dwNextScrollTime = dwTime + (DWORD)nScrollInterval;
+ }
+ }
+ else
+ {
+ if (dwScrollDir)
+ {
+ /* cusor moved INTO a scroll area.
+ ** reset "EnterScrollArea" time to start a new 50ms delay.
+ */
+ m_dwTimeEnterScrollArea = dwTime;
+ m_dwNextScrollTime = dwTime + (DWORD)nScrollDelay;
+ m_dwLastScrollDir = dwScrollDir;
+ }
+ }
+
+ return (dwScrollDir ? TRUE : FALSE);
+}
+
+
+// Support functions/macros
+#define SetTopLeft(rc, pt) \
+ ((rc)->top = (pt)->y,(rc)->left = (pt)->x)
+#define SetBottomRight(rc, pt) \
+ ((rc)->bottom = (pt)->y,(rc)->right = (pt)->x)
+#define OffsetPoint(pt, dx, dy) \
+ ((pt)->x += dx, (pt)->y += dy)
+
+
+/* HighlightRect
+** -------------
+** Invert rectangle on screen. used for drop target feedback.
+*/
+
+static int HighlightRect(HWND hwnd, HDC hdc, LPRECT rc)
+{
+ POINT pt1, pt2;
+ int old = SetROP2(hdc, R2_NOT);
+ HPEN hpen;
+ HGDIOBJ hold;
+
+ pt1.x = rc->left;
+ pt1.y = rc->top;
+ pt2.x = rc->right;
+ pt2.y = rc->bottom;
+
+ ScreenToClient(hwnd, &pt1);
+ ScreenToClient(hwnd, &pt2);
+
+ hold = SelectObject(hdc, GetStockObject(HOLLOW_BRUSH));
+ hpen = (HPEN) SelectObject(hdc, CreatePen(PS_SOLID, 2,
+ GetSysColor(COLOR_ACTIVEBORDER)));
+
+ Rectangle(hdc, pt1.x, pt1.y, pt2.x, pt2.y);
+
+ SetROP2(hdc, old);
+
+ hold = SelectObject(hdc, hold);
+ hpen = (HPEN) SelectObject(hdc, hpen);
+
+ DeleteObject(hpen);
+
+ return 0;
+}
+
+
+//**********************************************************************
+//
+// CDropTarget::InitDragFeedback
+//
+// Purpose:
+//
+// Initialize data used to draw drop target feedback.
+// As feedback we draw a rectangle the size of the object.
+//
+// Parameters:
+//
+// LPDATAOBJECT pDataObj - IDataObject from Drop source
+// POINTL pointl - position of mouse
+//
+// Return Value:
+//
+// none.
+//
+// Function Calls:
+// Function Location
+//
+// IDataObject::GetData Object
+// XformSizeInHimetricToPixels OLE2UI Library
+// GlobalLock WINDOWS API
+// GlobalUnlock WINDOWS API
+// ReleaseStgMedium OLE2 API
+// OffsetPoint IDT.CPP
+// SetTopLeft IDT.CPP
+// SetBottomRight IDT.CPP
+//
+// Comments:
+// In order to know the size of the object before the object
+// is actually dropped, we render CF_OBJECTDESCRIPTOR format.
+// this data format tells us both the size of the object as
+// well as which aspect is the object is displayed as in the
+// source. If the object is currently displayed as DVASPECT_ICON
+// then we want to create the object also as DVASPECT_ICON.
+//
+//********************************************************************
+
+void CDropTarget::InitDragFeedback(LPDATAOBJECT pDataObj, POINTL pointl)
+{
+ FORMATETC fmtetc;
+ STGMEDIUM stgmed;
+ POINT pt;
+ int height, width;
+ HRESULT hrErr;
+
+ height = width = 100; // some default values
+ pt.x = (int)pointl.x;
+ pt.y = (int)pointl.y;
+
+ // do a GetData for CF_OBJECTDESCRIPTOR format to get the size of the
+ // object as displayed in the source. using this size, initialize the
+ // size for the drag feedback rectangle.
+ fmtetc.cfFormat = g_cfObjectDescriptor;
+ fmtetc.ptd = NULL;
+ fmtetc.lindex = -1;
+ fmtetc.dwAspect = DVASPECT_CONTENT;
+ fmtetc.tymed = TYMED_HGLOBAL;
+
+ hrErr = pDataObj->GetData(&fmtetc, &stgmed);
+ if (hrErr == NOERROR)
+ {
+ LPOBJECTDESCRIPTOR pOD=(LPOBJECTDESCRIPTOR)GlobalLock(stgmed.hGlobal);
+ if (pOD != NULL)
+ {
+ XformSizeInHimetricToPixels(NULL, &pOD->sizel, &pOD->sizel);
+
+ width = (int)pOD->sizel.cx;
+ height = (int)pOD->sizel.cy;
+ m_dwSrcAspect = pOD->dwDrawAspect;
+ }
+
+ GlobalUnlock(stgmed.hGlobal);
+ ReleaseStgMedium(&stgmed);
+ }
+
+ m_ptLast = pt;
+ m_fDragFeedbackDrawn = FALSE;
+
+ OffsetPoint(&pt, -(width/2), -(height/2));
+ SetTopLeft(&m_rcDragRect, &pt);
+
+ OffsetPoint(&pt, width, height);
+ SetBottomRight(&m_rcDragRect, &pt);
+}
+
+
+//**********************************************************************
+//
+// CDropTarget::UndrawDragFeedback
+//
+// Purpose:
+//
+// Erase any drop target feedback.
+// As feedback we draw a rectangle the size of the object.
+//
+// Parameters:
+//
+// none.
+//
+// Return Value:
+//
+// none.
+//
+// Function Calls:
+// Function Location
+//
+// GetDC WINDOWS API
+// ReleaseDC WINDOWS API
+// HighlightRect IDT.CPP
+//
+// Comments:
+// In order to know the size of the object before the object
+// is actually dropped, we render CF_OBJECTDESCRIPTOR format.
+// this data format tells us both the size of the object as
+// well as which aspect is the object is displayed as in the
+// source. if the object is currently displayed as DVASPECT_ICON
+// then we want to create the object also as DVASPECT_ICON.
+//
+//********************************************************************
+
+void CDropTarget::UndrawDragFeedback( void )
+{
+ if (m_fDragFeedbackDrawn)
+ {
+ m_fDragFeedbackDrawn = FALSE;
+ HDC hDC = GetDC(m_pDoc->m_hDocWnd);
+ HighlightRect(m_pDoc->m_hDocWnd, hDC, &m_rcDragRect);
+ ReleaseDC(m_pDoc->m_hDocWnd, hDC);
+ }
+}
+
+
+//**********************************************************************
+//
+// CDropTarget::DrawDragFeedback
+//
+// Purpose:
+//
+// Compute new position of drop target feedback rectangle and
+// erase old rectangle and draw new rectangle.
+// As feedback we draw a rectangle the size of the object.
+//
+// Parameters:
+//
+// POINTL pointl - position of mouse
+//
+// Return Value:
+//
+// none.
+//
+// Function Calls:
+// Function Location
+//
+// OffsetPoint IDT.CPP
+// OffsetRect IDT.CPP
+// HighlightRect IDT.CPP
+// GetDC WINDOWS API
+// ReleaseDC WINDOWS API
+//
+//
+//********************************************************************
+
+void CDropTarget::DrawDragFeedback( POINTL pointl )
+{
+ POINT ptDiff;
+
+ ptDiff.x = (int)pointl.x - m_ptLast.x;
+ ptDiff.y = (int)pointl.y - m_ptLast.y;
+
+ if (m_fDragFeedbackDrawn && (ptDiff.x == 0 && ptDiff.y == 0))
+ return; // mouse did not move; leave rectangle as drawn
+
+ HDC hDC = GetDC(m_pDoc->m_hDocWnd);
+ if (m_fDragFeedbackDrawn)
+ {
+ m_fDragFeedbackDrawn = FALSE;
+ HighlightRect(m_pDoc->m_hDocWnd, hDC, &m_rcDragRect);
+ }
+
+ OffsetRect(&m_rcDragRect, ptDiff.x, ptDiff.y);
+ HighlightRect(m_pDoc->m_hDocWnd, hDC, &m_rcDragRect);
+ m_fDragFeedbackDrawn = TRUE;
+ m_ptLast.x = (int)pointl.x;
+ m_ptLast.y = (int)pointl.y;
+ ReleaseDC(m_pDoc->m_hDocWnd, hDC);
+}
+
+
+//**********************************************************************
+//
+// CDropTarget::QueryInterface
+//
+// Purpose:
+//
+// Used for interface negotiation
+//
+// Parameters:
+//
+// REFIID riid - ID of interface to be returned
+// LPVOID FAR* ppvObj - Location to return the interface
+//
+// Return Value:
+//
+// S_OK - Interface supported
+// E_NOINTERFACE - Interface NOT supported
+//
+// Function Calls:
+// Function Location
+//
+// TestDebugOut Windows API
+// CSimpleDoc::QueryInterface DOC.CPP
+//
+//
+//********************************************************************
+
+STDMETHODIMP CDropTarget::QueryInterface(REFIID riid, LPVOID FAR* ppvObj)
+{
+ TestDebugOut("In IDT::QueryInterface\r\n");
+
+ // delegate to the document
+ return m_pDoc->QueryInterface(riid, ppvObj);
+}
+
+
+//**********************************************************************
+//
+// CDropTarget::AddRef
+//
+// Purpose:
+//
+// Increments the reference count of CSimpleDoc. Since CDropTarget is
+// a nested class of CSimpleDoc, we don't need a separate reference
+// count for CDropTarget. We can safely use the reference count of
+// CSimpleDoc.
+//
+// Parameters:
+//
+// None
+//
+// Return Value:
+//
+// The new reference count of CSimpleDoc
+//
+// Function Calls:
+// Function Location
+//
+// CSimpleDoc::AddReff DOC.CPP
+// TestDebugOut Windows API
+//
+//
+//********************************************************************
+
+STDMETHODIMP_(ULONG) CDropTarget::AddRef()
+{
+ TestDebugOut("In IDT::AddRef\r\n");
+
+ // delegate to the document Object
+ return m_pDoc->AddRef();
+}
+
+//**********************************************************************
+//
+// CDropTarget::Release
+//
+// Purpose:
+//
+// Decrements the reference count of CSimpleDoc. Since CDropTarget is
+// a nested class of CSimpleDoc, we don't need a separate reference
+// count for CDropTarget. We can safely use the reference count of
+// CSimpleDoc.
+//
+// Parameters:
+//
+// None
+//
+// Return Value:
+//
+// The new reference count of CSimpleDoc
+//
+// Function Calls:
+// Function Location
+//
+// CSimpleDoc::Release DOC.CPP
+// TestDebugOut Windows API
+//
+//
+//********************************************************************
+
+STDMETHODIMP_(ULONG) CDropTarget::Release()
+{
+ TestDebugOut("In IDT::Release\r\n");
+
+ // delegate to the document object
+ return m_pDoc->Release();
+}
+
+
+//**********************************************************************
+//
+// CDropTarget::DragEnter
+//
+// Purpose:
+//
+// Called when the mouse first enters our DropTarget window
+//
+// Parameters:
+//
+// LPDATAOBJECT pDataObj - IDataObject from Drop source
+// DWORD grfKeyState - current key state
+// POINTL pointl - position of mouse
+// LPDWORD pdwEffect - (IN-OUT) drag effect that should occur
+// ON INPUT, this is dwOKEffects that source
+// passed to DoDragDrop API.
+// ON OUTPUT, this is the effect that we
+// want to take effect (used to determine
+// cursor feedback).
+//
+// Return Value:
+//
+// NOERROR
+//
+// Function Calls:
+// Function Location
+//
+// TestDebugOut Windows API
+// OleQueryCreateFromData OLE2 API
+// DoDragScroll IDT.CPP
+// QueryDrop IDT.CPP
+// InitDragFeedback IDT.CPP
+// DrawDragFeedback IDT.CPP
+//
+// Comments:
+// Callee should honor the dwEffects as passed in to determine
+// if the caller allows DROPEFFECT_MOVE.
+//
+//********************************************************************
+
+STDMETHODIMP CDropTarget::DragEnter(LPDATAOBJECT pDataObj, DWORD grfKeyState,
+ POINTL pointl, LPDWORD pdwEffect)
+{
+ TestDebugOut("In IDT::DragEnter\r\n");
+
+ /* Determine if the drag source data object offers a data format
+ ** that we understand. we accept only creating embedded objects.
+ */
+ m_fCanDropCopy = ((OleQueryCreateFromData(pDataObj) == NOERROR) ?
+ TRUE : FALSE);
+ m_fCanDropLink = FALSE; // linking NOT supported in this simple sample
+
+ if (m_fCanDropCopy || m_fCanDropLink)
+ InitDragFeedback(pDataObj, pointl);
+
+ BOOL fDragScroll = DoDragScroll ( pointl );
+
+ if (QueryDrop(grfKeyState,pointl,fDragScroll,pdwEffect))
+ {
+ DrawDragFeedback( pointl );
+ }
+
+ // with our drag drop optimization, pDataObj will actually be a
+ // wrapper data object. QueryGetData calls (currently) will be
+ // propogated to the drag source (whereas EnumFormatetc is handled
+ // locally). Make sure we can do a QueryGetData.
+
+ FORMATETC formatetc;
+ formatetc.cfFormat = CF_METAFILEPICT;
+ formatetc.tymed = TYMED_MFPICT;
+ formatetc.ptd = NULL;
+ formatetc.lindex = -1;
+ formatetc.dwAspect = DVASPECT_CONTENT;
+
+ // E_FAIL is usually returned if we could not get the drag source
+ // data object.
+ if( pDataObj->QueryGetData(&formatetc) == E_FAIL )
+ {
+ TestDebugOut("WARNING! QueryGetData failed!");
+ }
+
+ return NOERROR;
+}
+
+
+//**********************************************************************
+//
+// CDropTarget::DragOver
+//
+// Purpose:
+//
+// Called when the mouse moves, key state changes, or a time
+// interval passes while the mouse is still within our DropTarget
+// window.
+//
+// Parameters:
+//
+// DWORD grfKeyState - current key state
+// POINTL pointl - position of mouse
+// LPDWORD pdwEffect - (IN-OUT) drag effect that should occur
+// ON INPUT, this is dwOKEffects that source
+// passed to DoDragDrop API.
+// ON OUTPUT, this is the effect that we
+// want to take effect (used to determine
+// cursor feedback).
+//
+// Return Value:
+//
+// NOERROR
+//
+// Function Calls:
+// Function Location
+//
+// TestDebugOut Windows API
+// DoDragScroll IDT.CPP
+// QueryDrop IDT.CPP
+// DrawDragFeedback IDT.CPP
+// UndrawDragFeedback IDT.CPP
+//
+// Comments:
+// Callee should honor the dwEffects as passed in to determine
+// if the caller allows DROPEFFECT_MOVE. OLE pulses the DragOver
+// calls in order that the DropTarget can implement drag scrolling
+//
+//********************************************************************
+
+STDMETHODIMP CDropTarget::DragOver (DWORD grfKeyState, POINTL pointl,
+ LPDWORD pdwEffect)
+{
+ TestDebugOut("In IDT::DragOver\r\n");
+
+ BOOL fDragScroll = DoDragScroll ( pointl );
+
+ if (QueryDrop(grfKeyState,pointl,fDragScroll,pdwEffect))
+ {
+ DrawDragFeedback( pointl );
+ }
+ else
+ {
+ UndrawDragFeedback();
+ }
+
+ return NOERROR;
+}
+
+
+//**********************************************************************
+//
+// CDropTarget::DragLeave
+//
+// Purpose:
+//
+// Called when the mouse leaves our DropTarget window
+//
+// Parameters:
+//
+// none.
+//
+// Return Value:
+//
+// S_OK
+//
+// Function Calls:
+// Function Location
+//
+// TestDebugOut Windows API
+// UndrawDragFeedback IDT.CPP
+// ResultFromScode OLE2 API
+//
+//
+//********************************************************************
+
+STDMETHODIMP CDropTarget::DragLeave ()
+{
+ TestDebugOut("In IDT::DragLeave\r\n");
+
+ UndrawDragFeedback();
+
+ return ResultFromScode(S_OK);
+}
+
+
+//**********************************************************************
+//
+// CDropTarget::Drop
+//
+// Purpose:
+//
+// Called when a Drop operation should take place.
+//
+// Parameters:
+//
+// LPDATAOBJECT pDataObj - IDataObject from Drop source
+// DWORD grfKeyState - current key state
+// POINTL pointl - position of mouse
+// LPDWORD pdwEffect - (IN-OUT) drag effect that should occur
+// ON INPUT, this is dwOKEffects that source
+// passed to DoDragDrop API.
+// ON OUTPUT, this is the effect that we
+// want to take effect (used to determine
+// cursor feedback).
+//
+// Return Value:
+//
+// S_OK if sucess or HRESULT of the error code if fails
+//
+// Function Calls:
+// Function Location
+//
+// TestDebugOut Windows API
+// CSimpleSite::Create SITE.CPP
+// CSimpleSite::InitObject SITE.CPP
+// OleCreateFromData OLE2 API
+// DoDragScroll IDT.CPP
+// QueryDrop IDT.CPP
+// InitDragFeedback IDT.CPP
+// DrawDragFeedback IDT.CPP
+// UndrawDragFeedback IDT.CPP
+// GetScode OLE2 API
+// ResultFromScode OLE2 API
+//
+// Comments:
+// Callee should honor the dwEffects as passed in to determine
+// if the caller allows DROPEFFECT_MOVE.
+//
+//********************************************************************
+
+STDMETHODIMP CDropTarget::Drop (LPDATAOBJECT pDataObj, DWORD grfKeyState,
+ POINTL pointl, LPDWORD pdwEffect)
+{
+ FORMATETC fmtetc;
+ SCODE sc = S_OK;
+
+ TestDebugOut("In IDT::Drop\r\n");
+
+ UndrawDragFeedback();
+
+ if (pDataObj && QueryDrop(grfKeyState,pointl,FALSE,pdwEffect))
+ {
+ m_pDoc->m_lpSite = CSimpleSite::Create(m_pDoc);
+ if (!m_pDoc->m_lpSite)
+ {
+ /* memory allocation problem. cannot continue.
+ */
+ return(ResultFromScode(E_OUTOFMEMORY));
+ }
+
+ // keep same aspect as drop source
+ m_pDoc->m_lpSite->m_dwDrawAspect = m_dwSrcAspect;
+
+ // in order to specify a particular drawing Aspect we must
+ // pass a FORMATETC* to OleCreateFromData
+ fmtetc.cfFormat = NULL; // use whatever for drawing
+ fmtetc.ptd = NULL;
+ fmtetc.lindex = -1;
+ fmtetc.dwAspect = m_dwSrcAspect; // desired drawing aspect
+ fmtetc.tymed = TYMED_NULL;
+
+ HRESULT hrErr = OleCreateFromData (
+ pDataObj,
+ IID_IOleObject,
+ OLERENDER_DRAW,
+ &fmtetc,
+ &m_pDoc->m_lpSite->m_OleClientSite,
+ m_pDoc->m_lpSite->m_lpObjStorage,
+ (LPVOID FAR *)&m_pDoc->m_lpSite->m_lpOleObject);
+
+ if (hrErr == NOERROR)
+ {
+ m_pDoc->m_lpSite->InitObject(FALSE /* fCreateNew */);
+ m_pDoc->DisableInsertObject();
+ }
+ else
+ sc = GetScode(hrErr);
+ }
+
+ return ResultFromScode(sc);
+}