by Richard Russell, June 2010
The article Opening a file by dropping or clicking describes how you can handle a file which is dragged-and-dropped onto your program's icon. Another way of receiving files is as a result of the user dropping them onto your program's window rather than onto its icon. This article describes how to do that.
Firstly some initialisation is required:
WM_DROPFILES = &233 *SYS 1 MaxDroppedFiles% = 100 DIM DroppedFile$(MaxDroppedFiles%-1), DroppedAt{x%,y%} Dropped% = 0 ON SYS PROCsys(@msg%, @wparam%, @lparam%) : RETURN SYS "DragAcceptFiles", @hwnd%, 1
Once this code has been executed, a file (or files) being dropped onto your program's window will result in an ON SYS interrupt with the @msg% value being WM_DROPFILES.
In your 'main loop' you will want to monitor the value of Dropped% to determine whether any files have been dropped onto your window. If one or more files has been dropped, you can discover the filenames from the array DroppedFile$(). If you need to know where the files were dropped (for example your program performs a different action as a result) the coordinates DroppedAt.x% and DroppedAt.y% are in pixels measured from the top-left corner of your window. Here is a simple example of the kind of code needed:
REPEAT WAIT 1 IF Dropped% THEN PRINT "Number of files dropped = ";Dropped% FOR I% = 0 TO Dropped%-1 IF I% >= MaxDroppedFiles% THEN EXIT FOR PRINT "File ";I%;" is """ DroppedFile$(I%) """" NEXT I% PRINT "The files were dropped at x=";DroppedAt.x%;", y=";DroppedAt.y% Dropped% = 0 ENDIF UNTIL FALSE END
Here the information about the dropped files is simply printed to the screen, but in practice you are likely to want to do something different!
Finally, here is the ON SYS handler for processing the WM_DROPFILES message:
DEF PROCsys(M%,W%,L%) CASE M% OF WHEN WM_DROPFILES: LOCAL B%, I% DIM B% LOCAL 260 SYS "DragQueryFile", W%, -1, 0, 0 TO Dropped% IF Dropped% <> 0 THEN FOR I% = 0 TO Dropped%-1 IF I% >= MaxDroppedFiles% THEN EXIT FOR SYS "DragQueryFile", W%, I%, B%, 260 DroppedFile$(I%) = $$B% NEXT I% ENDIF SYS "DragQueryPoint", W%, DroppedAt{} SYS "DragFinish", W% ENDCASE ENDPROC
Needless to say, if there are other ON SYS interrupts that need to be handled by your program (e.g. menu selections, button clicks etc.) then you must add the necessary code to this handler (probably in a WHEN WM_COMMAND: clause).