I am dragging and dropping email attachments from outlook. The files are dropped into a Virtual Tree View.
My import function at the end of the drag over event takes a while to process the files and it freezes the outlook application until the function ends.
I want to be able to end the drag operation half way through the function.
procedure TForm.vstItemsDragDrop(Sender: TBaseVirtualTree;
Source: TObject; DataObject: IDataObject; Formats: TFormatArray;
Shift: TShiftState; Pt: TPoint; var Effect: Integer; Mode: TDropMode);
var
fileList : IStringList;
drop : IOleDrop;
begin
fileList:= TIStringList.Create;
drop := COleDrop.Create.def(DataObject);
fileList := drop.GetDroppedFileList(fileWarnings);
//I want to terminate the drag operator here because I already have what I need
//This imports parts takes a while to run so I want to end the drag and drop operation
//Outlook freezes still has cursor state on copy and doesn't respond to clicks or ESC
ImportParts( fileList)
end;
I usually just pick up the information in the Drop event (ie. do not process it) and then send a message back to my form that there is new information to be processed. The Drop event thus exits rather quickly, and the message handler then picks up and handles whatever was dropped.
In your case, you should make something like this:
CONST
WM_PROCESS_DROPPED_FILES = WM_USER+42;
TYPE
TMainForm = CLASS(TForm)
.
.
PRIVATE
fileList : IStringList; // Ie. move the declaration here...
PROCEDURE ProcessFiles(VAR MSG : TMessage); MESSAGE WM_PROCESS_DROPPED_FILES;
.
.
END;
and in your drop event, remove the declaration of fileList (you have made it a private member of the form instead of a local variable) and replace
ImportParts(fileList)
with
PostMessage(Handle,WM_PROCESS_DROPPED_FILES)
then implement
PROCEDURE TMainForm.ProcessFiles(VAR MSG : TMessage);
BEGIN
ImportParts(fileList)
END;
It may be necessary to make the fileList variable a TStringList instead and copy the information there, in case the reference to the IStringList is ended when the Drop event exits, but the general principle is the same - don't process the data in the Drop event, defer it to after the Drop event exits.