IDT.CPP
资源名称:MSDN_VC98.zip [点击查看]
上传用户:bangxh
上传日期:2007-01-31
资源大小:42235k
文件大小:26k
源码类别:
Windows编程
开发平台:
Visual C++
- //**********************************************************************
- // File name: IDT.CPP
- //
- // Implementation file for CDropTarget
- //
- // Functions:
- //
- // See IDT.H for class definition
- //
- // Copyright (c) 1992 - 1997 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 OLESTD API
- //
- // Comments:
- //
- //********************************************************************
- BOOL CDropTarget::QueryDrop (
- DWORD grfKeyState,
- POINTL pointl,
- BOOL fDragScroll,
- LPDWORD pdwEffect
- )
- {
- DWORD dwScrollEffect = 0L;
- DWORD dwOKEffects = *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 OLESTD Library
- // GlobalLock WINDOWS API
- // GlobalUnlock WINDOWS API
- // ReleaseStgMedium OLE2 API
- // OffsetPoint IDT.CPP
- // SetTopLeft IDT.CPP
- // SetBottomRight IDT.CPP
- //
- // Comments:
- // In order to known 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
- // GlobalUnlock WINDOWS API
- // HighlightRect IDT.CPP
- //
- // Comments:
- // In order to known 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
- // HighlightRect IDT.CPP
- // GetDC WINDOWS API
- // ReleaseDC WINDOWS API
- //
- // Comments:
- //
- //********************************************************************
- 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:
- //
- // 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
- //
- // OutputDebugString Windows API
- // CSimpleDoc::QueryInterface DOC.CPP
- //
- // Comments:
- //
- //********************************************************************
- STDMETHODIMP CDropTarget::QueryInterface(REFIID riid, LPVOID FAR* ppvObj)
- {
- OutputDebugString("In IDT::QueryInterfacern");
- // delegate to the document
- return m_pDoc->QueryInterface(riid, ppvObj);
- }
- //**********************************************************************
- //
- // CDropTarget::AddRef
- //
- // Purpose:
- //
- // Increments the reference count on this interface
- //
- // Parameters:
- //
- // None
- //
- // Return Value:
- //
- // The current reference count on this interface.
- //
- // Function Calls:
- // Function Location
- //
- // CSimpleDoc::AddReff DOC.CPP
- // OutputDebugString Windows API
- //
- // Comments:
- //
- // This function adds one to the ref count of the interface,
- // and calls then calls CSimpleObj to increment its ref.
- // count.
- //
- //********************************************************************
- STDMETHODIMP_(ULONG) CDropTarget::AddRef()
- {
- OutputDebugString("In IDT::AddRefrn");
- // increment the interface reference count (for debugging only)
- ++m_nCount;
- // delegate to the document Object
- return m_pDoc->AddRef();
- }
- //**********************************************************************
- //
- // CDropTarget::Release
- //
- // Purpose:
- //
- // Decrements the reference count on this interface
- //
- // Parameters:
- //
- // None
- //
- // Return Value:
- //
- // The current reference count on this interface.
- //
- // Function Calls:
- // Function Location
- //
- // CSimpleDoc::Release DOC.CPP
- // OutputDebugString Windows API
- //
- // Comments:
- //
- // This function subtracts one from the ref count of the interface,
- // and calls then calls CSimpleDoc to decrement its ref.
- // count.
- //
- //********************************************************************
- STDMETHODIMP_(ULONG) CDropTarget::Release()
- {
- OutputDebugString("In IDT::Releasern");
- // decrement the interface reference count (for debugging only)
- --m_nCount;
- // 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:
- //
- // S_OK
- //
- // Function Calls:
- // Function Location
- //
- // OutputDebugString Windows API
- // OleQueryCreateFromData OLE2 API
- // DoDragScroll IDT.CPP
- // QueryDrop IDT.CPP
- // InitDragFeedback 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.
- //
- //********************************************************************
- STDMETHODIMP CDropTarget::DragEnter (LPDATAOBJECT pDataObj, DWORD grfKeyState, POINTL pointl, LPDWORD pdwEffect)
- {
- OutputDebugString("In IDT::DragEnterrn");
- /* 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 );
- 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:
- //
- // S_OK
- //
- // Function Calls:
- // Function Location
- //
- // OutputDebugString 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)
- {
- OutputDebugString("In IDT::DragOverrn");
- 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
- //
- // OutputDebugString Windows API
- // UndrawDragFeedback IDT.CPP
- // OLE2 API
- //
- // Comments:
- //
- //********************************************************************
- STDMETHODIMP CDropTarget::DragLeave ()
- {
- OutputDebugString("In IDT::DragLeavern");
- UndrawDragFeedback();
- return 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
- //
- // Function Calls:
- // Function Location
- //
- // OutputDebugString 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
- // OLE2 API
- // 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;
- OutputDebugString("In IDT::Droprn");
- UndrawDragFeedback();
- if (pDataObj && QueryDrop(grfKeyState,pointl,FALSE,pdwEffect))
- {
- m_pDoc->m_lpSite = CSimpleSite::Create(m_pDoc);
- // 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 = hrErr;
- }
- return sc;
- }