Class DragAndDropHandler
See Also: Class IDragAndDropMgr, Class DropType
class DragAndDropHandler : public InterfaceServer
Description:
This class is available in release 4.0 and later only.
The DragAndDropHandler class is the base class from which specialized drag-and-drop handlers should be derived. Instances of these classes can be registered with the DragAndDropMgr when enabling a window for DnD activity and virtual methods on them are called to handle the various DnD events. Use IDragAndDropMgr::EnableDnD(hwnd, flag, handler) to enable DnD in a window and specify the DragAndDropHandler instance that will handle DnD events for that window. Note that the event method calls all deliver the current target window as an explicit argument, so one instance can potentially be shared among many windows. Further, a parent window can be enabled for DnD and this effectively causes all child windows to be enabled and handled by the given handler (unless overriden by an explicit EnableDnD with a different handler on a child).
// enable DnD on my window
GetDragAndDropMgr()->EnabledDnD(hWnd, TRUE, &myHandler);
There are actually two sets of DnD event handler virtual methods in the base class, a low-level set that equates to the methods on the OLE IDropTarget interface that take raw IDataObject drop data and a high-level set that take fully-parsed DropType drop data. The low-level methods have default implementations provided that do this parsing and call the corresponding high-level method, so in most cases you only need to provide implementations for the high-level methods. You would provide implementations of the low-level methods if custom parsing of the IDataObject was required.
Data Members:
protected:
DropType* current_droptype;
Cache for the currently parsed DropType. This is usually filled in during DragEnter() processing in the DragAndDropHandler for the current window.
static IDragAndDropMgr* dndMgr;
Cached pointer to the DnD manager. For use by subclasses.
Methods:
public:
Prototype:
virtual HRESULT DragEnter(HWND window, IDataObject* pDataObject, DWORD grfKeyState, POINTL pt, DWORD* pdwEffect);
Remarks:
Override this method in your DragAndDropHandler subclass to get low-level control over DnD operations. This is just a redirect of the identical method called on the OLE IDropTarget interface, see MSDN docs for details.
The default implementation for this methods use the DropClipFormat and DropType classes to recognize and parse the incoming IDataObject into a DropType instance and hand this to the associated high-level DnD handler methods desribed next. As an example, here is the default DragEnter() implementation which does the initial parsing on entry to a window:
// DragAndDropHandler default methods, parse IDataObject into
// DropTypes & hand-off main DnD methods to specific handlers
HRESULT DragAndDropHandler::DragEnter(HWND hWnd, IDataObject* pDataObject, DWORD grfKeyState, POINTL pt, DWORD* pdwEffect)
{
current_droptype = NULL;
// look for one of our accepted clip formats
DropClipFormat* cf = DropClipFormat::FindClipFormat(pDataObject);
if (cf != NULL)
{
// have one, get it to parse it into a DropType subclass
current_droptype = cf->ParseDataObject(pDataObject);
if (current_droptype != NULL)
{
// got recognizable drop data,
// pass on to high-level method
if(pdwEffect)
*pdwEffect = DROPEFFECT_LINK|DROPEFFECT_COPY;
POINT p = { pt.x, pt.y };
DragEnter(hWnd, current_droptype,
grfKeyState, p, pdwEffect);
return S_OK;
}
}
// nothing for us
if(pdwEffect)
*pdwEffect = DROPEFFECT_NONE;
return S_OK;
}
Parameters:
HWND window
The specified handle to the window in which the DnD event is occuring. This is one of the windows that was enabled via a IDragAndDropMgr::EnabledDnD() call, so it may be the parent of the lowest-level window that the mouse is actually over.
IDataObject* pDataObject
The incoming IDataObject.
DWORD grfKeyState
The specified current state of the keyboard modifier keys on the keyboard. Valid values can be a combination of any of the flags MK_CONTROL, MK_SHIFT, MK_ALT, MK_BUTTON, MK_LBUTTON, MK_MBUTTON, and MK_RBUTTON.
POINTL pt
The specified current cursor coordinates in the coordinate space of the drop-target window.
DWORD* pdwEffect
On entry, pointer to the value of the pdwEffect parameter of the DoDragDrop function. On return, must contain one of the effect flags from the Win32 DROPEFFECT enumeration, which indicates what the result of the drop operation would be.
Return Value:
Standard return values of E_OUTOFMEMORY, E_INVALIDARG, F_UNEXPECTED, and E_FAIL, S_OK.
Prototype:
virtual HRESULT Drop(HWND window, IDataObject* pDataObject, DWORD grfKeyState, POINTL pt, DWORD* pdwEffect);
Remarks:
This method will parse the dropped dataObject.
Parameters:
HWND window
The specified handle to the window in which the DnD event is occuring. This is one of the windows that was enabled via a IDragAndDropMgr::EnabledDnD() call, so it may be the parent of the lowest-level window that the mouse is actually over.
IDataObject* pDataObject
The incoming IDataObject.
DWORD grfKeyState
The specified current state of the keyboard modifier keys on the keyboard. Valid values can be a combination of any of the flags MK_CONTROL, MK_SHIFT, MK_ALT, MK_BUTTON, MK_LBUTTON, MK_MBUTTON, and MK_RBUTTON.
POINTL pt
The specified current cursor coordinates in the coordinate space of the drop-target window.
DWORD* pdwEffect
On entry, pointer to the value of the pdwEffect parameter of the DoDragDrop function. On return, must contain one of the effect flags from the Win32 DROPEFFECT enumeration, which indicates what the result of the drop operation would be.
Return Value:
Standard return values of E_OUTOFMEMORY, E_INVALIDARG, F_UNEXPECTED, and E_FAIL, S_OK.
Prototype:
virtual HRESULT DragOver(HWND window, DWORD grfKeyState, POINTL pt, DWORD * pdwEffect);
Remarks:
This method handles the process of dragging over a drop target.
Parameters:
HWND window
The specified handle to the window in which the DnD event is occuring. This is one of the windows that was enabled via a IDragAndDropMgr::EnabledDnD() call, so it may be the parent of the lowest-level window that the mouse is actually over.
DWORD grfKeyState
The specified current state of the keyboard modifier keys on the keyboard. Valid values can be a combination of any of the flags MK_CONTROL, MK_SHIFT, MK_ALT, MK_BUTTON, MK_LBUTTON, MK_MBUTTON, and MK_RBUTTON.
POINTL pt
The specified current cursor coordinates in the coordinate space of the drop-target window.
DWORD* pdwEffect
On entry, pointer to the value of the pdwEffect parameter of the DoDragDrop function. On return, must contain one of the effect flags from the Win32 DROPEFFECT enumeration, which indicates what the result of the drop operation would be.
Return Value:
Standard return values of E_OUTOFMEMORY, E_INVALIDARG, F_UNEXPECTED, and E_FAIL, S_OK.
Prototype:
virtual HRESULT DragEnter(HWND window, DropType* type, DWORD grfKeyState, POINT& pt, DWORD* pdwEffect);
Remarks:
This is the high-level method called to handle DnD events with already recognized and parsed data object. Override the above methods as needed in your DragAndDropHandler subclass to handle DnD events.
Parameters:
HWND window
The specified handle to the window in which the DnD event is occuring. This is one of the windows that was enabled via a IDragAndDropMgr::EnabledDnD() call, so it may be the parent of the lowest-level window that the mouse is actually over.
DropType* type
The specified Pointer to the DropType instance that corresponds to the data in the dropped IDataObject. You can use the DropType::TypeCode() method to determine the droptype (see the built-in codes in the DropType section). Each DropType subclass instance has utility methods and public data members containing the parsed drop data. See each subclass definition for details.
DWORD grfKeyState
The specified current state of the keyboard modifier keys on the keyboard. Valid values can be a combination of any of the flags MK_CONTROL, MK_SHIFT, MK_ALT, MK_BUTTON, MK_LBUTTON, MK_MBUTTON, and MK_RBUTTON.
POINT& pt
The specified current cursor coordinates in the coordinate space of the drop-target window.
DWORD* pdwEffect
On entry, pointer to the value of the pdwEffect parameter of the DoDragDrop function. On return, must contain one of the effect flags from the Win32 DROPEFFECT enumeration, which indicates what the result of the drop operation would be.
Return Value:
Standard return values of E_OUTOFMEMORY, E_INVALIDARG, F_UNEXPECTED, and E_FAIL, S_OK.
Default Implementation:
{ return E_FAIL; }
Prototype:
virtual HRESULT Drop(HWND window, DropType* type, DWORD grfKeyState, POINT& pt, DWORD* pdwEffect);
Remarks:
This method will parse the dropped dataObject.
Here's an example implementation of Drop() in the default handler:
HRESULT DefaultDragAndDropHandler::Drop(HWND hwnd, DropType* type,
DWORD grfKeyState, POINT& pt, DWORD* pdwEffect)
{
// This could take a while, set wait cursor
HCURSOR hOldCursor = SetCursor(LoadCursor(NULL, IDC_WAIT));
HRESULT result = S_OK;
// load the dropped data if needed
if (type->Load())
{
// see if dropped on a viewport, if so adjust point
// to be vp-relative
HWND vpwin = FindDropViewport(hwnd, pt);
// Handle the drop depending on drop type
BOOL bRet;
switch (type->TypeCode())
{
case SCENEFILE_DROPTYPE:
bRet = HandleDroppedGeom(
hwnd, vpwin, pt,
sceneFileDropType.current_package[0]);
break;
case IMAGEFILE_DROPTYPE:
bRet = HandleDroppedBitmap(
hwnd, vpwin, pt,
imageFileDropType.current_package[0]);
break;
case DROPSCRIPTEFILE_DROPTYPE:
bRet = HandleDroppedDropScript(
hwnd, vpwin, pt,
dropScriptFileDropType.current_package[0]);
break;
}
result = bRet ? S_OK : E_FAIL;
}
// restore cursor
SetCursor(hOldCursor);
return result;
}
Parameters:
HWND window
The specified handle to the window in which the DnD event is occuring. This is one of the windows that was enabled via a IDragAndDropMgr::EnabledDnD() call, so it may be the parent of the lowest-level window that the mouse is actually over.
DropType* type
The specified Pointer to the DropType instance that corresponds to the data in the dropped IDataObject. You can use the DropType::TypeCode() method to determine the droptype (see the built-in codes in the DropType section). Each DropType subclass instance has utility methods and public data members containing the parsed drop data. See each subclass definition for details.
DWORD grfKeyState
The specified current state of the keyboard modifier keys on the keyboard. Valid values can be a combination of any of the flags MK_CONTROL, MK_SHIFT, MK_ALT, MK_BUTTON, MK_LBUTTON, MK_MBUTTON, and MK_RBUTTON.
POINT& pt
The specified current cursor coordinates in the coordinate space of the drop-target window.
DWORD* pdwEffect
On entry, pointer to the value of the pdwEffect parameter of the DoDragDrop function. On return, must contain one of the effect flags from the Win32 DROPEFFECT enumeration, which indicates what the result of the drop operation would be.
Return Value:
Standard return values of E_OUTOFMEMORY, E_INVALIDARG, F_UNEXPECTED, and E_FAIL, S_OK.
Default Implementation:
{ return E_FAIL; }
Prototype:
virtual HRESULT DragOver(HWND window, DWORD grfKeyState, POINT& pt, DWORD * pdwEffect);
Remarks:
This method handles the process of dragging over a drop target.
Parameters:
HWND window
The specified handle to the window in which the DnD event is occuring. This is one of the windows that was enabled via a IDragAndDropMgr::EnabledDnD() call, so it may be the parent of the lowest-level window that the mouse is actually over.
DWORD grfKeyState
The specified current state of the keyboard modifier keys on the keyboard. Valid values can be a combination of any of the flags MK_CONTROL, MK_SHIFT, MK_ALT, MK_BUTTON, MK_LBUTTON, MK_MBUTTON, and MK_RBUTTON.
POINT& pt
The specified current cursor coordinates in the coordinate space of the drop-target window.
DWORD* pdwEffect
On entry, pointer to the value of the pdwEffect parameter of the DoDragDrop function. On return, must contain one of the effect flags from the Win32 DROPEFFECT enumeration, which indicates what the result of the drop operation would be.
Return Value:
Standard return values of E_OUTOFMEMORY, E_INVALIDARG, F_UNEXPECTED, and E_FAIL, S_OK.
Default Implementation:
{ return E_FAIL; }
Prototype:
virtual HRESULT DragLeave(HWND window);
Remarks:
This method handles the process of the drag operation leaving the drop target window.
Parameters:
HWND window
The specified handle to the window in which the DnD event is occuring. This is one of the windows that was enabled via a IDragAndDropMgr::EnabledDnD() call, so it may be the parent of the lowest-level window that the mouse is actually over.
Return Value:
Standard return values of E_OUTOFMEMORY, E_INVALIDARG, F_UNEXPECTED, and E_FAIL, S_OK.
Default Implementation:
{ return E_FAIL; }
Prototype:
virtual void Acquire();
Remarks:
This method is called called when the DnD manager starts managing DnD events for a particular window for this handler. You can provide an implementation if you need to keep track of extant uses of the handler (say, by ref-counting) or to do handler-specific cleanup.
Default Implementation:
{ }
Prototype:
virtual void Release();
Remarks:
This method is called called when the DnD manager stops managing DnD events for a particular window for this handler. You can provide an implementation if you need to keep track of extant uses of the handler (say, by ref-counting) or to do handler-specific cleanup.
Default Implementation:
{ }