Когда начинается большинство операций перетаскивания, система создает окно обратной связи с классом «SysDragImage». Можно отследить создание и уничтожение этого окна обратной связи и соответственно отреагировать в вашем приложении.
Вот пример кода (объявление класса формы пропускается, чтобы сделать его короче):
procedure WinEventProc(hWinEventHook: THandle; event: DWORD;
hwnd: HWND; idObject, idChild: Longint; idEventThread, dwmsEventTime: DWORD); stdcall;
var
ClassName: string;
begin
SetLength(ClassName, 255);
SetLength(ClassName, GetClassName(hWnd, pchar(ClassName), 255));
if pchar(ClassName) = 'SysDragImage' then
begin
if event = EVENT_OBJECT_CREATE then
Form1.Memo1.Lines.Add('Drag Start')
else
Form1.Memo1.Lines.Add('Drag End');
end;
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
FEvent1 := SetWinEventHook(EVENT_OBJECT_CREATE, EVENT_OBJECT_CREATE, 0, @WinEventProc, 0, 0, WINEVENT_OUTOFCONTEXT);
FEvent2 := SetWinEventHook(EVENT_OBJECT_DESTROY, EVENT_OBJECT_DESTROY, 0, @WinEventProc, 0, 0, WINEVENT_OUTOFCONTEXT);
end;
procedure TForm1.FormDestroy(Sender: TObject);
begin
UnhookWinEvent(FEvent1);
UnhookWinEvent(FEvent2);
end;
Единственная проблема здесь - когда вы нажимаете Escape сразу после начала перетаскивания, система не генерирует событие EVENT_OBJECT_DESTROY. Но это легко решить, запустив таймер EVENT_OBJECT_CREATE и периодически отслеживая, все ли окна обратной связи еще активны.