DropTarget Reference

This is a reference for the DropTarget object, which allows executing drag-and-drop operations (IDropTarget) on folders and files via script.

Notation: P = Property, M = Method. Member names are case-insensitive.

Table of Contents

  1. How to Obtain
  2. Methods
  3. Properties
  4. Execution Flow and Script Events
  5. Constants
  6. Examples

1. How to Obtain

Method Description
api.DropTarget(item) Returns a DropTarget for item (a FolderItem, path string, etc.). Internally, it queries the parent folder of the item for IDropTarget. Returns nothing (empty) if the ItemIDList of the item cannot be obtained.
FV.Droptarget The DropTarget for the current folder (a property of FolderView; see folderview_reference_en.md).

2. Methods

DragEnter, DragOver, and Drop accept the same arguments.

DropTarget.Drop(dataObj, grfKeyState, pt [, pdwEffect [, bSingle [, caller]]])

Parameter Content
dataObj The data to be dragged. A FolderItems object (e.g., FV.SelectedItems()) or an IDataObject. Returns E_INVALIDARG if unparseable.
grfKeyState Key/button state (combination of MK_*). E.g., MK_LBUTTON (Left mouse button), MK_CONTROL (Ctrl), MK_SHIFT (Shift).
pt Drop position (screen coordinates). api.Memory("POINT") or an object with equivalent {x, y}.
pdwEffect Drop effect (DROPEFFECT_*). If passed an object with index 0 such as Memory(DWORD), allowed effects are read from it and the resulting effect is written back. If a number is passed, it is used only as allowed effects and no result is returned. If omitted, COPY \| MOVE \| LINK is allowed and no result is returned.
bSingle If set to true, only the stage of the called method is executed (Section 4). If false or omitted, the full sequence of steps is executed.
caller The object passed to the 1st argument Ctrl of script events (such as te.OnDragEnter). If omitted, this DropTarget itself is used.

A minimum of 3 arguments (dataObj, grfKeyState, pt) is required. If insufficient arguments are provided, nothing is executed and E_INVALIDARG is returned.

Name Return Value Description
DragEnter(dataObj, grfKeyState, pt [, ...]) HRESULT Notifies that the drag has entered the target.
DragOver(dataObj, grfKeyState, pt [, ...]) HRESULT Notifies position and key state during drag, checking if the drop is acceptable (effect).
Drop(dataObj, grfKeyState, pt [, ...]) HRESULT Executes the drop operation (performing actual copy, move, or shortcut link creation).
DragLeave() HRESULT Notifies that the drag has left the target. Calls shell-side DragLeave and te.OnDragLeave. Return value when there is no shell-side target is undefined (Needs Verification).

The return value is S_OK (0) on success, or a negative value on failure (e.g., E_INVALIDARG = 0x80070057).


3. Properties

Name Type Description
Type P (Read-only) Always CTRL_DT (0x80000).
FolderItem P (Read-only) Target item (FolderItem) of this DropTarget. If created with api.DropTarget(item), this returns item.

4. Execution Flow and Script Events

When called with bSingle set to false (or omitted), preceding stages are executed sequentially within a single call.

Call Executed Stages
DragEnter(…) DragEnter → DragLeave
DragOver(…) DragEnter → DragOver → DragLeave
Drop(…) DragEnter → DragOver → Drop → DragLeave

Normally, calling Drop(…) once is sufficient, and explicitly calling preceding stages is unnecessary (standard add-ons and sync1.js call Drop or DragOver individually). When bSingle is set to true, only the called stage is executed, and DragLeave is not automatically invoked (useful when you want to call DragEnter/DragOver/Drop sequentially by yourself, ending with DragLeave()).

Integration with Script Events

A DropTarget created with api.DropTarget(item) (with a target item) will, at each stage, first call the script events (te.OnDragEnter / te.OnDragOver / te.OnDrop) before proceeding to standard shell processing.

Stage Behavior
DragEnter Calls shell-standard DragEnter, followed by te.OnDragEnter. If the event returns S_OK, that effect is applied.
DragOver Calls te.OnDragOver first. Calls shell-standard DragOver only if the event returns something other than S_OK or does not modify the effect.
Drop Calls te.OnDrop first. If it returns S_OK, shell-standard Drop will NOT be executed (assuming script side handled it). If other than S_OK, shell-standard Drop is executed.
Final (bSingle is false) Calls shell-standard DragLeave. In the case of Drop, te.OnDragLeave is also called.

5. Constants

Defined in consts.js.

DROPEFFECT_*: DROPEFFECT_NONE = 0 / DROPEFFECT_COPY = 1 / DROPEFFECT_MOVE = 2 / DROPEFFECT_LINK = 4

MK_*: MK_LBUTTON = 1 / MK_RBUTTON = 2 / MK_SHIFT = 4 / MK_CONTROL = 8 / MK_MBUTTON = 0x10 / MK_XBUTTON1 = 0x20 / MK_XBUTTON2 = 0x40

CTRL_DT = 0x80000 (Value returned by Type)


6. Examples

// "Drop" selected files to another folder (with Ctrl key = Copy)
const FV = te.Ctrl(CTRL_FV);
const Items = FV.SelectedItems();
const DropTarget = api.DropTarget("C:\\Backup");
if (DropTarget) {
    const pdwEffect = api.Memory("DWORD");
    pdwEffect[0] = DROPEFFECT_COPY | DROPEFFECT_MOVE | DROPEFFECT_LINK;
    const pt = api.Memory("POINT");
    api.GetCursorPos(pt);
    const hr = DropTarget.Drop(Items, MK_LBUTTON | MK_CONTROL, pt, pdwEffect);
    // Success if hr === 0 (S_OK). Actual effect applied will be stored in pdwEffect[0]
}

// Query drop effect only (without executing drop)
const dt = api.DropTarget(dest);
const eff = api.Memory("DWORD");
eff[0] = DROPEFFECT_COPY | DROPEFFECT_MOVE | DROPEFFECT_LINK;
dt.DragOver(Items, MK_LBUTTON, pt, eff);
const canMove = !!(eff[0] & DROPEFFECT_MOVE);

// Delegate to default drop behavior inside an event
te.OnDrop = function (Ctrl, dataObj, pgrfKeyState, pt, pdwEffect) {
    const Target = Ctrl.FolderItem;
    const DropTarget = api.DropTarget(Target);
    if (DropTarget) {
        return DropTarget.Drop(dataObj, pgrfKeyState[0], pt, pdwEffect);
    }
};

// Manual stage control (bSingle = true)
const d = api.DropTarget(dest);
d.DragEnter(Items, MK_LBUTTON, pt, eff, true);
d.DragOver(Items, MK_LBUTTON, pt, eff, true);
d.Drop(Items, MK_LBUTTON, pt, eff, true);
d.DragLeave();

Re-invoking its own event inside te.OnDrop may cause infinite recursion if Ctrl refers to the same item. In standard scripts, Target in api.DropTarget(Target) is limited to Ctrl.FolderItem or the result of HitTest.