Did explorer cut or copy?

Get help with using AutoHotkey (v1.1 and older) and its commands and hotkeys
zcooler
Posts: 455
Joined: 11 Jan 2014, 04:59

Did explorer cut or copy?

19 Mar 2015, 11:59

Hi!

Im transferring files/folders from the explorer to a treeview gui either via "cut" or "copy" through the Clipboard. Of course I know it, but the gui script has no way of knowing if explorer "cut" was carried out which in that case should move the files FileMove or explorer "copy" which only should copy/paste the files FileCopy. How can I make the gui script aware about the explorer context menu actions? I wonder if anyone can point me to a solution or has information about this area of interest?

/zcooler
zcooler
Posts: 455
Joined: 11 Jan 2014, 04:59

Re: Did explorer cut or copy?

20 Mar 2015, 14:31

I was hoping on something in reverse to Lexikos FileToClipboard function. That function writes the preferred DropEffect structure to clipboard to switch between copy/cut operations if move/copy files from a gui to the explorer. If a script can write the correct structure to clipboard it should also be abled to read the structure in the binary data in order to work out if it's coming from an explorer copy or cut operation. Yes?
http://www.autohotkey.com/board/topic/2 ... ard/page-3

Code: Select all

FileToClipboard(PathToCopy, Method="copy")
   {
   FileCount:=0
   PathLength:=0

   ; Count files and total string length
   Loop,Parse,PathToCopy,`n,`r
      {
      FileCount++
      PathLength+=StrLen(A_LoopField)
      }

   pid:=DllCall("GetCurrentProcessId","uint")
   hwnd:=WinExist("ahk_pid " . pid)
   ; 0x42 = GMEM_MOVEABLE(0x2) | GMEM_ZEROINIT(0x40)
   hPath := DllCall("GlobalAlloc","uint",0x42,"uint",20 + (PathLength + FileCount + 1) * 2,"UPtr")
   pPath := DllCall("GlobalLock","UPtr",hPath)
   NumPut(20,pPath+0),pPath += 16 ; DROPFILES.pFiles = offset of file list
   NumPut(1,pPath+0),pPath += 4 ; fWide = 0 -->ANSI,fWide = 1 -->Unicode
   Offset:=0
   Loop,Parse,PathToCopy,`n,`r ; Rows are delimited by linefeeds (`r`n).
      offset += StrPut(A_LoopField,pPath+offset,StrLen(A_LoopField)+1,"UTF-16") * 2

   DllCall("GlobalUnlock","UPtr",hPath)
   DllCall("OpenClipboard","UPtr",hwnd)
   DllCall("EmptyClipboard")
   DllCall("SetClipboardData","uint",0xF,"UPtr",hPath) ; 0xF = CF_HDROP

   ; Write Preferred DropEffect structure to clipboard to switch between copy/cut operations
   ; 0x42 = GMEM_MOVEABLE(0x2) | GMEM_ZEROINIT(0x40)
   mem := DllCall("GlobalAlloc","uint",0x42,"uint",4,"UPtr")
   str := DllCall("GlobalLock","UPtr",mem)

   if (Method="copy")
      DllCall("RtlFillMemory","UPtr",str,"uint",1,"UChar",0x05)
   else if (Method="cut")
      DllCall("RtlFillMemory","UPtr",str,"uint",1,"UChar",0x02)
   else
      {
      DllCall("CloseClipboard")
      return
      }

   DllCall("GlobalUnlock","UPtr",mem)

   cfFormat := DllCall("RegisterClipboardFormat","Str","Preferred DropEffect")
   DllCall("SetClipboardData","uint",cfFormat,"UPtr",mem)
   DllCall("CloseClipboard")
   return
}

I can of course use a clunky workaround having two paste context menu items. One for paste/move and one for paste/copy, but what's the fun in that!?
lexikos
Posts: 9635
Joined: 30 Sep 2013, 04:07
Contact:

Re: Did explorer cut or copy?

21 Mar 2015, 00:19

You can probably use WinClip to retrieve the Preferred DropEffect.
just me
Posts: 9528
Joined: 02 Oct 2013, 08:51
Location: Germany

Re: Did explorer cut or copy?

21 Mar 2015, 04:36

zcooler wrote: If a script can write the correct structure to clipboard it should also be abled to read the structure in the binary data in order to work out if it's coming from an explorer copy or cut operation. Yes?
Yes! ;)

Code: Select all

ClipboardGetDropEffect() {
   Static PreferredDropEffect := DllCall("RegisterClipboardFormat", "Str" , "Preferred DropEffect")
   DropEffect := 0
   If DllCall("IsClipboardFormatAvailable", "UInt", PreferredDropEffect) {
      If DllCall("OpenClipboard", "Ptr", 0) {
         hDropEffect := DllCall("GetClipboardData", "UInt", PreferredDropEffect, "UPtr")
         pDropEffect := DllCall("GlobalLock", "Ptr", hDropEffect, "UPtr")
         DropEffect := NumGet(pDropEffect + 0, 0, "UChar")
         DllCall("GlobalUnlock", "Ptr", hDropEffect)
         DllCall("CloseClipboard")
      }
   }
   Return DropEffect
}
zcooler
Posts: 455
Joined: 11 Jan 2014, 04:59

Re: Did explorer cut or copy?

21 Mar 2015, 05:13

Yiihaa, that's it :dance:
You are an absolute gem to this forum, just me :D
Days of searching and headscratching is finally over.
Many many thanks
from
zcooler
tmplinshi
Posts: 1604
Joined: 01 Oct 2013, 14:57

Re: Did explorer cut or copy?

21 Mar 2015, 06:11

thx just me!

Code: Select all

#Persistent
OnClipboardChange:
	If (A_EventInfo = 1) && ( v:=ClipboardGetDropEffect() )
		MsgBox, % (v=5) ? "Copy" : "Cut" ; Copy=5, Cut=2
Return

ClipboardGetDropEffect() {
   Static PreferredDropEffect := DllCall("RegisterClipboardFormat", "Str" , "Preferred DropEffect")
   DropEffect := 0
   If DllCall("IsClipboardFormatAvailable", "UInt", PreferredDropEffect) {
      If DllCall("OpenClipboard", "Ptr", 0) {
         hDropEffect := DllCall("GetClipboardData", "UInt", PreferredDropEffect, "UPtr")
         pDropEffect := DllCall("GlobalLock", "Ptr", hDropEffect, "UPtr")
         DropEffect := NumGet(pDropEffect + 0, 0, "UChar")
         DllCall("GlobalUnlock", "Ptr", hDropEffect)
         DllCall("CloseClipboard")
      }
   }
   Return DropEffect
}

Return to “Ask for Help (v1)”

Who is online

Users browsing this forum: Bing [Bot], Rohwedder and 88 guests