windows-nt/Source/XPSP1/NT/com/oleutest/simpdnd/ids.cpp
2020-09-26 16:20:57 +08:00

385 lines
9.8 KiB
C++
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

//**********************************************************************
// File name: IDS.CPP
//
// Implementation file for CDropSource
//
// Functions:
//
// See IDS.H for class definition
//
// Copyright (c) 1992 - 1993 Microsoft Corporation. All rights reserved.
//**********************************************************************
#include "pre.h"
#include "app.h"
#include "doc.h"
#include "site.h"
#include "dxferobj.h"
//+-------------------------------------------------------------------------
//
// Member: CSimpleDoc::FailureNotifyHelper(
//
// Synopsis: Report a drag drop error
//
// Arguments: [pszMsg] - Message
// [dwData] - Data to print out
//
// Algorithm: Print a message box for fatal errors during drag drop
// operation.
//
// History: dd-mmm-yy Author Comment
// 06-May-94 Ricksa author
//
//--------------------------------------------------------------------------
void CSimpleDoc::FailureNotifyHelper(TCHAR *pszMsg, DWORD dwData)
{
TCHAR pszBuf[256];
wsprintf(pszBuf, TEXT("%s %lx"), pszMsg, dwData);
MessageBox(m_hDocWnd, pszBuf, TEXT("Drag/Drop Error"), MB_OK);
}
//**********************************************************************
//
// CSimpleDoc::QueryDrag
//
// Purpose:
//
// Check to see if Drag operation should be initiated based on the
// current position of the mouse.
//
// Parameters:
//
// POINT pt - position of mouse
//
// Return Value:
//
// BOOL - TRUE if drag should take place,
// else FALSE
//
// Function Calls:
// Function Location
//
// CSimpleSite::GetObjRect SITE.CPP
// PtInRect Windows API
//
//
//********************************************************************
BOOL CSimpleDoc::QueryDrag(POINT pt)
{
// if pt is within rect of object, then start drag
if (m_lpSite)
{
RECT rect;
m_lpSite->GetObjRect(&rect);
return ( PtInRect(&rect, pt) ? TRUE : FALSE );
}
else
return FALSE;
}
//**********************************************************************
//
// CSimpleDoc::DoDragDrop
//
// Purpose:
//
// Actually perform a drag/drop operation with the current
// selection in the source document.
//
// Parameters:
//
// none.
//
// Return Value:
//
// DWORD - returns the result effect of the
// drag/drop operation:
// DROPEFFECT_NONE,
// DROPEFFECT_COPY,
// DROPEFFECT_MOVE, or
// DROPEFFECT_LINK
//
// Function Calls:
// Function Location
//
// CDataXferObj::Create DXFEROBJ.CPP
// CDataXferObj::QueryInterface DXFEROBJ.CPP
// CDataXferObj::Release DXFEROBJ.CPP
// DoDragDrop OLE API
// TestDebugOut Windows API
// MessageBox Windows API
//
//
//********************************************************************
DWORD CSimpleDoc::DoDragDrop (void)
{
DWORD dwEffect = 0;
LPDATAOBJECT lpDataObj;
TestDebugOut("In CSimpleDoc::DoDragDrop\r\n");
// Create a data transfer object by cloning the existing OLE object
CDataXferObj FAR* pDataXferObj = CDataXferObj::Create(m_lpSite,NULL);
if (! pDataXferObj)
{
MessageBox(NULL, TEXT("Out-of-memory"), TEXT("SimpDnD"),
MB_SYSTEMMODAL | MB_ICONHAND);
return DROPEFFECT_NONE;
}
// initially obj is created with 0 refcnt. this QI will make it go to 1.
pDataXferObj->QueryInterface(IID_IDataObject, (LPVOID FAR*)&lpDataObj);
assert(lpDataObj);
m_fLocalDrop = FALSE;
m_fLocalDrag = TRUE;
HRESULT hRes;
hRes=::DoDragDrop(lpDataObj,
&m_DropSource,
m_lpApp->m_dwSourceEffect, // we only allow copy
&dwEffect);
if (hRes!=ResultFromScode(S_OK)
&& hRes!=ResultFromScode(DRAGDROP_S_DROP)
&& hRes!=ResultFromScode(DRAGDROP_S_CANCEL))
{
FailureNotifyHelper(
TEXT("Unexpected error from DoDragDrop"), hRes);
}
// Validate the responses
if (hRes == ResultFromScode(DRAGDROP_S_DROP))
{
// Drop was successful so make sure the effects make sense
if (((dwEffect & m_lpApp->m_dwSourceEffect) == 0)
&& (dwEffect != DROPEFFECT_NONE))
{
FailureNotifyHelper(
TEXT("Unexpected Effect on DRAGDROP_S_DROP from DoDragDrop"),
dwEffect);
}
}
else if ((hRes == ResultFromScode(DRAGDROP_S_CANCEL))
|| (hRes == ResultFromScode(S_OK)))
{
// Drop was cancelled/or never happened so the effect s/b none
if (dwEffect != DROPEFFECT_NONE)
{
FailureNotifyHelper(
TEXT("Unexpected Effect on S_OK or Cancel from DoDragDrop"),
dwEffect);
}
}
m_fLocalDrag = FALSE;
/* if after the Drag/Drop modal (mouse capture) loop is finished
** and a drag MOVE operation was performed, then we must delete
** the selection that was dragged.
*/
if ( (dwEffect & DROPEFFECT_MOVE) != 0 )
{
// Dump our object - we never save it.
m_lpApp->lCreateDoc(m_lpApp->m_hAppWnd, 0, 0, 0);
}
pDataXferObj->Release(); // this should destroy the DataXferObj
return dwEffect;
}
//**********************************************************************
//
// CDropSource::QueryInterface
//
// Purpose:
//
// Return a pointer to a requested interface
//
// 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 CDropSource::QueryInterface(REFIID riid, LPVOID FAR* ppvObj)
{
TestDebugOut("In IDS::QueryInterface\r\n");
// delegate to the document
return m_pDoc->QueryInterface(riid, ppvObj);
}
//**********************************************************************
//
// CDropSource::AddRef
//
// Purpose:
//
// Increments the reference count of CSimpleDoc. Since CDropSource is
// a nested class of CSimpleDoc, we don't need a separate reference
// count for the CDropSource. We can safely use the reference count
// of CSimpleDoc here.
//
// Parameters:
//
// None
//
// Return Value:
//
// The new reference count of CSimpleDoc
//
// Function Calls:
// Function Location
//
// CSimpleDoc::AddRef DOC.CPP
// TestDebugOut Windows API
//
//
//********************************************************************
STDMETHODIMP_(ULONG) CDropSource::AddRef()
{
TestDebugOut("In IDS::AddRef\r\n");
// delegate to the document Object
return m_pDoc->AddRef();
}
//**********************************************************************
//
// CDropSource::Release
//
// Purpose:
//
// Decrements the reference count of CSimpleDoc. Since CDropSource is
// a nested class of CSimpleDoc, we don't need a separate reference
// count for the CDropSource. We can safely use the reference count
// of CSimpleDoc here.
//
// Parameters:
//
// None
//
// Return Value:
//
// The new reference count of CSimpleDoc
//
// Function Calls:
// Function Location
//
// CSimpleDoc::Release DOC.CPP
// TestDebugOut Windows API
//
//
//********************************************************************
STDMETHODIMP_(ULONG) CDropSource::Release()
{
TestDebugOut("In IDS::Release\r\n");
// delegate to the document object
return m_pDoc->Release();
}
//**********************************************************************
//
// CDropSource::QueryContinueDrag
//
// Purpose:
//
// Called to determine if a drop should take place or be canceled.
//
// Parameters:
//
// BOOL fEscapePressed - TRUE if ESCAPE key has been pressed
// DWORD grfKeyState - key state
//
// Return Value:
//
// DRAGDROP_S_CANCEL - drag operation should be canceled
// DRAGDROP_S_DROP - drop operation should be performed
// S_OK - dragging should continue
//
//
// Function Calls:
// Function Location
//
// ResultFromScode OLE API
//
//
//********************************************************************
STDMETHODIMP CDropSource::QueryContinueDrag (
BOOL fEscapePressed,
DWORD grfKeyState
)
{
if (fEscapePressed)
return ResultFromScode(DRAGDROP_S_CANCEL);
else
if (!(grfKeyState & MK_LBUTTON))
return ResultFromScode(DRAGDROP_S_DROP);
else
return NOERROR;
}
//**********************************************************************
//
// CDropSource::GiveFeedback
//
// Purpose:
//
// Called to set cursor feedback
//
// Parameters:
//
// DWORD dwEffect - drop operation to give feedback for
//
// Return Value:
//
// DRAGDROP_S_USEDEFAULTCURSORS - tells OLE to use standard cursors
//
// Function Calls:
// Function Location
//
// ResultFromScode OLE API
//
//
//********************************************************************
STDMETHODIMP CDropSource::GiveFeedback (DWORD dwEffect)
{
return ResultFromScode(DRAGDROP_S_USEDEFAULTCURSORS);
}