Jump to content

Sky Slate Blueberry Blackcurrant Watermelon Strawberry Orange Banana Apple Emerald Chocolate
Photo

Make AHK drop files into other applications


  • Please log in to reply
29 replies to this topic
MasterFocus
  • Moderators
  • 4323 posts
  • Last active: Jan 28 2016 01:38 AM
  • Joined: 08 Apr 2009

I am using Version v1.1.05.04 of AutoHotkey L

Well, I see some DllCalls there...
<!-- m -->http://l.autohotkey....pat.htm#DllCall<!-- m -->

-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

Antonio Fran├ža -- git.io -- github.com -- ahk4.net -- sites.google.com -- ahkscript.org

Member of the AHK community since 08/Apr/2009. Moderator since mid-2012.


RHCP
  • Members
  • 1228 posts
  • Last active: Apr 08 2017 06:17 PM
  • Joined: 29 May 2006

I've updated these functions so they will work with Unicode and Ansi builds. I think I did it correctly, as they're both able to drop a list of multiple files onto microsoft word.

 

Cheers.

DropFiles( FileList, wTitle="", Ctrl="", X=0, Y=0, NCA=0 ) 
{
 characterSize := A_IsUnicode ? 2 : 1
 StringReplace, FileList, FileList, `r`n, `n , All
 VarSetCapacity( DROPFILES,20,32 ),  DROPFILES.=FileList "`n`n",  nSize:=StrLen(DROPFILES)*characterSize
 StringReplace, DROPFILES,DROPFILES, `n,`n, UseErrorLevel
 Loop %ErrorLevel%
	NumPut( 0, DROPFILES, InStr(DROPFILES,"`n",0,0)*characterSize - characterSize, A_IsUnicode ? "Short" : "Char" )

 pDP := &DROPFILES
 NumPut(20, pDP+0)
 NumPut(X, pDP+4)
 NumPut(Y, pDP+8)
 NumPut(NCA, pDP+12)
 NumPut(A_IsUnicode ? 1 : 0, pDP+16)
 hDrop := DllCall( "GlobalAlloc", UInt,0x42, UInt, nSize )
 pData := DllCall( "GlobalLock", UInt, hDrop)
 DllCall( "RtlMoveMemory", UInt,pData, UInt,pDP, UInt, nSize )
 DllCall( "GlobalUnlock", UInt,hDrop )
 PostMessage, 0x233, hDrop, 0, %Ctrl%, %wTitle% ; WM_DROPFILES := 0x233
}
HDrop(fnames,x=0,y=0) 
{
 	characterSize := A_IsUnicode ? 2 : 1
   fns:=RegExReplace(fnames,"\n$")
   fns:=RegExReplace(fns,"^\n")
   hDrop:=DllCall("GlobalAlloc","UInt",0x42,"UInt",20+(StrLen(fns)*characterSize)+characterSize*2)
   p:=DllCall("GlobalLock","UInt",hDrop)
   NumPut(20, p+0)  ;offset
   NumPut(x,  p+4)  ;pt.x
   NumPut(y,  p+8)  ;pt.y
   NumPut(0,  p+12) ;fNC
   NumPut(A_IsUnicode ? 1 : 0,  p+16) ;fWide

   p2:=p+20
   Loop,Parse,fns,`n,`r
   {
      DllCall("RtlMoveMemory","UInt",p2,"Str",A_LoopField,"UInt",StrLen(A_LoopField)*characterSize)
      p2+=StrLen(A_LoopField)*characterSize + characterSize
   }
   DllCall("GlobalUnlock","UInt",hDrop)
   Return hDrop
}

; Definition
struct DROPFILES
{
    DWORD pFiles;    // offset of file list
    POINT pt;        // drop point (client coords)
    BOOL fNC;        // is it on NonClient area and pt is in screen coords
    BOOL fWide;      // wide character flag
};


bichlepa
  • Members
  • 62 posts
  • Last active: Feb 19 2019 08:39 PM
  • Joined: 04 Jul 2011

Thank you verly much! 

The modification of RHCP works fine on Win 8



beeski
  • Members
  • 158 posts
  • Last active: Mar 06 2016 08:21 PM
  • Joined: 22 Sep 2011

i too was able to use this to drop file(s) to an app, but i'd really love to be able to simulate the 'hovering of files to-be-dropped' prior to the drop.

 

the issue is, different applications can take advantage of such move, and treat the dropped files differently based on whether you, say, hover with your mouse (while having the LMB depressed and are in the process of dragging files) onto different controls in the target application.



beeski
  • Members
  • 158 posts
  • Last active: Mar 06 2016 08:21 PM
  • Joined: 22 Sep 2011

.



Zvonko
  • Members
  • 173 posts
  • Last active: Jan 24 2016 05:21 PM
  • Joined: 17 Oct 2014

Hi RHCP & Co!

 

I am trying to apply your HDrop function with multiple files.

 

With one file there is no problem:

 

          PostMessage, 0x233, HDrop("C:\zzzz\Test\zip.pdf"), 0,, ahk_class AutoHotkeyGUI

 

Could somebody show me how to adapt this line for two files, as example?

 

The following doesn't work:

 

          PostMessage, 0x233, HDrop("C:\zzzz\Test\zip.pdf`nC:\zzzz\Test\pdf.pdf"), 0,, ahk_class AutoHotkeyGUI

 

With `n (or `r`n) as delimiter the program opens only the first file.

 

The program itself accepts multiple file drag&drop.

 

Thank you very much in advance.



RHCP
  • Members
  • 1228 posts
  • Last active: Apr 08 2017 06:17 PM
  • Joined: 29 May 2006

Is it an AHK script you wrote?

 

The function appears to work in this basic example (Press f1).

#SingleInstance force

GUI, Add, ListView, y+15 w450 H100, Files
gui, show 
Gui +LastFound
id := WinExist()
return 

GuiDropFiles:
LV_Delete()
Loop, parse, A_GuiEvent, `n, `r
	LV_Add(, A_LoopField)
return 

f1::
files := A_WorkingDir "\dropTestFile1.txt" "`n" A_WorkingDir "\dropTestFile2.txt"
PostMessage, 0x233, HDrop(files), 0,, ahk_id %id%
return 

HDrop(fnames,x=0,y=0) 
{
 	characterSize := A_IsUnicode ? 2 : 1
   fns:=RegExReplace(fnames,"\n$")
   fns:=RegExReplace(fns,"^\n")
   hDrop:=DllCall("GlobalAlloc","UInt",0x42,"UInt",20+(StrLen(fns)*characterSize)+characterSize*2)
   p:=DllCall("GlobalLock","UInt",hDrop)
   NumPut(20, p+0)  ;offset
   NumPut(x,  p+4)  ;pt.x
   NumPut(y,  p+8)  ;pt.y
   NumPut(0,  p+12) ;fNC
   NumPut(A_IsUnicode ? 1 : 0,  p+16) ;fWide

   p2:=p+20
   Loop,Parse,fns,`n,`r
   {
      DllCall("RtlMoveMemory","UInt",p2,"Str",A_LoopField,"UInt",StrLen(A_LoopField)*characterSize)
      p2+=StrLen(A_LoopField)*characterSize + characterSize
   }
   DllCall("GlobalUnlock","UInt",hDrop)
   Return hDrop
}


Zvonko
  • Members
  • 173 posts
  • Last active: Jan 24 2016 05:21 PM
  • Joined: 17 Oct 2014

Thank you very much!

 

Yes, it is an AHK script, but I am very new in this field, as you can see ...

I will analyze your answer and try to understand ...

 

My script at this moment works with one file:

files := "C:\zzzz\Test\zip.zip"

but with two files (see below) only the first file is opened.

 

 
^!t::
 
myprogram = "C:\Butch!!!\!Haupttools\PEM\pemdropper.exe"
 
Run, %myprogram%
 
Sleep, 1000
 
; The program window is: AutoHotkeyGUI.
 
; Open file(s) in the program window:
files := "C:\zzzz\Test\zip.zip" "`n" "C:\zzzz\Test\pdf.pdf"
PostMessage, 0x233, HDrop(files), 0,, ahk_class AutoHotkeyGUI
 
return
 
HDrop(fnames,x=0,y=0) 
{
  characterSize := A_IsUnicode ? 2 : 1
   fns:=RegExReplace(fnames,"\n$")
   fns:=RegExReplace(fns,"^\n")
   hDrop:=DllCall("GlobalAlloc","UInt",0x42,"UInt",20+(StrLen(fns)*characterSize)+characterSize*2)
   p:=DllCall("GlobalLock","UInt",hDrop)
   NumPut(20, p+0)  ;offset
   NumPut(x,  p+4)  ;pt.x
   NumPut(y,  p+8)  ;pt.y
   NumPut(0,  p+12) ;fNC
   NumPut(A_IsUnicode ? 1 : 0,  p+16) ;fWide
 
   p2:=p+20
   Loop,Parse,fns,`n,`r
   {
      DllCall("RtlMoveMemory","UInt",p2,"Str",A_LoopField,"UInt",StrLen(A_LoopField)*characterSize)
      p2+=StrLen(A_LoopField)*characterSize + characterSize
   }
   DllCall("GlobalUnlock","UInt",hDrop)
   Return hDrop
}


RHCP
  • Members
  • 1228 posts
  • Last active: Apr 08 2017 06:17 PM
  • Joined: 29 May 2006

Can you link the AHK program which you are trying to drop the files onto? And what type of AHK are you using (32/64bit and ansi/unicode)? Also, the '<>' icon allows you to post code inside a codebox.



Zvonko
  • Members
  • 173 posts
  • Last active: Jan 24 2016 05:21 PM
  • Joined: 17 Oct 2014

Sorry ...



Zvonko
  • Members
  • 173 posts
  • Last active: Jan 24 2016 05:21 PM
  • Joined: 17 Oct 2014
AutoHotkey v1.1.16.05  |  Unicode 32-bit
 
I am using PEMdropper and PEM (a portable file associator).
 
PEMdropper:
 
PEM:
 
PEM must be in the same folder as PEMdropper.
 
In the pem.ini I have the following file association definition:
[key]
pdf=Butch!!!\Portables\SumatraPDF\SumatraPDF.exe
zip=Butch!!!\Portables\7-ZipPortable\7-ZipPortable.exe
 
I start pemdropper.exe via this batch file:
pemdropper.bat:
cd C:\Butch!!!\!Haupttools\PEM\
start "" pemdropper.exe
 
So my actual AHK script is:
^!t::

myprogram = "C:\Butch!!!\!Haupttools\PEM\pemdropper.bat"
; ^^^ This bat file starts my program pemdropper.exe.

Run, %myprogram%

Sleep, 1000

; The program window is: AutoHotkeyGUI.

; Open file(s) in the program window:
files := "C:\zzzz\Test\zip.zip" "`n" "C:\zzzz\Test\pdf.pdf"
PostMessage, 0x233, HDrop(files), 0,, ahk_class AutoHotkeyGUI

return


Zvonko
  • Members
  • 173 posts
  • Last active: Jan 24 2016 05:21 PM
  • Joined: 17 Oct 2014
 
Please forget my last post(s)!
The specific situation with the programs PEM / PEMdropper is too complicated to be used for tests.
(However PEMdropper is still the program I actually want to use in my project.)
 
I suppose that Notepad is not a suitable program for tests too, because it does not support multiple file DnD.
 
Here is my new testing environment:
Inedita, a simple editor which definitely supports multiple file DnD. 
 
(Portable, no installation, just unpacking!)
 
With this program I could proove that HDrop is working correctly with multiple files!
 
This is my AHK script:
 
^!t::

myprogram = "C:\Butch!!!\Portables\Inedita\inedita.exe"

Run, %myprogram%

Sleep, 1000

; The program window is: Inedita.

; Dropping file(s) into the program window:
files := "C:\zzzz\Test\1.txt" "`r`n" "C:\zzzz\Test\2.txt" "`r`n" "C:\zzzz\Test\eml.eml"  
PostMessage, 0x233, HDrop(files), 0,, ahk_class Inedita

return
 
After this, the question is why some other programs do not work with HDrop, although they support multiple file DnD. 
 
This is the case in my test with SumatraPDF, a PDF viewer:
 
(Portable, no installation, just unpacking!)
 
With SumatraPDF, HDrop does not work even with one file!
 
^!t::

myprogram = "C:\Butch!!!\Portables\SumatraPDF\sumatrapdf.exe"

Run, %myprogram%

Sleep, 1000

; The program window is: SUMATRA_PDF_FRAME

; Dropping file(s) into the program window:
files := "C:\zzzz\Test\pdf.pdf"
PostMessage, 0x233, HDrop(files), 0,, ahk_class SUMATRA_PDF_FRAME

return
 
Do you have an idea what the reason for such a behavior could be?
 
I appreciate your help very much!


RHCP
  • Members
  • 1228 posts
  • Last active: Apr 08 2017 06:17 PM
  • Joined: 29 May 2006

 

With SumatraPDF, HDrop does not work even with one file!
Do you have an idea what the reason for such a behavior could be?
 

 

You need to be wary of which control is being dropped. This will work (supports multiple DnD) with SumatraPDF:

PostMessage, 0x233, HDrop(files), 0, SUMATRA_PDF_CANVAS1, ahk_class SUMATRA_PDF_FRAME

HDrop also has an x and y co-ordinates - the fNC bool value dictates whether this is relative to the window or client area.

 

As for why some programs which support multiple DnD files only see the one file with HDROP...I don't know. I didn't write the function.

What happens if you send a HDrop() for each file instead of one for all of them?

 

Cheers.



Zvonko
  • Members
  • 173 posts
  • Last active: Jan 24 2016 05:21 PM
  • Joined: 17 Oct 2014

RHCP, your information was very helpful to me, thank you very much!

 

I never would be able to find out that SumatraPDF uses a different control for dropping.

I used AU3-Spy.exe to identify the program windows ahk_class name, and there is a 'ClassNN'  quotation which in case of SumatraPDF refers to CANVAS1. Is this the place you found this information?

 

As for why some programs which support multiple DnD files only see the one file with HDROP...I don't know. I didn't write the function.

 

Yes, it is definitely so, there are such programs.

In my case, I am not able to use pemdropper.exe with the HDrop function. If only one file can be processed, I can do the same in a simplier way without HDrop.

 

Thank you again!



beeski
  • Members
  • 158 posts
  • Last active: Mar 06 2016 08:21 PM
  • Joined: 22 Sep 2011

to this day i haven't been able to pull this off successfully.

 

i can achieve simply dropping files into a running application, but i cannot seem to be able to do the advanced take on this, where a user needs to hover over a control in the target app whilst holding the files-to-be-dropped with the left mouse button, and then finish the drop operation with the release of the LMB. i could manually program the mouse clicks and movements but my idea had been to automate this behind-the-scenes using PostMessages...  :S