CView
derived classes are prepared for drag & drop.
To register a window as a drop target, add a
COleDropTarget
member to your class and call the
Register()
function passing the
CWnd
pointer to the window. The common place to do this is
OnInitialUpdate()
with view windows:
void CMyListView::OnInitialUpdate(void)
{
if (NULL == m_pDropTarget)
m_DropTarget.Register(this);
}
You can now implement your versions of the virtual drag functions:
OnDragEnter
This is called when dragging the first time (or again after leaving) over the window. At first it should be checked if the window is able to drop data (window is enabled and an optional read only state is not set). Then check if the drag source provides data that can be dropped. Additional checks may be if the provided data would fit (e.g. number of text characters is less than a specified limit). The result of these checks may be stored in a member variable to be used by
OnDragOver()
. The returned drop effect should be determined like the one returned by
OnDragOver()
.
OnDragOver
The main purpose is to set the drop effect according to the key state (e.g. copying when the Ctrl key is down and moving otherwise), and to check if data can be dropped on the current position (e.g. over the client area and not over a scroll bar or the header of a list control). This is called repeatedly when moving around the window (like the
WM_MOUSEMOVE
message) and when the key state (Shift, Ctrl, Alt) changes. So don't perform time consuming tasks inside this function. This is also called before
OnDropEx()
and
OnDrop()
to get the drop effect to be passed to these functions. Because the returned drop effect is used to determine the type of cursor and returned to the source upon dropping, it should be a single effect and not a combination of multiple effects.
OnDragLeave
This is called when leaving the window. Use it for cleanup. With most windows there is no need to implement this handler. If it is present to perform some cleanup, it may be necessary to add similar code to the drop handlers because
OnDragLeave()
is not called when a dropping occurs.
OnDrop and OnDropEx
Only one of these functions must be implemented. They are called when releasing the mouse button when over the window. Get the data here and insert them into the control when dropping should occur. When the mouse button is released, these functions are called:
OnDragOver()
is called to get the drop effect to be passed to OnDropEx()
and/or OnDrop()
.OnDropEx()
is called (even when the drop effect is DROPEFFECT_NONE
).- When
OnDropEx()
returns -1 and the drop effect is not DROPEFFECT_NONE
, OnDrop()
is called. - When
OnDropEx()
returns -1 and the drop effect is DROPEFFECT_NONE
, OnDragLeave()
is called.
Because
OnDropEx()
is always called even when the drop effect is
DROPEFFECT_NONE
,
OnDropEx()
should check the passed value and return without dropping in this case.
OnDragScroll
This can be handled to perform auto scrolling when dragging over a scrollbar or an inset region (a small band inside the borders of the client area).
OnDragScroll()
is the first handler called when entering or moving over a window. When scrolling is active, the
DROPEFFECT_SCROLL
bit is set in the return value to avoid further processing. If the scroll bit is not set,
OnDragEnter()
resp.
OnDragOver()
is called.
Study the MFC COleDropTarget::OnDragScroll source to see how it is basically implemented.