Ability to make a script be a shell extension DropHandler

I have a common use case where I want to do something to one file with another file.

For instance, right now, I have copied some tiles from one folder to another and renamed them. I'd like to turn the original files into symbolic links with the original file names that point to the new copies. That involves copying the old file's name to the clipboard, then creating a symbolic link with the clipboard-saved name that points to the new file.

A much easier way to do this would be with a script. It would be nice if I could right-click drag the new file onto the old file and simply select, "Replace this file a symbolic link to the dropped file."

To do this, Directory Opus would have to modify some registry entries. The handler should be temporarily added when the macro is active, then removed when finished. (A log of alterations should be kept so it is possible to back out of the modifications gracefully if Directory Opus is terminated of the computer is reset.) I don't know if drop target can be implemented for all files (*), but if not, a handler can be added for specific extensions (possibly overriding an existing handler). The registry changes would be like thus to make, say, .mkv into a drop target:

HKEY_CLASSES_ROOT <no change required>
   .mkv <no change required>
      (Default) = WMP.PlayMedia <no change required>
   CLSID
      {00000000-1111-2222-3333-444444444444} <CLSID of Directory Opus, if doesn't already exist>
         InProcServer32
            (Default) = C:\Program Files\GPSoftware\Directory Opus\drophandler.dll
            ThreadingModel = Apartment
   WMP.PlayMedia
      shellex <possibly added>
         DropHandler <possibly added>
            (Default) = {00000000-1111-2222-3333-444444444444} <possibly replaced>

Now the drophandler.dll has to handle IUnknown, IPersistFile, IDropTarget.

See https://docs.microsoft.com/en-us/previous-versions/windows/desktop/legacy/cc144165(v=vs.85)

When a file is dropped on the .mkv, the .dll will be called, and directory opus can pass both the dropped and dropped-on files to the script in question. The script can this delete/rename/move/whatever based on the two incoming files.

Alternatively, this functionality could be implemented as a lister-only capability and not involve the registry at all. In that case, the drag-drop->script functionality would only work within the lister windows.

BTW, what I do right now is to select the file I want to "drop on to" in one pane, then I drag and drop he source file into that pane and create a Drag-and-drop Event script function for the file type. Although it doesn't drop "on the file", I can still retrieve the file that was selected in the dropped pane. It's not as neat, because I have to click the destination file first, but it does work.

Unfortunately, the method falls down if the files I want to replace are in many different folders. In this case, I'd like to be able to search for the files of interest and drop directly onto them in the search results list... but I can't, because you can't drop onto search results because dropping only works onto folders. I have to resort to visiting each folder separately to do the job, which is no fun.

Here's the script:

Function OnClick(ByRef clickData)
Dim data
Set data = ClickData.func

if data.desttab.stats.selfiles <> 1 then
   msgbox "You should only have one file selected in the destination window."
   return
end if
if data.sourcetab.stats.selfiles <> 1 then
   msgbox "You should only drop one file."
   return
end if

Set dlg = data.Dlg 
' Initialise the object to display a simple message with three buttons.
dlg.window = DOpus.Listers(0)
dlg.message = "Verify that you want to replace"+vbCrLf+vbCrLf+_
		data.desttab.selected_files(0).path+"\"+vbCrLf+_
   		data.desttab.selected_files(0).name+vbCrLf+vbCrLf+_
		 +" with "+vbCrLf+vbCrLf+_
		data.sourcetab.selected_files(0).path+"\"+vbCrLf+_
		data.sourcetab.selected_files(0).name+vbCrLf
dlg.title = "The destination file will be deleted!"
dlg.buttons = "Replace the file|Cancel"
' Show the dialog and print the result to the script log
ret=dlg.show()
if ret = 0 then exit function

name=data.desttab.selected_files(0).name

Set cmd = data.command
cmd.Clear()
cmd.ClearFiles()
cmd.AddFile (data.desttab.selected_files(0))
cmd.RunCommand ("Delete QUIET")

cmd.Clear()
cmd.ClearFiles()
cmd.AddFile (data.sourcetab.selected_files(0))
cmd.RunCommand ("Copy MAKELINK=softlink AS """ + name + """" )

End Function

Putting the copying, renaming, and linking into a single button is not an option?

If I was doing this, I would probably put the script on a hotkey and make it use the left and right folders. (Instead of source and dest folders. That way you don't have to worry about which order you click things; just keep one type of file on the left and the other on the right.)

With that, you could select the two files you want and then push the hotkey, which should let you go through each pair as quickly as drag & drop from one file to the other.