Drop Files onto a Window (WM_DROPFILES)
clipboard_files stages a file-drop list on the clipboard so a user can
Ctrl+V it; file_drop actively drops files onto a target window — the
completion of a drag-and-drop — by posting a WM_DROPFILES message carrying a
DROPFILES blob. It reuses clipboard_files.build_dropfiles to pack that
blob (the byte layout is shared, not re-implemented) and dispatches it through an
injectable driver seam, so the build-and-dispatch logic is unit-testable on any
platform with a fake driver; the real GlobalAlloc + PostMessage lives in
the default Win32 driver. Imports no PySide6.
Headless API
from je_auto_control import plan_file_drop, drop_files
# Pure dry-run — inspect the payload without sending:
plan_file_drop(["C:\\a\\one.txt"], point=(10, 20))
# {"message": 0x233, "paths": [...], "point": [10, 20], "wide": True,
# "blob_size": ...}
# Real drop onto a window handle (Windows):
drop_files(hwnd, ["C:\\a\\one.txt", "C:\\b\\two.png"], point=(10, 20))
# Inject a driver to intercept the send (e.g. in tests):
drop_files(hwnd, ["x.txt"], driver=lambda hwnd, blob, point: True)
point is the drop coordinate in the window’s client area. drop_files
returns bool; the default driver posts the real WM_DROPFILES (the
receiving window then owns and frees the memory via DragFinish) and raises
RuntimeError off Windows.
Executor commands
AC_drop_files (hwnd / paths / point) performs the drop;
AC_plan_file_drop (paths / point) is the pure dry-run. They are
exposed as the matching ac_* MCP tools (drop side-effect-only, plan
read-only) and as Script Builder commands under Window.