topbanner_forum
  *

avatar image

Welcome, Guest. Please login or register.
Did you miss your activation email?

Login with username, password and session length
  • October 23, 2019, 04:49 AM
  • Proudly celebrating 13 years online.
  • Donate now to become a lifetime supporting member of the site and get a non-expiring license key for all of our programs.
  • donate

Show Posts

This section allows you to view all posts made by this member. Note that you can only see posts made in areas you currently have access to.


Messages - lifeweaver [ switch to compact view ]

Pages: [1]
1
Skrommel's Software / MultiMonMan - How to support 3 monitors
« on: February 06, 2016, 09:18 AM »
If anyone tried to use MultiMonMan with 3 monitors and it didn't work, try adding:
x := x > 0 ? x : 0
before the line
Gui,%monitor%:Show,x%x% y%y% w%w% h-1,%monitor% - %applicationname%

I can't say this will fix everyones problem, but it fixed mine, somehow 'x' wasn't set so the line sets 'x' to zero if it's not greater than zero.

2
Can you do web development in LOLCODE?

A minimal HTTP server written in LOLCODE by justinmeza

OBTW
    httpd.lol -- a minimal HTTP server written in LOLCODE
    example:
        ./lci httpd.lol
        point your favorite HTTP-getter to http://127.0.0.1:13337/lol.html
        ...
        profit?
    by Justin J. Meza, 2014
TLDR
HAI 1.4
    CAN HAS STDIO?
    CAN HAS SOCKS?
    CAN HAS STRING?

    HOW IZ I parse YR header
        I HAS A len ITZ I IZ STRING'Z LEN YR header MKAY
        I HAS A readin ITZ FAIL
        I HAS A file ITZ ""
        IM IN YR loop UPPIN YR index TIL BOTH SAEM index AN len
            I HAS A char ITZ I IZ STRING'Z AT YR header AN YR index MKAY
            BOTH OF BOTH SAEM char AN " " AN readin
            O RLY?
                YA RLY, FOUND YR file
            OIC
            readin, O RLY?, YA RLY, file R SMOOSH file AN char MKAY, OIC
            BOTH OF BOTH SAEM char AN "/" AN NOT readin
            O RLY?
                YA RLY, readin R WIN
            OIC
        IM OUTTA YR loop
        FOUND YR ""
    IF U SAY SO

    BTW bind to a local port
    I HAS A sock
    sock R I IZ SOCKS'Z BIND YR "127.0.0.1" AN YR 13337 MKAY

    IM IN YR loop
        BTW receive a connection
        I HAS A conn
        conn R I IZ SOCKS'Z LISTN YR sock MKAY

        BTW get a command
        I HAS A cmd
        cmd R I IZ SOCKS'Z GET YR sock AN YR conn AN YR 1024 MKAY
        VISIBLE "CMD IZ " AN cmd

        BTW parse the file name
        I HAS A name ITZ I IZ parse YR cmd MKAY
        VISIBLE "FIEL IZ " AN name

        I HAS A reply ITZ ""

        BTW get the file contents
        I HAS A file ITZ I IZ STDIO'Z OPEN YR name AN YR "r" MKAY
        I IZ STDIO'Z DIAF YR file MKAY, O RLY?
        YA RLY
            VISIBLE "FIEL NOT FOUND"
            reply R "HTTP/1.1 404 Not Found:3:):3:)"
        NO WAI
            VISIBLE "FIEL FOUND!"
            I HAS A data ITZ I IZ STDIO'Z LUK YR file AN YR 1024 MKAY
            I HAS A len ITZ I IZ STRING'Z LEN YR data MKAY
            I IZ STDIO'Z CLOSE YR file MKAY
            VISIBLE "LEN IZ " AN len
            VISIBLE "DATA IZ " AN data

            reply R SMOOSH "HTTP/1.1 200 OK:3:)"...
                    AN "Server: httpd.lol/0.1 (lci):3:)"...
                    AN "Context-Type: text/html:3:)"...
                    AN "Content-Length: :{len}:3:):3:)"...
                    AN ":{data}:3:)" MKAY
        OIC

BTW serve it up
VISIBLE "REPLY IZ " AN reply
I IZ SOCKS'Z PUT YR sock AND YR conn AN YR reply MKAY

        BTW buh-bye
        I IZ SOCKS'Z CLOSE YR conn MKAY
    IM OUTTA YR loop
KTHXBYE

3
Here is a script for you written in AutoHotkey.

looks like you forgot to attach the script ;)

Indeed I intended to post the code but alas it was too long.
I've now attached the script to the post.

4
Hi superboyac,

Here is a script for you written in AutoHotkey.

Script runs on: Windows 7 Professional, AutoHotkey 1.1.22.07 Unicode build

To use:

  •     Install AutoHotkey, if you have problems see their tutorial about running scripts
  •     Copy the script into a '.ahk' file
  •     Double click on the script icon to start it

Note: It is possible to compile AutoHotkey scripts to exe so you don't need to have AutoHotkey installed.

5
Supberboyac,

saving/importing/exporting customized sets would be perfect
Can you elaborate?
J River stores your custom shortcuts in a JRiver-Resource.xml file, so you have them in a format you can read outside the application, do you mean export from J River to foobar or foobar to J River?

6
Hi superboyac,

I know it's not what you are asking for but thought you might find it interesting => using AutoHotkey as the hotkeys for JRiver.

7
Post New Requests Here / Re: IDEA: Drop Zone for Web Images
« on: October 12, 2015, 01:47 PM »
Thanks!

8
Post New Requests Here / Re: IDEA: Drop Zone for Web Images
« on: October 12, 2015, 01:12 PM »
Just modified it, I think there is a limit to how much text can be posted in one post as the preview looked correct but it kept cutting off some.

9
Post New Requests Here / Re: IDEA: Drop Zone for Web Images
« on: October 12, 2015, 01:03 PM »
That is much better.

There seems to have been a change that has crept in, in that the filetype is now JPG it was jpg

Also the default datestamp, has Minutes omitted ;)

It may also need an error trap.
If you create a second event but don't change anything from the default it will throw an Invalid Option. This then cause a problem when you try to return to the config with a further error Invalid Gui name, and again on exiting.

I can use it with Firefox for what I need, but will  look at IE11 again and the security issue when I get a chance

Not sure about this one, I'm able to download .jpg and they stay .jpg, can you check the actual image on the website and verify it isn't named .JPG?
I added some error checking, and fixed the cause of the error popup.

I've changed the default dateFormat, the original post didn't specify minutes. => 'PREFIX YYYY-MM-DD_HH-SS SUFFIX'
Reminder: you'll have to update the timeFormat for all your created dropZone.

; -------------------------------------------------- Auto Execute --------------------------------------------------
#Persistent
#NoEnv  ; Recommended for performance and compatibility with future AutoHotkey releases.
SetWorkingDir %A_ScriptDir%  ; Ensures a consistent starting directory.
#SingleInstance force
SetBatchLines, -1
SetKeyDelay, -1
title := "Web Images Drop Zone"

iniPath := A_ScriptDir . "\WIDZ.data"


Menu, Tray, NoStandard
Menu, Tray, Add, &Config, Show
Menu, Tray, Default, &Config
Menu, Tray, Add, &Toggle DropZones, toggleDropZones
Menu, Tray, Add, E&xit, Exit
Menu, Tray, Click, 1
Menu, Tray, Tip, %title%
LoadSettings(iniPath)

if(firstTimeOpenShowConfig)
{
  firstTimeOpenShowConfig := false
  gosub, show
  WinWaitClose, %title% - Config
}

dropZoneGuis := CreateDropZoneGuis(iniPath)
OnExit("Exit")
return

; -------------------------------------------------- Labels --------------------------------------------------
createOrUpdateDropZone:
  ; Get dropZone info info
  GuiControlGet, dropZone,, dropZone
  GuiControlGet, timeFormat,, timeFormat
  GuiControlGet, fileDrop,, fileDrop
  GuiControlGet, icon,, icon
  GuiControlGet, pos, %pos%
  GuiControlGet, prefix,, prefix
  GuiControlGet, suffix,, suffix
 
  ; Error handling
  response := ValidateFields(dropZone, prefix, suffix, pos, fileDrop, icon, timeFormat)
  if(response != "")
  {
    msgbox invalid field(s): %response%
    return
  }
 
  ; Check if the dropZone already exists
  Loop % LV_GetCount()
  {
    Lv_GetText(dropZoneName, A_index)
    if(dropZoneName = dropZone)
    {
      LV_Modify(A_Index,,dropZone, prefix, suffix, pos, fileDrop, icon, timeFormat)
      return
    }
  }
 
  LV_Add(,dropZone, prefix, suffix, pos, fileDrop, icon, timeFormat)
return

drawDropWindow:
  ;http://www.autohotkey.com/board/topic/111196-drawing-boxes-on-screen-need-help-finishing/?p=655416
  GuID := "dropzone"
  LetUserSelectRect(GuiID, x1, y1, x2, y2)
  lastDropWindowPos := x1 . ":" . x2 . ":" . y1 . ":" . y2
  GuiControl,, pos, %lastDropWindowPos%

  Loop 4
    Gui, % GuiID A_Index ": Destroy"
return

dropZoneList:
  ; populate fields on a double click
  if(A_GuiEvent = "Normal")
    CopyDropZoneToForm(A_EventInfo)
  else if(A_GuiEvent = "RightClick")
    DeleteDropZoneData(A_EventInfo)
return

Exit:
  IfWinExist, %title% - Config
    SaveData(iniPath)
  ExitApp
return

fileDrop:
  FileSelectFolder, fileDrop,,, Select file folder
  if(fileDrop)
    GuiControl, , fileDrop, %fileDrop%
  else
    msgbox your folder wasn't found please select a valid folder, i.e. no the virtual ones like Libraries/Documents/Music/etc
return

icon:
  FileSelectFile, icon, 3, %A_MyDocuments%,Choose an Icon, Image files (*.jpg; *.jpeg; *.gif; *.png)
  GuiControl, , icon, %icon%
return

show:
  DeleteAllDropZones(dropZoneGuis)
  Gui, WebImageDropZoneConfig: New, hwndWIDZ, Web Image Drop Zone
  global WIDZ
  Gui, Add, ListView, x12 y10 w450 r15 gdropZoneList AltSubmit, DropZone|Prefix|Suffix|Pos|Save Path|Icon|TimeFormat
  Gui, Add, Text, x12 y300 w60 h20 , DropZone:
  Gui, Add, Edit, x72 y300 w90 h20 vdropZone , dropzone
  Gui, Add, Text, x172 y300 w60 h20 , TimeFormat:
  Gui, Add, Edit, x232 y300 w230 h20 vtimeFormat , yyyy-MM-dd_hh-mm-ss
 
  Gui, font, s11 bold, MS sans serif
  Gui, Add, Link, x462 y300 w10 h20 , <a href="http://www.autohotkey.com/docs/commands/FormatTime.htm">?</a>
  gui, font
 
  Gui, Add, Text, x12 y330 w50 h20 , File Drop:
  Gui, Add, Edit, x72 y330 w320 h20 vfileDrop , file drop
  Gui, Add, Button, x392 y330 w70 h20 gfileDrop , Browse
 
  Gui, Add, Text, x12 y360 w40 h20 , Icon:
  Gui, Add, Edit, x72 y360 w320 h20 vicon, Edit
  Gui, Add, Button, x392 y360 w70 h20 gicon , Browse
 
  Gui, Add, Text, x12 y390 w40 h20 , Prefix:
  Gui, Add, Edit, x72 y390 w110 h20 vprefix , prefix
  Gui, Add, Text, x192 y390 w40 h20 , Suffix:
  Gui, Add, Edit, x232 y390 w110 h20 vsuffix , suffix
  Gui, Add, Button, x12 y420 w110 h20 gdrawDropWindow, DropZone Position
  Gui, Add, Edit, x132 y420 w210 h20 ReadOnly vpos , 0:100:0:100
  Gui, Add, Button, x352 y390 w110 h50 gcreateOrUpdateDropZone , Create/Update
 
  ; Generated using SmartGUI Creator 4.0
  Gui, Show, x138 y90 h450 w479, %title% - Config
  PopulateDropZoneList(iniPath)
  OnMessage(0x200, "GuiToolTip")
  Loop 6
      LV_ModifyCol(A_Index, "AutoHdr")
 
return

toggleDropZones:
for index, array in dropZoneGuis
{
  hwnd := array["hwnd"]
 
  if WinExist("ahk_id " . hwnd)
    gui, %hwnd%:Hide
  else
    gui, %hwnd%:Show
}
return

WebImageDropZoneConfigGuiClose:
WebImageDropZoneConfigGuiEscape:
  IfWinExist, %title% - Config
    SaveData(iniPath)
  Gui, WebImageDropZoneConfig:Destroy
 
  ; Update the dropzones
  dropZoneGuis := CreateDropZoneGuis(iniPath)
return



; -------------------------------------------------- Methods --------------------------------------------------
CopyDropZoneToForm(eventInfo)
{
  global lastDropWindowPos
  ; get row text
  LV_GetText(dropZone, eventInfo, 1)
  LV_GetText(prefix, eventInfo, 2)
  LV_GetText(suffix, eventInfo, 3)
  LV_GetText(pos, eventInfo, 4)
  LV_GetText(fileDrop, eventInfo, 5)
  LV_GetText(icon, eventInfo, 6)
  LV_GetText(TimeFormat, eventInfo, 7)
 
  ; update fields
  GuiControl,, dropZone, %dropZone%
  GuiControl,, prefix, %prefix%
  GuiControl,, suffix, %suffix%
  GuiControl,, pos, %pos%
  lastDropWindowPos := pos
  GuiControl,, fileDrop, %fileDrop%
  GuiControl,, icon, %icon%
  GuiControl,, TimeFormat, %TimeFormat%
}

CreateDropZoneGuis(path)
{
  dropZoneGuis := Array()
  dropZoneData := LoadData(path)
 
  for index, array in dropZoneData
  {
    extractedPos := StrSplit(array["pos"], ":")
    guiHwnd := DropZoneGui(array["dropZone"], array["icon"], extractedPos[1], extractedPos[2], extractedPos[3], extractedPos[4])
    IDT_WIDZ := IDropTarget_Create(guiHwnd, "_WIDZ", [1, 13, 15]) ; CF_TEXT, CF_UNICODETEXT, CF_HDROP
    dropZoneGuis.insert({dropZone: array["dropZone"], hwnd: guiHwnd, iDropTarget: IDT_WIDZ})
  }

  return dropZoneGuis
}

; Custom message box for the confirm dropzone delete.
Custom_MsgBox(msg_text)
{
  global showCancelConfirm, dontShowAgain
  Gui, CustomMsgBox: New, hwndCMB
  Gui, Add, Text, x12 y10 w430 h70, %msg_text%
  Gui, Add, CheckBox, x12 y90 w140 h30 vdontShowAgain , Don't show this again?
  Gui, Add, Button, x232 y90 w100 h30 gCustomMsgBoxGuiSubmit , OK
  Gui, Add, Button, x342 y90 w100 h30 gCustomMsgBoxGuiSubmit Default , Cancel
  ; Generated using SmartGUI Creator 4.0
  Gui, Show
  WinWaitClose, ahk_id %CMB%
  return buttonClicked
 
  CustomMsgBoxGuiSubmit:
    GuiControlGet, dontShowAgainChecked,, dontShowAgain
    if(dontShowAgainChecked)
      showCancelConfirm := false
   
    buttonClicked := A_GuiControl
    gosub, CustomMsgBoxGuiClose
  return

  CustomMsgBoxGuiClose:
  CustomMsgBoxGuiEscape:
  Gui, CustomMsgBox:Destroy
  return
}

DeleteDropZoneData(eventInfo)
{
  global showCancelConfirm
 
  Gui, WebImageDropZoneConfig:Default
  LV_GetText(thisDropZone, eventInfo)
 
  if(showCancelConfirm)
  {
    if(Custom_MsgBox("Are you sure you want to delete the '" . thisDropZone . "' drop zone?") = "OK")
    {
      Gui, WebImageDropZoneConfig:Default
      LV_Delete(eventInfo)
    }
  }
  else
    LV_Delete(eventInfo)
}

DeleteAllDropZones(dropZoneGuis)
{
  ; dropZone, hwnd, iDropTarget
  for index, array in dropZoneGuis
  {
    ;~ Revoke the registration of the ListView as a potential target for OLE drag-and-drop operations.
    array["iDropTarget"].RevokeDragDrop()
    hwnd := array["hwnd"]
    if(WinExist("ahk_id " . hwnd))
      Gui, %hwnd%:Destroy
  }
}

determineRealURL(url)
{
  origUrl := url
  if(InStr(url, "google.com"))
    RegExMatch(url, "(?<=\?imgurl=).*?(?=&)", url)
 
  ;~ msgbox % "url: " url "`n`norigUrl: " origUrl
  return url
}

downloadFile(origUrl, foundUrl, dropZoneInfo, targetHwnd)
{
  SplitPath, foundUrl,,, imageFileExt
  fileDropDir := dropZoneInfo["fileDrop"]
  prefix := dropZoneInfo["prefix"]
  suffix := dropZoneInfo["suffix"]
  timeFormat := dropZoneInfo["timeFormat"]
  FormatTime, nowTime,, % timeFormat

  ; Per request removed the fileName check
  ;~ Inputbox, fileName, File Name Entry, Please Enter a file name. (no extension),,,,,,,, %prefix% %nowTime% %suffix%
  ;~ if(fileName = "")
  fileName :=  prefix . " " . nowTime . " " . suffix
  fileName := Trim(fileName)
 
 
  ; Only try to download the file if its a jpg, otherwise create a link
  if(RegExMatch(foundUrl, "\.\w{3,4}$"))
  {
    try
    {
      saveLocation := fileDropDir . "\" . fileName . "." . imageFileExt
      URLDownloadToFile, %foundUrl%, %saveLocation%
      if(ErrorLevel)
        return "Unable to download '" . foundUrl . "' parsed from '" . origUrl . "'" . "`n`nfileDropDir: " . fileDropDir . "`nfileName: " . fileName . "`next: " . imageFileExt
     
      NotificationPopup(saveLocation, targetHwnd)
      return true
    }
    catch, e
    {
      msgbox % "ErrorLevel: " ErrorLevel "`nA_LastError: " A_LastError "`nmessage: " e.message "`nWhat: " e.what "`nExtra: " e.extra "`nLine: " e.line
      return "Unable to download '" . foundUrl . "' parsed from '" . origUrl . "'" . "`n`nfileDropDir: " . fileDropDir . "`nfileName: " . fileName . "`next: " . imageFileExt
    }
  }
  else
  {
    FileCreateShortcut, %foundUrl%, %fileDropDir%\%fileName%.lnk
    TrayTip, Link Created, Couldn't find image so a link was created instead., 15
    return true
  }
}

DropFile(dropZoneGuis, targetHwnd, url)
{
  dropZoneInfo := findDropZoneInfo(dropZoneGuis, targetHwnd)
  foundUrl := determineRealURL(url)
 
  return downloadFile(url, foundUrl, dropZoneInfo, targetHwnd)
}

; Called to create/display dropZone gui
DropZoneGui(label, icon, x1, x2, y1, y2)
{
  static index = 0
  index += 1
 
  ; If no pos data was provided
  if(!x1)
  {
    x1 := 0
    x2 := 100
    y1 := 0
    y2 := 100
  }
 
  width := x2 - x1
  height := y2 - y1
  labelWidth := StrLen(label) * 25
  labelHeight := 32
 
  ; If the label is too long we set the labelsPerRow to 1 otherwise nothing would be displayed
  labelsPerColumn := height / labelHeight < 1 ? 1 : height / labelHeight
  labelsPerRow := width / labelWidth < 1 ? 1 : width / labelWidth

  CustomColor = EEAA99  ; Can be any RGB color (it will be made transparent below).
  Gui, New, hwndDZG%index% +LastFound +AlwaysOnTop -Caption +ToolWindow ; +ToolWindow avoids a taskbar button and an alt-tab menu item.
  Gui, Color, %CustomColor%
 
  ; If an icon was provided make it the size of the gui else use the label text
  if(icon && FileExist(icon))
    Gui, Add, Picture, w%width% h%height%, %icon%
  else
  {
    Gui, Font, s32  ; Set a large font size (32-point).
    x := 0
   
    Loop %labelsPerRow%
    {
      y := 0
      Loop %labelsPerColumn%
      {
        Gui, Add, Text, % "x" x " y" y " cLime", %label%
        y += 50
      }
      x += labelWidth
    }
  }
  ; Make all pixels of this color transparent and make the text itself translucent (150):
  WinSet, TransColor, %CustomColor% 150
  Gui, Show, x%x1% y%y1% w%width% h%height% NoActivate  ; NoActivate avoids deactivating the currently active window.
  return DZG%index%
}

Exit(ExitReason, ExitCode)
{
  global dropZoneGuis, iniPath
 
  IfWinExist, %title% - Config
    SaveData(iniPath)

  DeleteAllDropZones(dropZoneGuis)
  ExitApp
}

findDropZoneInfo(dropZoneGuis, targetHwnd)
{
  global iniPath
 
  data := LoadData(iniPath)
  for index, array in dropZoneGuis
    if(array["hwnd"] = targetHwnd)
      for dindex, darray in data
        if(darray["dropZone"] = array["dropZone"])
          return darray
}

GuiToolTip(wParam, lParam, Msg)
{
  MouseGetPos,,,mhwnd, OutputVarControl
 
  if(OutputVarControl = "Button3" && mhwnd = WIDZ)
Help := "After pressing 'Dropzone Position' move your mouse to the desired location; hold down the mouse button then move the mouse to select your area."
  else
    Help := ""

  ToolTip % Help
}

LetUserSelectRect(ByRef ID, ByRef X1, ByRef Y1, ByRef X2, ByRef Y2)
{ ;http://www.autohotkey.com/board/topic/111196-drawing-boxes-on-screen-need-help-finishing/?p=655416
    CoordMode, Mouse ; Required: change coord mode to screen vs relative.
    static r := 3
    ; Create the "selection rectangle" GUIs (one for each edge).
    Loop 4 {
        Gui, % ID A_Index ": -Caption +ToolWindow +AlwaysOnTop"
        Gui, % ID A_Index ": Color", Red
    }
    ; Disable LButton.
    Hotkey, *LButton, lusr_return, On
    ; Wait for user to press LButton.
    KeyWait, LButton, D
    ; Get initial coordinates.
    MouseGetPos, xorigin, yorigin
    ; Set timer for updating the selection rectangle.
    SetTimer, lusr_update, 10
    ; Wait for user to release LButton.
    KeyWait, LButton
    ; Re-enable LButton.
    Hotkey, *LButton, Off
    ; Disable timer.
    SetTimer, lusr_update, Off
    return
 
    lusr_update:
        CoordMode, Mouse ; Required: change coord mode to screen vs relative.
        MouseGetPos, x, y
        if (x = xlast && y = ylast)
            ; Mouse hasn't moved so there's nothing to do.
            return
        if (x < xorigin)
             x1 := x, x2 := xorigin
        else x2 := x, x1 := xorigin
        if (y < yorigin)
             y1 := y, y2 := yorigin
        else y2 := y, y1 := yorigin
        ; Update the "selection rectangle".
        Gui, % ID "1:Show", % "NA X" x1 " Y" y1 " W" x2-x1 " H" r
        Gui, % ID "2:Show", % "NA X" x1 " Y" y2-r " W" x2-x1 " H" r
        Gui, % ID "3:Show", % "NA X" x1 " Y" y1 " W" r " H" y2-y1
        Gui, % ID "4:Show", % "NA X" x2-r " Y" y1 " W" r " H" y2-y1
    lusr_return:
    return
}

;~ LV_Add(, array[1], array[2], array[3], array[4], array[5], array[6], array[7])
LoadData(path)
{
  FileRead, data, %path%
  dataArray := Object()
 
  Loop, Parse, data, `n, `r`n
  {
    ; If not the setttings row
    if(A_Index != 1)
    {
      array := StrSplit(A_LoopField, "|")
      if(array[1])
      {
        dataArray.Insert({dropZone: array[1], prefix: array[2], suffix: array[3], pos: array[4], fileDrop: array[5], icon: array[6], timeFormat: array[7]})
      }
    }
  }
 
  return dataArray
}

LoadSettings(path)
{
  global showCancelConfirm, firstTimeOpenShowConfig
 
  FileReadLine, data, %path%, 1
 
  array := StrSplit(data, "|")
  firstTimeOpenShowConfig := array[1] = 0 ? false : true
  showCancelConfirm := array[2] = 0 ? false : true
}

NotificationPopup(saveLocation, targetHwnd)
{
  static index = 0
  static hwnd := Array()
 
  index += 1
  Gui, New, hwndNewConformation%index% +LastFound +AlwaysOnTop -Caption +ToolWindow
  Gui, Add, Text,, Success! - %saveLocation%
  WinGetPos, xpos, ypos, w, h, ahk_id %targetHwnd%
  Gui, Show, NA x%xpos% y%ypos%
  hwnd.Push(NewConformation%index%)
 
  SetTimer, deleteNotification, 3000
  return
 
  deleteNotification:
    deleteHwnd := hwnd.RemoveAt(1)
    if(deleteHwnd)
      Gui, %deleteHwnd%:Destroy
    if(hwnd.Length() < 1)
      SetTimer, deleteNotification, off
  return
}

PopulateDropZoneList(path)
{
  data := LoadData(path)
  for index, array in data
    LV_Add(, array["dropZone"], array["prefix"], array["suffix"], array["pos"], array["fileDrop"], array["icon"], array["timeFormat"])
}

SaveData(path)
{
  global showCancelConfirm, firstTimeOpenShowConfig
  FileCopy, %path%, %path%.bak
  FileDelete, %path%
  data := ""
 
  ; Save the setttings
  data := firstTimeOpenShowConfig . "|"  . showCancelConfirm . "`n"
  FileAppend, %data%, %path%
 
  ; Save the list data
  Loop, % LV_GetCount()
  {
    rowData := RowText(A_Index)
    data := rowData[1] . "|" .  rowData[2] . "|" .  rowData[3] . "|" .  rowData[4] . "|" .  rowData[5] . "|" .  rowData[6] . "|" . rowData[7] . "`n"
    FileAppend, %data%, %path%
  }
  FileDelete, %path%.bak
}

RowText(rowNumber)
{
  LV_GetText(dropZone, rowNumber, 1)
  LV_GetText(prefix, rowNumber, 2)
  LV_GetText(suffix, rowNumber, 3)
  LV_GetText(pos, rowNumber, 4)
  LV_GetText(location, rowNumber, 5)
  LV_GetText(icon, rowNumber, 6)
  LV_GetText(TimeFormat, rowNumber, 7)
  return [dropZone, prefix, suffix, pos, location, icon, TimeFormat]
}

ValidateFields(dropZone, prefix, suffix, lastDropWindowPos, fileDrop, icon, timeFormat)
{
   reason := ""
   ; Make sure file locations exist
   if(!FileExist(fileDrop))
      reason .= "fileDrop, "
   
   if(!FileExist(icon))
      reason .= "icon, "
   
   ; Make sure dropzone is not blank
   if(dropZone = "")
      reason .= "dropZone, "
   
   if(lastDropWindowPos = "")
      reason .= "DropZone_Position, "
   
   if(timeFormat = "")
      reason .= "timeFormat"

   return reason
}

IDropTargetOnDrop_WIDZ(TargetObject, pDataObj, KeyState, X, Y, DropEffect)
{
  Static CF_NATIVE := A_IsUnicode ? 13 : 1 ; CF_UNICODETEXT  : CF_TEXT
  global dropZoneGuis
  ; if valid
  If (pEnumObj := IDataObject_EnumFormatEtc(pDataObj))
  {
    ; Loop through structure
    While IEnumFORMATETC_Next(pEnumObj, FORMATETC)
    {
      ; Populate variables with current item data
      IDataObject_ReadFormatEtc(FORMATETC, Format, Device, Aspect, Index, Type)
     
      ; We only want the text since it will have the shortcut url so continue looping until it shows up
      if(Format != CF_NATIVE)
            continue
      else
      {
        IDataObject_GetData(pDataObj, FORMATETC, Size, Data)
        url := StrGet(&Data)
        response := DropFile(dropZoneGuis, TargetObject.hwnd, url)
        if(response != true)
          msgbox % response
       
        break
      }
    }
  }
}

; ************************************************ All the code below is from https://github.com/AHK-just-me and wasn't written by me
; from https://github.com/AHK-just-me/DoDragDrop/blob/master/sources/IDropTarget.ahk
; ==================================================================================================================================
; IDropTarget interface -> msdn.microsoft.com/en-us/library/ms679679(v=vs.85).aspx
; Requires: IDataObject.ahk
; ==================================================================================================================================
IDropTarget_Create(HWND, UserFuncSuffix, RequiredFormats := "", Register := True, UseHelper := True) {
   Return New IDropTarget(HWND, UserFuncSuffix, RequiredFormats, Register, UseHelper)
}
; ==================================================================================================================================
Class IDropTarget {
   __New(HWND, UserFuncSuffix, RequiredFormats := "", Register := True, UseHelper := True) {
      Static Methods := ["QueryInterface", "AddRef", "Release", "DragEnter", "DragOver", "DragLeave", "Drop"]
      Static Params := (A_PtrSize = 8 ? [3, 1, 1, 5, 4, 1, 5] : [3, 1, 1, 6, 5, 1, 6])
      Static DefaultFormat := 15 ; CF_HDROP
      Static DropFunc := "IDropTargetOnDrop"
      Static EnterFunc := "IDropTargetOnEnter"
      Static OverFunc := "IDropTargetOnOver"
      Static LeaveFunc := "IDropTargetOnLeave"
      Static CLSID_IDTH := "{4657278A-411B-11D2-839A-00C04FD918D0}" ; CLSID_DragDropHelper
      Static IID_IDTH := "{4657278B-411B-11D2-839A-00C04FD918D0}"   ; IID_IDropTargetHelper
      If This.Base.HasKey("Ptr")
         Return False
      UserFunc := DropFunc . UserFuncSuffix
      If !IsFunc(UserFunc) || (Func(UserFunc).MinParams < 6)
         Return False
      This.DropUserFunc := Func(UserFunc)
      UserFunc := EnterFunc . UserFuncSuffix
      If (IsFunc(UserFunc) && (Func(UserFunc).MinParams > 5))
         This.EnterUserFunc := Func(UserFunc)
      UserFunc := OverFunc . UserFuncSuffix
      If (IsFunc(UserFunc) && (Func(UserFunc).MinParams > 4))
         This.OverUserFunc := Func(UserFunc)
      UserFunc := LeaveFunc . UserFuncSuffix
      If (IsFunc(UserFunc) && (Func(UserFunc).MinParams > 0))
         This.LeaveUserFunc := Func(UserFunc)
      This.HWND := HWND
      This.Registered := False
      If IsObject(RequiredFormats)
         This.Required := RequiredFormats
      Else
         This.Required := [DefaultFormat]
      This.PreferredDropEffect := 0
      SizeOfVTBL := (Methods.Length() + 2) * A_PtrSize
      This.SetCapacity("VTBL", SizeOfVTBL)
      This.Ptr := This.GetAddress("VTBL")
      DllCall("RtlZeroMemory", "Ptr", This.Ptr, "UInt", SizeOfVTBL)
      NumPut(This.Ptr + A_PtrSize, This.Ptr + 0, "UPtr")
      For Index, Method In Methods {
         CB := RegisterCallback("IDropTarget." . Method, "", Params[Index], &This)
         NumPut(CB, This.Ptr + 0, A_Index * A_PtrSize, "UPtr")
      }
      This.Helper := ComObjCreate(CLSID_IDTH, IID_IDTH)
      If (Register)
         If !This.RegisterDragDrop()
            Return False
   }
   ; -------------------------------------------------------------------------------------------------------------------------------
   ; Registers window/control as a drop target.
   ; -------------------------------------------------------------------------------------------------------------------------------
   RegisterDragDrop() {
      If !(This.Registered)
         If DllCall("Ole32.dll\RegisterDragDrop", "Ptr", This.HWND, "Ptr", This.Ptr, "Int")
            Return False
      Return (This.Registered := True)
   }
   ; -------------------------------------------------------------------------------------------------------------------------------
   ; Revokes registering of the window/control as a drop target.
   ; This method should be called before the window/control will be destroyed.
   ; -------------------------------------------------------------------------------------------------------------------------------
   RevokeDragDrop() {
      If (This.Registered)
         DllCall("Ole32.dll\RevokeDragDrop", "Ptr", This.HWND)
      Return !(This.Registered := False)
   }
   ; -------------------------------------------------------------------------------------------------------------------------------
   ; Notifies the drag-image manager, if used, to show or hide the drag image.
   ; Parameter:
   ;     Show  -  If true, the drag image will be shown; otherwise it will be hidden.
   ; -------------------------------------------------------------------------------------------------------------------------------
   HelperShow(Show := True) {
      Static HelperShow := A_PtrSize * 7
      If (This.Helper) {
         pVTBL := NumGet(This.Helper + 0, "UPtr")
         , DllCall(NumGet(pVTBL + HelperShow, "UPtr"), "Ptr", This.Helper, "UInt", !!Show)
         Return True
      }
      Return False
   }
   ; ===============================================================================================================================
   ; The following methods must not be called directly, they are reserved for internal and system use.
   ; ===============================================================================================================================
   __Delete() {
      This.RevokeDragDrop()
      While (CB := NumGet(This.Ptr + (A_PtrSize * A_Index), "Ptr"))
         DllCall("GlobalFree", "Ptr", CB)
      If (This.Helper)
         ObjRelease(This.Helper)
   }
   ; -------------------------------------------------------------------------------------------------------------------------------
   QueryInterface(RIID, PPV) {
      ; IUnknown -> msdn.microsoft.com/en-us/library/ms682521(v=vs.85).aspx
      Static IID := "{00000122-0000-0000-C000-000000000046}"
      VarSetCapacity(QID, 80, 0)
      QIDLen := DllCall("Ole32.dll\StringFromGUID2", "Ptr", RIID, "Ptr", &QID, "Int", 40, "Int")
      If (StrGet(&QID, QIDLen, "UTF-16") = IID) {
         NumPut(This, PPV + 0, "Ptr")
         Return 0 ; S_OK
      }
      Else {
         NumPut(0, PPV + 0, "Ptr")
         Return 0x80004002 ; E_NOINTERFACE
      }
   }
   ; -------------------------------------------------------------------------------------------------------------------------------
   AddRef() {
      ; IUnknown -> msdn.microsoft.com/en-us/library/ms691379(v=vs.85).aspx
      ; Reference counting is not needed in this case.
      Return 1
   }
   ; -------------------------------------------------------------------------------------------------------------------------------
   Release() {
      ; IUnknown -> msdn.microsoft.com/en-us/library/ms682317(v=vs.85).aspx
      ; Reference counting is not needed in this case.
      Return 0
   }
   ; -------------------------------------------------------------------------------------------------------------------------------
   DragEnter(pDataObj, grfKeyState, P3 := "", P4 := "", P5 := "") {
      ; DragEnter -> msdn.microsoft.com/en-us/library/ms680106(v=vs.85).aspx
      ; Params 32: IDataObject *pDataObj, DWORD grfKeyState, LONG x, LONG y, DWORD *pdwEffect
      ; Params 64: IDataObject *pDataObj, DWORD grfKeyState, POINTL pt, DWORD *pdwEffect
      Static HelperEnter := A_PtrSize * 3
      Instance := Object(A_EventInfo)
      If (A_PtrSize = 8)
         X := P2 & 0xFFFFFFFF, Y := P2 >> 32
      Else
         X := P2, Y := P3
      Effect := 0
      If !(grfKeyState & 0x02) { ; right-drag isn't supported by default
         For Each, Format In Instance.Required {
            IDataObject_CreateFormatEtc(FORMATETC, Format)
            If (Effect := IDataObject_QueryGetData(pDataObj, FORMATETC))
               Break
         }
      }
      If (Effect) && (Instance.EnterUserFunc)
         Effect := Instance.EnterUserFunc.Call(Instance, pDataObj, grfKeyState, X, Y, Effect)
      Instance.PreferredDropEffect := Effect
      ; If Ctrl and/or Shift is pressed swap the effect
      Effect ^= grfKeyState & 0x0C ? 3 : 0
      ; Call IDropTargetHelper, if created
      If (Instance.Helper) {
         VarSetCapacity(PT, 8, 0)
         , NumPut(X, PT, 0, "Int")
         , NumPut(Y, PT, 0, "Int")
         , pVTBL := NumGet(Instance.Helper + 0, "UPtr")
         , DllCall(NumGet(pVTBL + HelperEnter, "UPtr")
                 , "Ptr", Instance.Helper, "Ptr", Instance.HWND, "Ptr", pDataObj, "Ptr", &PT, "UInt", Effect, "Int")
      }
      NumPut(Effect, (A_PtrSize = 8 ? P4 : P5) + 0, "UInt")
      Return 0 ; S_OK
   }
   ; -------------------------------------------------------------------------------------------------------------------------------
   DragOver(grfKeyState, P2 := "", P3 := "", P4 := "") {
      ; DragOver -> msdn.microsoft.com/en-us/library/ms680129(v=vs.85).aspx
      ; Params 32: DWORD grfKeyState, LONG x, LONG y, DWORD *pdwEffect
      ; Params 64: DWORD grfKeyState, POINTL pt, DWORD *pdwEffect
      Static HelperOver := A_PtrSize * 5
      Instance := Object(A_EventInfo)
      If (A_PtrSize = 8)
         X := P2 & 0xFFFFFFFF, Y := P2 >> 32
      Else
         X := P2, Y := P3
      ; If Ctrl and/or Shift is pressed swap the effect
      Effect := Instance.PreferredDropEffect ^ (grfKeyState & 0x0C ? 3 : 0)
      If (Effect) && (Instance.OverUserFunc)
         Effect := Instance.OverUserFunc.Call(Instance, grfKeyState, X, Y, Effect)
      If (Instance.Helper) {
         VarSetCapacity(PT, 8, 0)
         , NumPut(X, PT, 0, "Int")
         , NumPut(Y, PT, 0, "Int")
         , pVTBL := NumGet(Instance.Helper + 0, "UPtr")
         , DllCall(NumGet(pVTBL + HelperOver, "UPtr"), "Ptr", Instance.Helper, "Ptr", &PT, "UInt", Effect, "Int")
      }
      NumPut(Effect, (A_PtrSize = 8 ? P3 : P4) + 0, "UInt")
      Return 0 ; S_OK
   }
   ; -------------------------------------------------------------------------------------------------------------------------------
   DragLeave() {
      ; DragLeave -> msdn.microsoft.com/en-us/library/ms680110(v=vs.85).aspx
      Static HelperLeave := A_PtrSize * 4
      Instance := Object(A_EventInfo)
      Instance.PreferredDropEffect := 0
      If (Instance.LeaveUserFunc)
         Instance.LeaveUserFunc.Call(Instance)
      If (Instance.Helper) {
         pVTBL := NumGet(Instance.Helper + 0, "UPtr"), DllCall(NumGet(pVTBL + HelperLeave, "UPtr"), "Ptr", Instance.Helper)
      }
      Return 0 ; S_OK
   }
   ; -------------------------------------------------------------------------------------------------------------------------------
   Drop(pDataObj, grfKeyState, P3 := "", P4 := "", P5 := "") {
      ; Drop -> msdn.microsoft.com/en-us/library/ms687242(v=vs.85).aspx
      ; Params 32: IDataObject *pDataObj, DWORD grfKeyState, LONG x, LONG y, DWORD *pdwEffect
      ; Params 64: IDataObject *pDataObj, DWORD grfKeyState, POINTL pt, DWORD *pdwEffect
      Static HelperDrop := A_PtrSize * 6
      Instance := Object(A_EventInfo)
      If (A_PtrSize = 8)
         X := P3 & 0xFFFFFFFF, Y := P3 >> 32
      Else
         X := P3, Y := P4
      Effect := Instance.PreferredDropEffect ^ (grfKeyState & 0x0C ? 3 : 0)
      Effect := Instance.DropUserFunc.Call(Instance, pDataObj, grfKeyState, X, Y, Effect)
      NumPut(Effect, (A_PtrSize = 8 ? P4 : P5) + 0, "UInt")
      If (Instance.Helper) {
         VarSetCapacity(PT, 8, 0)
         , NumPut(X, PT, 0, "Int")
         , NumPut(Y, PT, 0, "Int")
         , pVTBL := NumGet(Instance.Helper + 0, "UPtr")
         , DllCall(NumGet(pVTBL + HelperDrop, "UPtr"), "Ptr", Instance.Helper, "Ptr", pDataObj, "Ptr", &PT, "UInt", Effect, "Int")
      }
      ObjRelease(pDataObj)
      Return 0 ; S_OK
   }
}
; ==================================================================================================================================

; from https://github.com/AHK-just-me/DoDragDrop/blob/master/sources/IDataObject.ahk
; ==================================================================================================================================
; IDataObject interface -> msdn.microsoft.com/en-us/library/ms688421(v=vs.85).aspx
; Partial implementation.
; Requires: IEnumFORMATETC.ahk
; ==================================================================================================================================
IDataObject_EnumFormatEtc(pDataObj) {
   ; EnumFormatEtc -> msdn.microsoft.com/en-us/library/ms683979(v=vs.85).aspx
   ; DATADIR_GET = 1
   Static EnumFormatEtc := A_PtrSize * 8
   pVTBL := NumGet(pDataObj + 0, "UPtr")
   If !DllCall(NumGet(pVTBL + EnumFormatEtc, "UPtr"), "Ptr", pDataObj, "UInt", 1, "PtrP", ppenumFormatEtc, "Int")
      Return ppenumFormatEtc
   Return False
}
; ==================================================================================================================================
IDataObject_GetData(pDataObj, ByRef FORMATETC, ByRef Size, ByRef Data) {
   ; GetData -> msdn.microsoft.com/en-us/library/ms678431(v=vs.85).aspx
   Static GetData := A_PtrSize * 3
   Data := ""
   , Size := -1
   , VarSetCapacity(STGMEDIUM, 24, 0) ; 64-bit
   , pVTBL := NumGet(pDataObj + 0, "UPtr")
   If !DllCall(NumGet(pVTBL + GetData, "UPtr"), "Ptr", pDataObj, "Ptr", &FORMATETC, "Ptr", &STGMEDIUM, "Int") {
      If (NumGet(STGMEDIUM, "UInt") = 1) { ; TYMED_HGLOBAL
         hGlobal := NumGet(STGMEDIUM, A_PtrSize, "UPtr")
         , pGlobal := DllCall("GlobalLock", "Ptr", hGlobal, "Uptr")
         , Size := DllCall("GlobalSize", "Ptr", hGlobal, "UPtr")
         , VarSetCapacity(Data, Size, 0)
         , DllCall("RtlMoveMemory", "Ptr", &Data, "Ptr", pGlobal, "Ptr", Size)
         , DllCall("GlobalUnlock", "Ptr", hGlobal)
         , DllCall("Ole32.dll\ReleaseStgMedium", "Ptr", &STGMEDIUM)
         Return True
      }
      DllCall("Ole32.dll\ReleaseStgMedium", "Ptr", &STGMEDIUM)
   }
   Return False
}
; ==================================================================================================================================
IDataObject_QueryGetData(pDataObj, ByRef FORMATETC) {
   ; QueryGetData -> msdn.microsoft.com/en-us/library/ms680637(v=vs.85).aspx
   Static QueryGetData := A_PtrSize * 5
   pVTBL := NumGet(pDataObj + 0, "UPtr")
   Return !DllCall(NumGet(pVTBL + QueryGetData, "UPtr"), "Ptr", pDataObj, "Ptr", &FORMATETC, "Int")
}
; ==================================================================================================================================
IDataObject_SetData(pDataObj, ByRef FORMATETC, ByRef STGMEDIUM) {
   ; SetData -> msdn.microsoft.com/en-us/library/ms686626(v=vs.85).aspx
   Static SetData := A_PtrSize * 7
   pVTBL := NumGet(pDataObj + 0, "UPtr")
   Return !DllCall(NumGet(pVTBL + SetData, "UPtr"), "Ptr", pDataObj, "Ptr", &FORMATETC, "Ptr", &STGMEDIUM, "Int", True, "Int")
}
; ==================================================================================================================================
; Auxiliary functions to get/set data of the data object.
; ==================================================================================================================================
; FORMATETC structure -> msdn.microsoft.com/en-us/library/ms682242(v=vs.85).aspx
; ==================================================================================================================================
IDataObject_CreateFormatEtc(ByRef FORMATETC, Format, Aspect := 1, Index := -1, Tymed := 1) {
   ; DVASPECT_CONTENT = 1, Index all data = -1, TYMED_HGLOBAL = 1
   VarSetCapacity(FORMATETC, 32, 0) ; 64-bit
   , NumPut(Format, FORMATETC, 0, "Ushort")
   , NumPut(Aspect, FORMATETC, A_PtrSize = 8 ? 16 : 8 , "UInt")
   , NumPut(Index, FORMATETC, A_PtrSIze = 8 ? 20 : 12, "Int")
   , NumPut(Tymed, FORMATETC, A_PtrSize = 8 ? 24 : 16, "UInt")
   Return &FORMATETC
}
; ==================================================================================================================================
IDataObject_ReadFormatEtc(ByRef FORMATETC, ByRef Format, ByRef Device, ByRef Aspect, ByRef Index, ByRef Tymed) {
   Format := NumGet(FORMATETC, OffSet := 0, "UShort")
   , Device := NumGet(FORMATETC, Offset += A_PtrSize, "UPtr")
   , Aspect := NumGet(FORMATETC, Offset += A_PtrSize, "UInt")
   , Index  := NumGet(FORMATETC, Offset += 4, "Int")
   , Tymed  := NumGet(FORMATETC, Offset += 4, "UInt")
}
; ==================================================================================================================================
; Get/Set format data.
; ==================================================================================================================================
IDataObject_GetDroppedFiles(pDataObj, ByRef DroppedFiles) {
   ; msdn.microsoft.com/en-us/library/bb773269(v=vs.85).aspx
   IDataObject_CreateFormatEtc(FORMATETC, 15) ; CF_HDROP
   DroppedFiles := []
   If IDataObject_GetData(pDataObj, FORMATETC, Size, Data) {
      Offset := NumGet(Data, 0, "UInt")
      CP := NumGet(Data, 16, "UInt") ? "UTF-16" : "CP0"
      Shift := (CP = "UTF-16")
      While (File := StrGet(&Data + Offset, CP)) {
         DroppedFiles.Push(File)
         Offset += (StrLen(File) + 1) << Shift
      }
   }
   Return DroppedFiles.Length()
}
; ==================================================================================================================================
IDataObject_GetLogicalDropEffect(pDataObj, ByRef DropEffect) {
   Static LogicalDropEffect := DllCall("RegisterClipboardFormat", "Str", "Logical Performed DropEffect")
   IDataObject_CreateFormatEtc(FORMATETC, LogicalDropEffect)
   DropEffect := ""
   If IDataObject_GetData(pDataObj, FORMATETC, Size, Data) {
      DropEffect := NumGet(Data, "UChar")
      Return True
   }
   Return False
}
; ==================================================================================================================================
IDataObject_GetPerformedDropEffect(pDataObj, ByRef DropEffect) {
   Static PerformedDropEffect := DllCall("RegisterClipboardFormat", "Str", "Performed DropEffect")
   IDataObject_CreateFormatEtc(FORMATETC, PerformedDropEffect)
   DropEffect := ""
   If IDataObject_GetData(pDataObj, FORMATETC, Size, Data) {
      DropEffect := NumGet(Data, "UChar")
      Return True
   }
   Return False
}
; ==================================================================================================================================
IDataObject_GetText(pDataObj, ByRef Txt) {
   Static CF_NATIVE := A_IsUnicode ? 13 : 1 ; CF_UNICODETEXT : CF_TEXT
   IDataObject_CreateFormatEtc(FORMATETC, CF_NATIVE)
   Txt := ""
   If IDataObject_GetData(pDataObj, FORMATETC, Size, Data) {
      Txt := StrGet(Data, Size >> !!A_IsUnicode)
      Return True
   }
   Return False
}
; ==================================================================================================================================
IDataObject_SetLogicalDropEffect(pDataObj, DropEffect) {
   Static LogicalDropEffect := DllCall("RegisterClipboardFormat", "Str", "Logical Performed DropEffect")
   IDataObject_CreateFormatEtc(FORMATETC, LogicalDropEffect)
   , VarSetCapacity(STGMEDIUM, 24, 0) ; 64-bit
   , NumPut(1, STGMEDIUM, "UInt") ; TYMED_HGLOBAL
   ; 0x42 = GMEM_MOVEABLE (0x02) | GMEM_ZEROINIT (0x40)
   , hMem := DllCall("GlobalAlloc", "UInt", 0x42, "UInt", 4, "UPtr")
   , pMem := DllCall("GlobalLock", "Ptr", hMem)
   , NumPut(DropEffect, pMem + 0, "UChar")
   , DllCall("GlobalUnlock", "Ptr", hMem)
   , NumPut(hMem, STGMEDIUM, A_PtrSize, "UPtr")
   Return IDataObject_SetData(pDataObj, FORMATETC, STGMEDIUM)
}
; ==================================================================================================================================
IDataObject_SetPerformedDropEffect(pDataObj, DropEffect) {
   Static PerformedDropEffect := DllCall("RegisterClipboardFormat", "Str", "Performed DropEffect")
   IDataObject_CreateFormatEtc(FORMATETC, PerformedDropEffect)
   , VarSetCapacity(STGMEDIUM, 24, 0) ; 64-bit
   , NumPut(1, STGMEDIUM, "UInt") ; TYMED_HGLOBAL
   ; 0x42 = GMEM_MOVEABLE (0x02) | GMEM_ZEROINIT (0x40)
   , hMem := DllCall("GlobalAlloc", "UInt", 0x42, "UInt", 4, "UPtr")
   , pMem := DllCall("GlobalLock", "Ptr", hMem)
   , NumPut(DropEffect, pMem + 0, "UChar")
   , DllCall("GlobalUnlock", "Ptr", hMem)
   , NumPut(hMem, STGMEDIUM, A_PtrSize, "UPtr")
   Return IDataObject_SetData(pDataObj, FORMATETC, STGMEDIUM)
}
; ==================================================================================================================================
IDataObject_SHFileOperation(pDataObj, TargetPath, Operation, HWND := 0) {
   ; SHFileOperation -> msdn.microsoft.com/en-us/library/bb762164(v=vs.85).aspx
   If Operation Not In 1,2
      Return False
   IDataObject_CreateFormatEtc(FORMATETC, 15) ; CF_HDROP
   If IDataObject_GetData(pDataObj, FORMATETC, Size, Data) {
      Offset := NumGet(Data, 0, "UInt") ; offset of the file list
      IsUnicode := NumGet(Data, 16, "UInt") ; 1: Unicode, 0: ANSI
      TargetLen := StrPut(TargetPath, IsUnicode ? "UTF-16" : "CP0") + 2
      VarSetCapacity(Target, TargetLen << !!IsUnicode, 0)
      StrPut(TargetPath, &Target, IsUnicode ? "UTF-16" : "CP0")
      SHFOSLen := A_PtrSize * (A_PtrSize = 8 ? 7 : 8)
      VarSetCapacity(SHFOS, SHFOSLen, 0) ; SHFILEOPSTRUCT
      NumPut(HWND, SHFOS, 0, "UPtr")
      NumPut(Operation, SHFOS, A_PtrSize, "UInt") ; FO_MOVE = 1, FO_COPY = 2, so we have to swap the DropEffect
      NumPut(&Data + Offset, SHFOS, A_PtrSize * 2, "UPtr")
      NumPut(&Target, SHFOS, A_PtrSize * 3, "UPtr")
      NumPut(0x0200, SHFOS, A_PtrSize * 4, "UInt") ; FOF_NOCONFIRMMKDIR
      If (IsUnicode)
         Return DllCall("Shell32.dll\SHFileOperationW", "Ptr", &SHFOS, "Int")
      Else
         Return DllCall("Shell32.dll\SHFileOperationA", "Ptr", &SHFOS, "Int")
   }
}
; ==================================================================================================================================
; from https://github.com/AHK-just-me/DoDragDrop/blob/master/sources/IEnumFORMATETC.ahk
; ==================================================================================================================================
; IEnumFORMATETC interface -> msdn.microsoft.com/en-us/library/ms682337(v=vs.85).aspx
; Partial implementation, 'Clone' method is missing.
; ==================================================================================================================================
IEnumFORMATETC_Next(pEnumObj, ByRef FORMATETC) {
   ; Next -> msdn.microsoft.com/en-us/library/dd542673(v=vs.85).aspx
   Static Next := A_PtrSize * 3
   VarSetCapacity(FORMATETC, A_PtrSize = 8 ? 32 : 20, 0)
   , pVTBL := NumGet(pEnumObj + 0, "UPtr")
   Return !DllCall(NumGet(pVTBL + Next, "UPtr"), "Ptr", pEnumObj, "UInt", 1, "Ptr", &FORMATETC, "Ptr", 0, "Int")
}
; ----------------------------------------------------------------------------------------------------------------------------------
IEnumFORMATETC_Reset(pEnumObj) {
   ; Reset -> msdn.microsoft.com/en-us/library/dd542674(v=vs.85).aspx
   Static Reset := A_PtrSize * 5
   pVTBL := NumGet(pEnumObj + 0, "UPtr")
   Return !DllCall(NumGet(pVTBL + Reset, "UPtr"), "Ptr", pEnumObj, "Int")
}
; ----------------------------------------------------------------------------------------------------------------------------------
IEnumFORMATETC_Skip(pEnumObj, ItemCount) {
   ; Skip -> msdn.microsoft.com/en-us/library/dd542674(v=vs.85).aspx
   Static Skip := A_PtrSize * 4
   pVTBL := NumGet(pEnumObj + 0, "UPtr")
   Return !DllCall(NumGet(pVTBL + Skip, "UPtr"), "Ptr", pEnumObj, "UInt", ItemCount, "Int")
}
; ==================================================================================================================================

10
Post New Requests Here / Re: IDEA: Drop Zone for Web Images
« on: October 12, 2015, 10:34 AM »
Can we bypass the filename check and maybe just produce a box that self closes after a few seconds indicating a save has been completed. And is there a way of making it appear on the monitor where the drop zone is located, if not just above the system tray so bottom right of monitor. I use 3 monitors and everything likes to appear in the middle of monitor 1 :)

Added

Ok that didn't exactly do what I expected . When I dragged the attached image to the Drop Zone in Firefox it created a shortcut to the original, but IE11 it was barred.
I think the issue with IE11 is the security thing, I don't have this issue with Win7 - IE11.

Another small issue found is that a "space" seems to be inserted after the date/time. I am using "yyyy-MM-dd_hh-mm-ss"

Added

Revised:
; -------------------------------------------------- Auto Execute --------------------------------------------------
#Persistent
#NoEnv  ; Recommended for performance and compatibility with future AutoHotkey releases.
SetWorkingDir %A_ScriptDir%  ; Ensures a consistent starting directory.
#SingleInstance force
SetBatchLines, -1
SetKeyDelay, -1
title := "Web Images Drop Zone"

iniPath := A_ScriptDir . "\WIDZ.data"


Menu, Tray, NoStandard
Menu, Tray, Add, &Config, Show
Menu, Tray, Default, &Config
Menu, Tray, Add, &Toggle DropZones, toggleDropZones
Menu, Tray, Add, E&xit, Exit
Menu, Tray, Click, 1
Menu, Tray, Tip, %title%
LoadSettings(iniPath)

if(firstTimeOpenShowConfig)
{
  firstTimeOpenShowConfig := false
  gosub, show
  WinWaitClose, %title% - Config
}

dropZoneGuis := CreateDropZoneGuis(iniPath)
OnExit("Exit")
return

; -------------------------------------------------- Labels --------------------------------------------------
createOrUpdateDropZone:
  ; Get dropZone info info
  GuiControlGet, dropZone,, dropZone
  GuiControlGet, timeFormat,, timeFormat
  GuiControlGet, fileDrop,, fileDrop
  GuiControlGet, icon,, icon
  GuiControlGet, prefix,, prefix
  GuiControlGet, suffix,, suffix
 
  ; Check if the dropZone already exists
  Loop % LV_GetCount()
  {
    Lv_GetText(dropZoneName, A_index)
    if(dropZoneName = dropZone)
    {
      LV_Modify(A_Index,,dropZone, prefix, suffix, lastDropWindowPos, fileDrop, icon, timeFormat)
      return
    }
  }
 
  LV_Add(,dropZone, prefix, suffix, lastDropWindowPos, fileDrop, icon, timeFormat)
return

drawDropWindow:
  ;http://www.autohotkey.com/board/topic/111196-drawing-boxes-on-screen-need-help-finishing/?p=655416
  GuID := "dropzone"
  LetUserSelectRect(GuiID, x1, y1, x2, y2)
  lastDropWindowPos := x1 . ":" . x2 . ":" . y1 . ":" . y2
  GuiControl,, pos, %lastDropWindowPos%

  Loop 4
    Gui, % GuiID A_Index ": Destroy"
return

dropZoneList:
  ; populate fields on a double click
  if(A_GuiEvent = "Normal")
    CopyDropZoneToForm(A_EventInfo)
  else if(A_GuiEvent = "RightClick")
    DeleteDropZoneData(A_EventInfo)
return

Exit:
  IfWinExist, %title% - Config
    SaveData(iniPath)
  ExitApp
return

fileDrop:
  FileSelectFolder, fileDrop,,, Select file folder
  if(fileDrop)
    GuiControl, , fileDrop, %fileDrop%
  else
    msgbox your folder wasn't found please select a valid folder, i.e. no the virtual ones like Libraries/Documents/Music/etc
return

icon:
  FileSelectFile, icon, 3, %A_MyDocuments%,Choose an Icon, Image files (*.jpg; *.jpeg; *.gif; *.png)
  GuiControl, , icon, %icon%
return

show:
  DeleteAllDropZones(dropZoneGuis)
  Gui, WebImageDropZoneConfig: New, hwndWIDZ, Web Image Drop Zone
  global WIDZ
  Gui, Add, ListView, x12 y10 w450 r15 gdropZoneList AltSubmit, DropZone|Prefix|Suffix|Pos|Save Path|Icon|TimeFormat
  Gui, Add, Text, x12 y300 w60 h20 , DropZone:
  Gui, Add, Edit, x72 y300 w90 h20 vdropZone , dropzone
  Gui, Add, Text, x172 y300 w60 h20 , TimeFormat:
  Gui, Add, Edit, x232 y300 w230 h20 vtimeFormat , yyyy-MM-dd_hh-ss
 
  Gui, font, s11 bold, MS sans serif
  Gui, Add, Link, x462 y300 w10 h20 , <a href="http://www.autohotkey.com/docs/commands/FormatTime.htm">?</a>
  gui, font
 
  Gui, Add, Text, x12 y330 w50 h20 , File Drop:
  Gui, Add, Edit, x72 y330 w320 h20 vfileDrop , file drop
  Gui, Add, Button, x392 y330 w70 h20 gfileDrop , Browse
 
  Gui, Add, Text, x12 y360 w40 h20 , Icon:
  Gui, Add, Edit, x72 y360 w320 h20 vicon, Edit
  Gui, Add, Button, x392 y360 w70 h20 gicon , Browse
 
  Gui, Add, Text, x12 y390 w40 h20 , Prefix:
  Gui, Add, Edit, x72 y390 w110 h20 vprefix , prefix
  Gui, Add, Text, x192 y390 w40 h20 , Suffix:
  Gui, Add, Edit, x232 y390 w110 h20 vsuffix , suffix
  Gui, Add, Button, x12 y420 w110 h20 gdrawDropWindow, DropZone Position
  Gui, Add, Edit, x132 y420 w210 h20 ReadOnly vpos , 0:100:0:100
  Gui, Add, Button, x352 y390 w110 h50 gcreateOrUpdateDropZone , Create/Update
 
  ; Generated using SmartGUI Creator 4.0
  Gui, Show, x138 y90 h450 w479, %title% - Config
  PopulateDropZoneList(iniPath)
  OnMessage(0x200, "GuiToolTip")
  Loop 6
      LV_ModifyCol(A_Index, "AutoHdr")
 
return

toggleDropZones:
for index, array in dropZoneGuis
{
  hwnd := array["hwnd"]
 
  if WinExist("ahk_id " . hwnd)
    gui, %hwnd%:Hide
  else
    gui, %hwnd%:Show
}
return

WebImageDropZoneConfigGuiClose:
WebImageDropZoneConfigGuiEscape:
  IfWinExist, %title% - Config
    SaveData(iniPath)
  Gui, WebImageDropZoneConfig:Destroy
 
  ; Update the dropzones
  dropZoneGuis := CreateDropZoneGuis(iniPath)
return



; -------------------------------------------------- Methods --------------------------------------------------
CopyDropZoneToForm(eventInfo)
{
  global lastDropWindowPos
  ; get row text
  LV_GetText(dropZone, eventInfo, 1)
  LV_GetText(prefix, eventInfo, 2)
  LV_GetText(suffix, eventInfo, 3)
  LV_GetText(pos, eventInfo, 4)
  LV_GetText(fileDrop, eventInfo, 5)
  LV_GetText(icon, eventInfo, 6)
  LV_GetText(TimeFormat, eventInfo, 7)
 
  ; update fields
  GuiControl,, dropZone, %dropZone%
  GuiControl,, prefix, %prefix%
  GuiControl,, suffix, %suffix%
  GuiControl,, pos, %pos%
  lastDropWindowPos := pos
  GuiControl,, fileDrop, %fileDrop%
  GuiControl,, icon, %icon%
  GuiControl,, TimeFormat, %TimeFormat%
}

CreateDropZoneGuis(path)
{
  dropZoneGuis := Array()
  dropZoneData := LoadData(path)
 
  for index, array in dropZoneData
  {
    extractedPos := StrSplit(array["pos"], ":")
    guiHwnd := DropZoneGui(array["dropZone"], array["icon"], extractedPos[1], extractedPos[2], extractedPos[3], extractedPos[4])
    IDT_WIDZ := IDropTarget_Create(guiHwnd, "_WIDZ", [1, 13, 15]) ; CF_TEXT, CF_UNICODETEXT, CF_HDROP
    dropZoneGuis.insert({dropZone: array["dropZone"], hwnd: guiHwnd, iDropTarget: IDT_WIDZ})
  }

  return dropZoneGuis
}

; Custom message box for the confirm dropzone delete.
Custom_MsgBox(msg_text)
{
  global showCancelConfirm, dontShowAgain
  Gui, CustomMsgBox: New, hwndCMB
  Gui, Add, Text, x12 y10 w430 h70, %msg_text%
  Gui, Add, CheckBox, x12 y90 w140 h30 vdontShowAgain , Don't show this again?
  Gui, Add, Button, x232 y90 w100 h30 gCustomMsgBoxGuiSubmit , OK
  Gui, Add, Button, x342 y90 w100 h30 gCustomMsgBoxGuiSubmit Default , Cancel
  ; Generated using SmartGUI Creator 4.0
  Gui, Show
  WinWaitClose, ahk_id %CMB%
  return buttonClicked
 
  CustomMsgBoxGuiSubmit:
    GuiControlGet, dontShowAgainChecked,, dontShowAgain
    if(dontShowAgainChecked)
      showCancelConfirm := false
   
    buttonClicked := A_GuiControl
    gosub, CustomMsgBoxGuiClose
  return

  CustomMsgBoxGuiClose:
  CustomMsgBoxGuiEscape:
  Gui, CustomMsgBox:Destroy
  return
}

DeleteDropZoneData(eventInfo)
{
  global showCancelConfirm
 
  Gui, WebImageDropZoneConfig:Default
  LV_GetText(thisDropZone, eventInfo)
 
  if(showCancelConfirm)
  {
    if(Custom_MsgBox("Are you sure you want to delete the '" . thisDropZone . "' drop zone?") = "OK")
      LV_Delete(eventInfo)
  }
  else
    LV_Delete(eventInfo)
}

DeleteAllDropZones(dropZoneGuis)
{
  ; dropZone, hwnd, iDropTarget
  for index, array in dropZoneGuis
  {
    ;~ Revoke the registration of the ListView as a potential target for OLE drag-and-drop operations.
    array["iDropTarget"].RevokeDragDrop()
    hwnd := array["hwnd"]
    Gui, %hwnd%:Destroy
  }
}

determineRealURL(url)
{
  origUrl := url
  if(InStr(url, "google.com"))
    RegExMatch(url, "(?<=\?imgurl=).*?(?=&)", url)
 
  ;~ msgbox % "url: " url "`n`norigUrl: " origUrl
  return url
}

downloadFile(origUrl, foundUrl, dropZoneInfo, targetHwnd)
{
  SplitPath, foundUrl,,, imageFileExt
  fileDropDir := dropZoneInfo["fileDrop"]
  prefix := dropZoneInfo["prefix"]
  suffix := dropZoneInfo["suffix"]
  timeFormat := dropZoneInfo["timeFormat"]
  FormatTime, nowTime,, % timeFormat

  ; Per request removed the fileName check
  ;~ Inputbox, fileName, File Name Entry, Please Enter a file name. (no extension),,,,,,,, %prefix% %nowTime% %suffix%
  ;~ if(fileName = "")
  fileName :=  prefix . " " . nowTime . " " . suffix
  fileName := Trim(fileName)
 
 
  ; Only try to download the file if its a jpg, otherwise create a link
  if(RegExMatch(foundUrl, "\.\w{3,4}$"))
  {
    try
    {
      saveLocation := fileDropDir . "\" . fileName . "." . imageFileExt
      URLDownloadToFile, %foundUrl%, %saveLocation%
      if(ErrorLevel)
        return "Unable to download '" . foundUrl . "' parsed from '" . origUrl . "'" . "`n`nfileDropDir: " . fileDropDir . "`nfileName: " . fileName . "`next: " . imageFileExt
     
      NotificationPopup(saveLocation, targetHwnd)
      return true
    }
    catch, e
    {
      msgbox % "ErrorLevel: " ErrorLevel "`nA_LastError: " A_LastError "`nmessage: " e.message "`nWhat: " e.what "`nExtra: " e.extra "`nLine: " e.line
      return "Unable to download '" . foundUrl . "' parsed from '" . origUrl . "'" . "`n`nfileDropDir: " . fileDropDir . "`nfileName: " . fileName . "`next: " . imageFileExt
    }
  }
  else
  {
    FileCreateShortcut, %foundUrl%, %fileDropDir%\%fileName%.lnk
    TrayTip, Link Created, Couldn't find image so a link was created instead., 15
    return true
  }
}

DropFile(dropZoneGuis, targetHwnd, url)
{
  dropZoneInfo := findDropZoneInfo(dropZoneGuis, targetHwnd)
  foundUrl := determineRealURL(url)
 
  return downloadFile(url, foundUrl, dropZoneInfo, targetHwnd)
}

; Called to create/display dropZone gui
DropZoneGui(label, icon, x1, x2, y1, y2)
{
  static index = 0
  index += 1
 
  ; If no pos data was provided
  if(!x1)
  {
    x1 := 0
    x2 := 100
    y1 := 0
    y1 := 100
  }
 
  width := x2 - x1
  height := y2 - y1
  labelWidth := StrLen(label) * 25
  labelHeight := 32
 
  ; If the label is too long we set the labelsPerRow to 1 otherwise nothing would be displayed
  labelsPerColumn := height / labelHeight < 1 ? 1 : height / labelHeight
  labelsPerRow := width / labelWidth < 1 ? 1 : width / labelWidth

  CustomColor = EEAA99  ; Can be any RGB color (it will be made transparent below).
  Gui, New, hwndDZG%index% +LastFound +AlwaysOnTop -Caption +ToolWindow ; +ToolWindow avoids a taskbar button and an alt-tab menu item.
  Gui, Color, %CustomColor%
 
  ; If an icon was provided make it the size of the gui else use the label text
  if(icon)
    Gui, Add, Picture, w%width% h%height%, %icon%
  else
  {
    Gui, Font, s32  ; Set a large font size (32-point).
    x := 0
   
    Loop %labelsPerRow%
    {
      y := 0
      Loop %labelsPerColumn%
      {
        Gui, Add, Text, % "x" x " y" y " cLime", %label%
        y += 50
      }
      x += labelWidth
    }
  }
  ; Make all pixels of this color transparent and make the text itself translucent (150):
  WinSet, TransColor, %CustomColor% 150
  Gui, Show, x%x1% y%y1% w%width% h%height% NoActivate  ; NoActivate avoids deactivating the currently active window.
  return DZG%index%
}

Exit(ExitReason, ExitCode)
{
  global dropZoneGuis

  DeleteAllDropZones(dropZoneGuis)
  ExitApp
}

findDropZoneInfo(dropZoneGuis, targetHwnd)
{
  global iniPath
 
  data := LoadData(iniPath)
  for index, array in dropZoneGuis
    if(array["hwnd"] = targetHwnd)
      for dindex, darray in data
        if(darray["dropZone"] = array["dropZone"])
          return darray
}

GuiToolTip(wParam, lParam, Msg)
{
  MouseGetPos,,,mhwnd, OutputVarControl
 
  if(OutputVarControl = "Button3" && mhwnd = WIDZ)
Help := "After pressing 'Dropzone Position' move your mouse to the desired location; hold down the mouse button then move the mouse to select your area."
  else
    Help := ""

  ToolTip % Help
}

LetUserSelectRect(ByRef ID, ByRef X1, ByRef Y1, ByRef X2, ByRef Y2)
{ ;http://www.autohotkey.com/board/topic/111196-drawing-boxes-on-screen-need-help-finishing/?p=655416
    CoordMode, Mouse ; Required: change coord mode to screen vs relative.
    static r := 3
    ; Create the "selection rectangle" GUIs (one for each edge).
    Loop 4 {
        Gui, % ID A_Index ": -Caption +ToolWindow +AlwaysOnTop"
        Gui, % ID A_Index ": Color", Red
    }
    ; Disable LButton.
    Hotkey, *LButton, lusr_return, On
    ; Wait for user to press LButton.
    KeyWait, LButton, D
    ; Get initial coordinates.
    MouseGetPos, xorigin, yorigin
    ; Set timer for updating the selection rectangle.
    SetTimer, lusr_update, 10
    ; Wait for user to release LButton.
    KeyWait, LButton
    ; Re-enable LButton.
    Hotkey, *LButton, Off
    ; Disable timer.
    SetTimer, lusr_update, Off
    return
 
    lusr_update:
        CoordMode, Mouse ; Required: change coord mode to screen vs relative.
        MouseGetPos, x, y
        if (x = xlast && y = ylast)
            ; Mouse hasn't moved so there's nothing to do.
            return
        if (x < xorigin)
             x1 := x, x2 := xorigin
        else x2 := x, x1 := xorigin
        if (y < yorigin)
             y1 := y, y2 := yorigin
        else y2 := y, y1 := yorigin
        ; Update the "selection rectangle".
        Gui, % ID "1:Show", % "NA X" x1 " Y" y1 " W" x2-x1 " H" r
        Gui, % ID "2:Show", % "NA X" x1 " Y" y2-r " W" x2-x1 " H" r
        Gui, % ID "3:Show", % "NA X" x1 " Y" y1 " W" r " H" y2-y1
        Gui, % ID "4:Show", % "NA X" x2-r " Y" y1 " W" r " H" y2-y1
    lusr_return:
    return
}

;~ LV_Add(, array[1], array[2], array[3], array[4], array[5], array[6], array[7])
LoadData(path)
{
  FileRead, data, %path%
  dataArray := Object()
 
  Loop, Parse, data, `n, `r`n
  {
    ; If not the setttings row
    if(A_Index != 1)
    {
      array := StrSplit(A_LoopField, "|")
      if(array[1])
      {
        dataArray.Insert({dropZone: array[1], prefix: array[2], suffix: array[3], pos: array[4], fileDrop: array[5], icon: array[6], timeFormat: array[7]})
      }
    }
  }
 
  return dataArray
}

LoadSettings(path)
{
  global showCancelConfirm, firstTimeOpenShowConfig
 
  FileReadLine, data, %path%, 1
 
  array := StrSplit(data, "|")
  firstTimeOpenShowConfig := array[1] = 0 ? false : true
  showCancelConfirm := array[2] = 0 ? false : true
}

NotificationPopup(saveLocation, targetHwnd)
{
  static index = 0
  static hwnd := Array()
 
  index += 1
  Gui, New, hwndNewConformation%index% +LastFound +AlwaysOnTop -Caption +ToolWindow
  Gui, Add, Text,, Success! - %saveLocation%
  WinGetPos, xpos, ypos, w, h, ahk_id %targetHwnd%
  Gui, Show, NA x%xpos% y%ypos%
  hwnd.Push(NewConformation%index%)
 
  SetTimer, deleteNotification, 3000
  return
 
  deleteNotification:
    deleteHwnd := hwnd.RemoveAt(1)
    if(deleteHwnd)
      Gui, %deleteHwnd%:Destroy
    if(hwnd.Length() < 1)
      SetTimer, deleteNotification, off
  return
}

PopulateDropZoneList(path)
{
  data := LoadData(path)
  for index, array in data
    LV_Add(, array["dropZone"], array["prefix"], array["suffix"], array["pos"], array["fileDrop"], array["icon"], array["timeFormat"])
}

SaveData(path)
{
  global showCancelConfirm, firstTimeOpenShowConfig
  FileCopy, %path%, %path%.bak
  FileDelete, %path%
  data := ""
 
  ; Save the setttings
  data := firstTimeOpenShowConfig . "|"  . showCancelConfirm . "`n"
  FileAppend, %data%, %path%
 
  ; Save the list data
  Loop, % LV_GetCount()
  {
    rowData := RowText(A_Index)
    data := rowData[1] . "|" .  rowData[2] . "|" .  rowData[3] . "|" .  rowData[4] . "|" .  rowData[5] . "|" .  rowData[6] . "|" . rowData[7] . "`n"
    FileAppend, %data%, %path%
  }
  FileDelete, %path%.bak
}

RowText(rowNumber)
{
  LV_GetText(dropZone, rowNumber, 1)
  LV_GetText(prefix, rowNumber, 2)
  LV_GetText(suffix, rowNumber, 3)
  LV_GetText(pos, rowNumber, 4)
  LV_GetText(location, rowNumber, 5)
  LV_GetText(icon, rowNumber, 6)
  LV_GetText(TimeFormat, rowNumber, 7)
  return [dropZone, prefix, suffix, pos, location, icon, TimeFormat]
}

IDropTargetOnDrop_WIDZ(TargetObject, pDataObj, KeyState, X, Y, DropEffect)
{
  Static CF_NATIVE := A_IsUnicode ? 13 : 1 ; CF_UNICODETEXT  : CF_TEXT
  global dropZoneGuis
  ; if valid
  If (pEnumObj := IDataObject_EnumFormatEtc(pDataObj))
  {
    ; Loop through structure
    While IEnumFORMATETC_Next(pEnumObj, FORMATETC)
    {
      ; Populate variables with current item data
      IDataObject_ReadFormatEtc(FORMATETC, Format, Device, Aspect, Index, Type)
     
      ; We only want the text since it will have the shortcut url so continue looping until it shows up
      if(Format != CF_NATIVE)
            continue
      else
      {
        IDataObject_GetData(pDataObj, FORMATETC, Size, Data)
        url := StrGet(&Data)
        response := DropFile(dropZoneGuis, TargetObject.hwnd, url)
        if(response != true)
          msgbox % response
       
        break
      }
    }
  }
}

; ************************************************ All the code below is from https://github.com/AHK-just-me and wasn't written by me
; from https://github.com/AHK-just-me/DoDragDrop/blob/master/sources/IDropTarget.ahk
; ==================================================================================================================================
; IDropTarget interface -> msdn.microsoft.com/en-us/library/ms679679(v=vs.85).aspx
; Requires: IDataObject.ahk
; ==================================================================================================================================
; Creates a new instance of the IDropTarget object.
; Parameters:
;     HWND              -  HWND of the Gui window or control which shall be used as a drop target.
;     UserFuncSuffix    -  The suffix for the names of the user-defined functions which will be called on events (see Remarks).
;     RequiredFormats   -  An array containing the numeric clipboard formats required to permit drop.
;                          If omitted, only 15 (CF_HDROP) used for dropping files will be required.
;     Register          -  If set to True the target will be registered as a drop target on creation.
;                          Otherwise you have to call the RegisterDragDrop() method manually to activate the drop target.
;     UseHelper         -  Use the shell helper object if available (True/False).
; Return value:
;     New IDropTarget instance on success; in case of parameter errors, False.
; Remarks:
;     The interface permits up to 4 user-defined functions which will be called from the related methods:
;        IDropTargetOnEnter      Optional, called from IDropTarget.DragEnter()
;        IDropTargetOnOver       Optional, called from IDropTarget.DragOver()
;        IDropTargetOnLeave      Optional, called from IDropTarget.DragLeave()
;        IDropTargetOnDrop       Mandatory, called from IDropTarget.Drop()
;     The suffix passed in UserFuncSuffix which will be appended to this names to identify the instance specific functions.
;
;     Function parameters:
;        IDropTargetOnDrop and IDropTargetOnEnter must accept at least 6 parameters:
;           TargetObject   -  This instance.
;           pDataObj       -  A pointer to the IDataObject interface on the data object being dropped.
;           KeyState       -  The current state of the mouse buttons and keyboard modifier keys.
;           X              -  The current X coordinate of the cursor in screen coordinates.
;           Y              -  The current Y coordinate of the cursor in screen coordinates.
;           DropEffect     -  The drop effect determined by the Drop() method.
;        IDropTargetOnOver must accept at least 5 parameters:
;           TargetObject   -  This instance.
;           KeyState       -  The current state of the mouse buttons and keyboard modifier keys.
;           X              -  The current X coordinate of the cursor in screen coordinates.
;           Y              -  The current Y coordinate of the cursor in screen coordinates.
;           DropEffect     -  The drop effect determined by the Drop() method.
;        IDropTargetOnLeave must accept at least 1 parameter:
;           TargetObject   -  This instance.
;
;     What the functions must return:
;        The return value of IDropTargetOnDrop, IDropTargetOnEnter, and IDropTargetOnOver is used as the drop effect reported
;        as the result of the drop operation. In the easiest case the function returns the value passed in DropEffect.
;        Otherwise, it must return one of the following values:
;           0 (DROPEFFECT_NONE)
;           1 (DROPEFFECT_COPY)
;           2 (DROPEFFECT_MOVE)
;        The return value of IDropTargetOnLeave is not used.
;
;     As is the interface supports only left-dragging and permits DROPEFFECT_COPY and DROPEFFECT_MOVE. The default effect is
;     DROPEFFECT_COPY. It will be switched to DROPEFFECT_MOVE if either Ctrl or Shift is pressed. You can overwrite the default
;     from the IDropTargetOnEnter user function.
;
;     The dropped data have to be processed completely by the IDropTargetOnDrop user function.
; ==================================================================================================================================
IDropTarget_Create(HWND, UserFuncSuffix, RequiredFormats := "", Register := True, UseHelper := True) {
   Return New IDropTarget(HWND, UserFuncSuffix, RequiredFormats, Register, UseHelper)
}
; ==================================================================================================================================
Class IDropTarget {
   __New(HWND, UserFuncSuffix, RequiredFormats := "", Register := True, UseHelper := True) {
      Static Methods := ["QueryInterface", "AddRef", "Release", "DragEnter", "DragOver", "DragLeave", "Drop"]
      Static Params := (A_PtrSize = 8 ? [3, 1, 1, 5, 4, 1, 5] : [3, 1, 1, 6, 5, 1, 6])
      Static DefaultFormat := 15 ; CF_HDROP
      Static DropFunc := "IDropTargetOnDrop"
      Static EnterFunc := "IDropTargetOnEnter"
      Static OverFunc := "IDropTargetOnOver"
      Static LeaveFunc := "IDropTargetOnLeave"
      Static CLSID_IDTH := "{4657278A-411B-11D2-839A-00C04FD918D0}" ; CLSID_DragDropHelper
      Static IID_IDTH := "{4657278B-411B-11D2-839A-00C04FD918D0}"   ; IID_IDropTargetHelper
      If This.Base.HasKey("Ptr")
         Return False
      UserFunc := DropFunc . UserFuncSuffix
      If !IsFunc(UserFunc) || (Func(UserFunc).MinParams < 6)
         Return False
      This.DropUserFunc := Func(UserFunc)
      UserFunc := EnterFunc . UserFuncSuffix
      If (IsFunc(UserFunc) && (Func(UserFunc).MinParams > 5))
         This.EnterUserFunc := Func(UserFunc)
      UserFunc := OverFunc . UserFuncSuffix
      If (IsFunc(UserFunc) && (Func(UserFunc).MinParams > 4))
         This.OverUserFunc := Func(UserFunc)
      UserFunc := LeaveFunc . UserFuncSuffix
      If (IsFunc(UserFunc) && (Func(UserFunc).MinParams > 0))
         This.LeaveUserFunc := Func(UserFunc)
      This.HWND := HWND
      This.Registered := False
      If IsObject(RequiredFormats)
         This.Required := RequiredFormats
      Else
         This.Required := [DefaultFormat]
      This.PreferredDropEffect := 0
      SizeOfVTBL := (Methods.Length() + 2) * A_PtrSize
      This.SetCapacity("VTBL", SizeOfVTBL)
      This.Ptr := This.GetAddress("VTBL")
      DllCall("RtlZeroMemory", "Ptr", This.Ptr, "UInt", SizeOfVTBL)
      NumPut(This.Ptr + A_PtrSize, This.Ptr + 0, "UPtr")
      For Index, Method In Methods {
         CB := RegisterCallback("IDropTarget." . Method, "", Params[Index], &This)
         NumPut(CB, This.Ptr + 0, A_Index * A_PtrSize, "UPtr")
      }
      This.Helper := ComObjCreate(CLSID_IDTH, IID_IDTH)
      If (Register)
         If !This.RegisterDragDrop()
            Return False
   }
   ; -------------------------------------------------------------------------------------------------------------------------------
   ; Registers window/control as a drop target.
   ; -------------------------------------------------------------------------------------------------------------------------------
   RegisterDragDrop() {
      If !(This.Registered)
         If DllCall("Ole32.dll\RegisterDragDrop", "Ptr", This.HWND, "Ptr", This.Ptr, "Int")
            Return False
      Return (This.Registered := True)
   }
   ; -------------------------------------------------------------------------------------------------------------------------------
   ; Revokes registering of the window/control as a drop target.
   ; This method should be called before the window/control will be destroyed.
   ; -------------------------------------------------------------------------------------------------------------------------------
   RevokeDragDrop() {
      If (This.Registered)
         DllCall("Ole32.dll\RevokeDragDrop", "Ptr", This.HWND)
      Return !(This.Registered := False)
   }
   ; -------------------------------------------------------------------------------------------------------------------------------
   ; Notifies the drag-image manager, if used, to show or hide the drag image.
   ; Parameter:
   ;     Show  -  If true, the drag image will be shown; otherwise it will be hidden.
   ; -------------------------------------------------------------------------------------------------------------------------------
   HelperShow(Show := True) {
      Static HelperShow := A_PtrSize * 7
      If (This.Helper) {
         pVTBL := NumGet(This.Helper + 0, "UPtr")
         , DllCall(NumGet(pVTBL + HelperShow, "UPtr"), "Ptr", This.Helper, "UInt", !!Show)
         Return True
      }
      Return False
   }
   ; ===============================================================================================================================
   ; The following methods must not be called directly, they are reserved for internal and system use.
   ; ===============================================================================================================================
   __Delete() {
      This.RevokeDragDrop()
      While (CB := NumGet(This.Ptr + (A_PtrSize * A_Index), "Ptr"))
         DllCall("GlobalFree", "Ptr", CB)
      If (This.Helper)
         ObjRelease(This.Helper)
   }
   ; -------------------------------------------------------------------------------------------------------------------------------
   QueryInterface(RIID, PPV) {
      ; IUnknown -> msdn.microsoft.com/en-us/library/ms682521(v=vs.85).aspx
      Static IID := "{00000122-0000-0000-C000-000000000046}"
      VarSetCapacity(QID, 80, 0)
      QIDLen := DllCall("Ole32.dll\StringFromGUID2", "Ptr", RIID, "Ptr", &QID, "Int", 40, "Int")
      If (StrGet(&QID, QIDLen, "UTF-16") = IID) {
         NumPut(This, PPV + 0, "Ptr")
         Return 0 ; S_OK
      }
      Else {
         NumPut(0, PPV + 0, "Ptr")
         Return 0x80004002 ; E_NOINTERFACE
      }
   }
   ; -------------------------------------------------------------------------------------------------------------------------------
   AddRef() {
      ; IUnknown -> msdn.microsoft.com/en-us/library/ms691379(v=vs.85).aspx
      ; Reference counting is not needed in this case.
      Return 1
   }
   ; -------------------------------------------------------------------------------------------------------------------------------
   Release() {
      ; IUnknown -> msdn.microsoft.com/en-us/library/ms682317(v=vs.85).aspx
      ; Reference counting is not needed in this case.
      Return 0
   }
   ; -------------------------------------------------------------------------------------------------------------------------------
   DragEnter(pDataObj, grfKeyState, P3 := "", P4 := "", P5 := "") {
      ; DragEnter -> msdn.microsoft.com/en-us/library/ms680106(v=vs.85).aspx
      ; Params 32: IDataObject *pDataObj, DWORD grfKeyState, LONG x, LONG y, DWORD *pdwEffect
      ; Params 64: IDataObject *pDataObj, DWORD grfKeyState, POINTL pt, DWORD *pdwEffect
      Static HelperEnter := A_PtrSize * 3
      Instance := Object(A_EventInfo)
      If (A_PtrSize = 8)
         X := P2 & 0xFFFFFFFF, Y := P2 >> 32
      Else
         X := P2, Y := P3
      Effect := 0
      If !(grfKeyState & 0x02) { ; right-drag isn't supported by default
         For Each, Format In Instance.Required {
            IDataObject_CreateFormatEtc(FORMATETC, Format)
            If (Effect := IDataObject_QueryGetData(pDataObj, FORMATETC))
               Break
         }
      }
      If (Effect) && (Instance.EnterUserFunc)
         Effect := Instance.EnterUserFunc.Call(Instance, pDataObj, grfKeyState, X, Y, Effect)
      Instance.PreferredDropEffect := Effect
      ; If Ctrl and/or Shift is pressed swap the effect
      Effect ^= grfKeyState & 0x0C ? 3 : 0
      ; Call IDropTargetHelper, if created
      If (Instance.Helper) {
         VarSetCapacity(PT, 8, 0)
         , NumPut(X, PT, 0, "Int")
         , NumPut(Y, PT, 0, "Int")
         , pVTBL := NumGet(Instance.Helper + 0, "UPtr")
         , DllCall(NumGet(pVTBL + HelperEnter, "UPtr")
                 , "Ptr", Instance.Helper, "Ptr", Instance.HWND, "Ptr", pDataObj, "Ptr", &PT, "UInt", Effect, "Int")
      }
      NumPut(Effect, (A_PtrSize = 8 ? P4 : P5) + 0, "UInt")
      Return 0 ; S_OK
   }
   ; -------------------------------------------------------------------------------------------------------------------------------
   DragOver(grfKeyState, P2 := "", P3 := "", P4 := "") {
      ; DragOver -> msdn.microsoft.com/en-us/library/ms680129(v=vs.85).aspx
      ; Params 32: DWORD grfKeyState, LONG x, LONG y, DWORD *pdwEffect
      ; Params 64: DWORD grfKeyState, POINTL pt, DWORD *pdwEffect
      Static HelperOver := A_PtrSize * 5
      Instance := Object(A_EventInfo)
      If (A_PtrSize = 8)
         X := P2 & 0xFFFFFFFF, Y := P2 >> 32
      Else
         X := P2, Y := P3
      ; If Ctrl and/or Shift is pressed swap the effect
      Effect := Instance.PreferredDropEffect ^ (grfKeyState & 0x0C ? 3 : 0)
      If (Effect) && (Instance.OverUserFunc)
         Effect := Instance.OverUserFunc.Call(Instance, grfKeyState, X, Y, Effect)
      If (Instance.Helper) {
         VarSetCapacity(PT, 8, 0)
         , NumPut(X, PT, 0, "Int")
         , NumPut(Y, PT, 0, "Int")
         , pVTBL := NumGet(Instance.Helper + 0, "UPtr")
         , DllCall(NumGet(pVTBL + HelperOver, "UPtr"), "Ptr", Instance.Helper, "Ptr", &PT, "UInt", Effect, "Int")
      }
      NumPut(Effect, (A_PtrSize = 8 ? P3 : P4) + 0, "UInt")
      Return 0 ; S_OK
   }
   ; -------------------------------------------------------------------------------------------------------------------------------
   DragLeave() {
      ; DragLeave -> msdn.microsoft.com/en-us/library/ms680110(v=vs.85).aspx
      Static HelperLeave := A_PtrSize * 4
      Instance := Object(A_EventInfo)
      Instance.PreferredDropEffect := 0
      If (Instance.LeaveUserFunc)
         Instance.LeaveUserFunc.Call(Instance)
      If (Instance.Helper) {
         pVTBL := NumGet(Instance.Helper + 0, "UPtr"), DllCall(NumGet(pVTBL + HelperLeave, "UPtr"), "Ptr", Instance.Helper)
      }
      Return 0 ; S_OK
   }
   ; -------------------------------------------------------------------------------------------------------------------------------
   Drop(pDataObj, grfKeyState, P3 := "", P4 := "", P5 := "") {
      ; Drop -> msdn.microsoft.com/en-us/library/ms687242(v=vs.85).aspx
      ; Params 32: IDataObject *pDataObj, DWORD grfKeyState, LONG x, LONG y, DWORD *pdwEffect
      ; Params 64: IDataObject *pDataObj, DWORD grfKeyState, POINTL pt, DWORD *pdwEffect
      Static HelperDrop := A_PtrSize * 6
      Instance := Object(A_EventInfo)
      If (A_PtrSize = 8)
         X := P3 & 0xFFFFFFFF, Y := P3 >> 32
      Else
         X := P3, Y := P4
      Effect := Instance.PreferredDropEffect ^ (grfKeyState & 0x0C ? 3 : 0)
      Effect := Instance.DropUserFunc.Call(Instance, pDataObj, grfKeyState, X, Y, Effect)
      NumPut(Effect, (A_PtrSize = 8 ? P4 : P5) + 0, "UInt")
      If (Instance.Helper) {
         VarSetCapacity(PT, 8, 0)
         , NumPut(X, PT, 0, "Int")
         , NumPut(Y, PT, 0, "Int")
         , pVTBL := NumGet(Instance.Helper + 0, "UPtr")
         , DllCall(NumGet(pVTBL + HelperDrop, "UPtr"), "Ptr", Instance.Helper, "Ptr", pDataObj, "Ptr", &PT, "UInt", Effect, "Int")
      }
      ObjRelease(pDataObj)
      Return 0 ; S_OK
   }
}
; ==================================================================================================================================


; from https://github.com/AHK-just-me/DoDragDrop/blob/master/sources/IDataObject.ahk
; ==================================================================================================================================
; IDataObject interface -> msdn.microsoft.com/en-us/library/ms688421(v=vs.85).aspx
; Partial implementation.
; Requires: IEnumFORMATETC.ahk
; ==================================================================================================================================
IDataObject_EnumFormatEtc(pDataObj) {
   ; EnumFormatEtc -> msdn.microsoft.com/en-us/library/ms683979(v=vs.85).aspx
   ; DATADIR_GET = 1
   Static EnumFormatEtc := A_PtrSize * 8
   pVTBL := NumGet(pDataObj + 0, "UPtr")
   If !DllCall(NumGet(pVTBL + EnumFormatEtc, "UPtr"), "Ptr", pDataObj, "UInt", 1, "PtrP", ppenumFormatEtc, "Int")
      Return ppenumFormatEtc
   Return False
}
; ==================================================================================================================================
IDataObject_GetData(pDataObj, ByRef FORMATETC, ByRef Size, ByRef Data) {
   ; GetData -> msdn.microsoft.com/en-us/library/ms678431(v=vs.85).aspx
   Static GetData := A_PtrSize * 3
   Data := ""
   , Size := -1
   , VarSetCapacity(STGMEDIUM, 24, 0) ; 64-bit
   , pVTBL := NumGet(pDataObj + 0, "UPtr")
   If !DllCall(NumGet(pVTBL + GetData, "UPtr"), "Ptr", pDataObj, "Ptr", &FORMATETC, "Ptr", &STGMEDIUM, "Int") {
      If (NumGet(STGMEDIUM, "UInt") = 1) { ; TYMED_HGLOBAL
         hGlobal := NumGet(STGMEDIUM, A_PtrSize, "UPtr")
         , pGlobal := DllCall("GlobalLock", "Ptr", hGlobal, "Uptr")
         , Size := DllCall("GlobalSize", "Ptr", hGlobal, "UPtr")
         , VarSetCapacity(Data, Size, 0)
         , DllCall("RtlMoveMemory", "Ptr", &Data, "Ptr", pGlobal, "Ptr", Size)
         , DllCall("GlobalUnlock", "Ptr", hGlobal)
         , DllCall("Ole32.dll\ReleaseStgMedium", "Ptr", &STGMEDIUM)
         Return True
      }
      DllCall("Ole32.dll\ReleaseStgMedium", "Ptr", &STGMEDIUM)
   }
   Return False
}
; ==================================================================================================================================
IDataObject_QueryGetData(pDataObj, ByRef FORMATETC) {
   ; QueryGetData -> msdn.microsoft.com/en-us/library/ms680637(v=vs.85).aspx
   Static QueryGetData := A_PtrSize * 5
   pVTBL := NumGet(pDataObj + 0, "UPtr")
   Return !DllCall(NumGet(pVTBL + QueryGetData, "UPtr"), "Ptr", pDataObj, "Ptr", &FORMATETC, "Int")
}
; ==================================================================================================================================
IDataObject_SetData(pDataObj, ByRef FORMATETC, ByRef STGMEDIUM) {
   ; SetData -> msdn.microsoft.com/en-us/library/ms686626(v=vs.85).aspx
   Static SetData := A_PtrSize * 7
   pVTBL := NumGet(pDataObj + 0, "UPtr")
   Return !DllCall(NumGet(pVTBL + SetData, "UPtr"), "Ptr", pDataObj, "Ptr", &FORMATETC, "Ptr", &STGMEDIUM, "Int", True, "Int")
}
; ==================================================================================================================================
; Auxiliary functions to get/set data of the data object.
; ==================================================================================================================================
; FORMATETC structure -> msdn.microsoft.com/en-us/library/ms682242(v=vs.85).aspx
; ==================================================================================================================================
IDataObject_CreateFormatEtc(ByRef FORMATETC, Format, Aspect := 1, Index := -1, Tymed := 1) {
   ; DVASPECT_CONTENT = 1, Index all data = -1, TYMED_HGLOBAL = 1
   VarSetCapacity(FORMATETC, 32, 0) ; 64-bit
   , NumPut(Format, FORMATETC, 0, "Ushort")
   , NumPut(Aspect, FORMATETC, A_PtrSize = 8 ? 16 : 8 , "UInt")
   , NumPut(Index, FORMATETC, A_PtrSIze = 8 ? 20 : 12, "Int")
   , NumPut(Tymed, FORMATETC, A_PtrSize = 8 ? 24 : 16, "UInt")
   Return &FORMATETC
}
; ==================================================================================================================================
IDataObject_ReadFormatEtc(ByRef FORMATETC, ByRef Format, ByRef Device, ByRef Aspect, ByRef Index, ByRef Tymed) {
   Format := NumGet(FORMATETC, OffSet := 0, "UShort")
   , Device := NumGet(FORMATETC, Offset += A_PtrSize, "UPtr")
   , Aspect := NumGet(FORMATETC, Offset += A_PtrSize, "UInt")
   , Index  := NumGet(FORMATETC, Offset += 4, "Int")
   , Tymed  := NumGet(FORMATETC, Offset += 4, "UInt")
}
; ==================================================================================================================================
; Get/Set format data.
; ==================================================================================================================================
IDataObject_GetDroppedFiles(pDataObj, ByRef DroppedFiles) {
   ; msdn.microsoft.com/en-us/library/bb773269(v=vs.85).aspx
   IDataObject_CreateFormatEtc(FORMATETC, 15) ; CF_HDROP
   DroppedFiles := []
   If IDataObject_GetData(pDataObj, FORMATETC, Size, Data) {
      Offset := NumGet(Data, 0, "UInt")
      CP := NumGet(Data, 16, "UInt") ? "UTF-16" : "CP0"
      Shift := (CP = "UTF-16")
      While (File := StrGet(&Data + Offset, CP)) {
         DroppedFiles.Push(File)
         Offset += (StrLen(File) + 1) << Shift
      }
   }
   Return DroppedFiles.Length()
}
; ==================================================================================================================================
IDataObject_GetLogicalDropEffect(pDataObj, ByRef DropEffect) {
   Static LogicalDropEffect := DllCall("RegisterClipboardFormat", "Str", "Logical Performed DropEffect")
   IDataObject_CreateFormatEtc(FORMATETC, LogicalDropEffect)
   DropEffect := ""
   If IDataObject_GetData(pDataObj, FORMATETC, Size, Data) {
      DropEffect := NumGet(Data, "UChar")
      Return True
   }
   Return False
}
; ==================================================================================================================================
IDataObject_GetPerformedDropEffect(pDataObj, ByRef DropEffect) {
   Static PerformedDropEffect := DllCall("RegisterClipboardFormat", "Str", "Performed DropEffect")
   IDataObject_CreateFormatEtc(FORMATETC, PerformedDropEffect)
   DropEffect := ""
   If IDataObject_GetData(pDataObj, FORMATETC, Size, Data) {
      DropEffect := NumGet(Data, "UChar")
      Return True
   }
   Return False
}
; ==================================================================================================================================
IDataObject_GetText(pDataObj, ByRef Txt) {
   Static CF_NATIVE := A_IsUnicode ? 13 : 1 ; CF_UNICODETEXT : CF_TEXT
   IDataObject_CreateFormatEtc(FORMATETC, CF_NATIVE)
   Txt := ""
   If IDataObject_GetData(pDataObj, FORMATETC, Size, Data) {
      Txt := StrGet(Data, Size >> !!A_IsUnicode)
      Return True
   }
   Return False
}
; ==================================================================================================================================
IDataObject_SetLogicalDropEffect(pDataObj, DropEffect) {
   Static LogicalDropEffect := DllCall("RegisterClipboardFormat", "Str", "Logical Performed DropEffect")
   IDataObject_CreateFormatEtc(FORMATETC, LogicalDropEffect)
   , VarSetCapacity(STGMEDIUM, 24, 0) ; 64-bit
   , NumPut(1, STGMEDIUM, "UInt") ; TYMED_HGLOBAL
   ; 0x42 = GMEM_MOVEABLE (0x02) | GMEM_ZEROINIT (0x40)
   , hMem := DllCall("GlobalAlloc", "UInt", 0x42, "UInt", 4, "UPtr")
   , pMem := DllCall("GlobalLock", "Ptr", hMem)
   , NumPut(DropEffect, pMem + 0, "UChar")
   , DllCall("GlobalUnlock", "Ptr", hMem)
   , NumPut(hMem, STGMEDIUM, A_PtrSize, "UPtr")
   Return IDataObject_SetData(pDataObj, FORMATETC, STGMEDIUM)
}
; ==================================================================================================================================
IDataObject_SetPerformedDropEffect(pDataObj, DropEffect) {
   Static PerformedDropEffect := DllCall("RegisterClipboardFormat", "Str", "Performed DropEffect")
   IDataObject_CreateFormatEtc(FORMATETC, PerformedDropEffect)
   , VarSetCapacity(STGMEDIUM, 24, 0) ; 64-bit
   , NumPut(1, STGMEDIUM, "UInt") ; TYMED_HGLOBAL
   ; 0x42 = GMEM_MOVEABLE (0x02) | GMEM_ZEROINIT (0x40)
   , hMem := DllCall("GlobalAlloc", "UInt", 0x42, "UInt", 4, "UPtr")
   , pMem := DllCall("GlobalLock", "Ptr", hMem)
   , NumPut(DropEffect, pMem + 0, "UChar")
   , DllCall("GlobalUnlock", "Ptr", hMem)
   , NumPut(hMem, STGMEDIUM, A_PtrSize, "UPtr")
   Return IDataObject_SetData(pDataObj, FORMATETC, STGMEDIUM)
}
; ==================================================================================================================================
IDataObject_SHFileOperation(pDataObj, TargetPath, Operation, HWND := 0) {
   ; SHFileOperation -> msdn.microsoft.com/en-us/library/bb762164(v=vs.85).aspx
   If Operation Not In 1,2
      Return False
   IDataObject_CreateFormatEtc(FORMATETC, 15) ; CF_HDROP
   If IDataObject_GetData(pDataObj, FORMATETC, Size, Data) {
      Offset := NumGet(Data, 0, "UInt") ; offset of the file list
      IsUnicode := NumGet(Data, 16, "UInt") ; 1: Unicode, 0: ANSI
      TargetLen := StrPut(TargetPath, IsUnicode ? "UTF-16" : "CP0") + 2
      VarSetCapacity(Target, TargetLen << !!IsUnicode, 0)
      StrPut(TargetPath, &Target, IsUnicode ? "UTF-16" : "CP0")
      SHFOSLen := A_PtrSize * (A_PtrSize = 8 ? 7 : 8)
      VarSetCapacity(SHFOS, SHFOSLen, 0) ; SHFILEOPSTRUCT
      NumPut(HWND, SHFOS, 0, "UPtr")
      NumPut(Operation, SHFOS, A_PtrSize, "UInt") ; FO_MOVE = 1, FO_COPY = 2, so we have to swap the DropEffect
      NumPut(&Data + Offset, SHFOS, A_PtrSize * 2, "UPtr")
      NumPut(&Target, SHFOS, A_PtrSize * 3, "UPtr")
      NumPut(0x0200, SHFOS, A_PtrSize * 4, "UInt") ; FOF_NOCONFIRMMKDIR
      If (IsUnicode)
         Return DllCall("Shell32.dll\SHFileOperationW", "Ptr", &SHFOS, "Int")
      Else
         Return DllCall("Shell32.dll\SHFileOperationA", "Ptr", &SHFOS, "Int")
   }
}
; ==================================================================================================================================

; from https://github.com/AHK-just-me/DoDragDrop/blob/master/sources/IEnumFORMATETC.ahk
; ==================================================================================================================================
; IEnumFORMATETC interface -> msdn.microsoft.com/en-us/library/ms682337(v=vs.85).aspx
; Partial implementation, 'Clone' method is missing.
; ==================================================================================================================================
IEnumFORMATETC_Next(pEnumObj, ByRef FORMATETC) {
   ; Next -> msdn.microsoft.com/en-us/library/dd542673(v=vs.85).aspx
   Static Next := A_PtrSize * 3
   VarSetCapacity(FORMATETC, A_PtrSize = 8 ? 32 : 20, 0)
   , pVTBL := NumGet(pEnumObj + 0, "UPtr")
   Return !DllCall(NumGet(pVTBL + Next, "UPtr"), "Ptr", pEnumObj, "UInt", 1, "Ptr", &FORMATETC, "Ptr", 0, "Int")
}
; ----------------------------------------------------------------------------------------------------------------------------------
IEnumFORMATETC_Reset(pEnumObj) {
   ; Reset -> msdn.microsoft.com/en-us/library/dd542674(v=vs.85).aspx
   Static Reset := A_PtrSize * 5
   pVTBL := NumGet(pEnumObj + 0, "UPtr")
   Return !DllCall(NumGet(pVTBL + Reset, "UPtr"), "Ptr", pEnumObj, "Int")
}
; ----------------------------------------------------------------------------------------------------------------------------------
IEnumFORMATETC_Skip(pEnumObj, ItemCount) {
   ; Skip -> msdn.microsoft.com/en-us/library/dd542674(v=vs.85).aspx
   Static Skip := A_PtrSize * 4
   pVTBL := NumGet(pEnumObj + 0, "UPtr")
   Return !DllCall(NumGet(pVTBL + Skip, "UPtr"), "Ptr", pEnumObj, "UInt", ItemCount, "Int")
}
; ==================================================================================================================================

11
Post New Requests Here / Re: IDEA: Drop Zone for Web Images
« on: October 12, 2015, 06:17 AM »
lifeweaver

I have run the AHK script but am hitting a problem. At present I have not implemented the registry bypass for the internet warning, but assume that should not be an issue.

I can drag an image, but as I drag across the desktop, I get a + by the cursor as expected, but as soon as I hover the dropzone I get a barred icon.

This means the gui is not accepting the type of information that is trying to be dragged to it.

Can you give me some more information?
Which browser you were using?
Is it with every image on different sites or just images on one site?
Can you give me the URL to a specific file that doesn't work?

12
Post New Requests Here / Re: IDEA: Drop Zone for Web Images
« on: October 09, 2015, 02:04 PM »
My irfanview/bat method with Pale Moon web browser gets the actual, full size, image, from the google image search results list. Also, no security warning has ever been shown on my Windows 10 system.

Nice! Does it do the same for yahoo/bing?
I was able to get the image just fine from google also as their url contains the original url, but yahoo/bing didn't.

From my testing the security warning only happens for Internet Explorer and only if have or have had the Internet Security settings turned to 'High' for the Internet zone.

13
Post New Requests Here / Re: IDEA: Drop Zone for Web Images
« on: October 09, 2015, 01:43 PM »
Hi magician62,

Here is a script for you written in AutoHotkey.
Also I had the same problem with the security thing and fixed it by following directions in this link.


Script runs on: Windows 7 Professional, AutoHotkey 1.1.22.07 Unicode build

To use:
  • Install AutoHotkey, if you have problems see their tutorial about running scripts
  • Copy the script into a '.ahk' file
  • Double click on the script icon to start it
  • Fill out the form fields for a new dropzone
  • Click the 'DropZone Position' button to select the size of the dropZone
    • Click and hold the mouse button to select the top left corner of the dropZone
    • Let go of the mouse to select the bottom left corner of the dropZone
  • Click the 'Create/Update' button to save the new dropzone
  • Close the config window to create the dropZones
  • Now you merely need to drag images from the browsers to the dropZones!

Notes:
The next time you start the script the dropZones will be created instantly and the config window won't open automatically.
If you need to open the config window again click the 'H' icon on your taskbar tray.
You can hide the dropZone windows by right clicking on the try icon and selecting 'Toggle DropZones'.
The tray icon also allows you to exit the script.

Special Note:
Please realize that when you do an image search on yahoo/bing/etc you are seeing thumbnails not actual images as such. Trying to drag these images will only create a shortcut to wherever that thumbnail goes, not an image.

For google I able to find the actual image so their search is good, I might be able to figure out how to do it in the instances of the other other search engines but have exhausted all the time I have for this week.

; -------------------------------------------------- Auto Execute --------------------------------------------------
#Persistent
#NoEnv  ; Recommended for performance and compatibility with future AutoHotkey releases.
SetWorkingDir %A_ScriptDir%  ; Ensures a consistent starting directory.
#SingleInstance force
SetBatchLines, -1
SetKeyDelay, -1
title := "Web Images Drop Zone"

iniPath := A_ScriptDir . "\WIDZ.data"


Menu, Tray, NoStandard
Menu, Tray, Add, &Config, Show
Menu, Tray, Default, &Config
Menu, Tray, Add, &Toggle DropZones, toggleDropZones
Menu, Tray, Add, E&xit, Exit
Menu, Tray, Click, 1
Menu, Tray, Tip, %title%
LoadSettings(iniPath)

if(firstTimeOpenShowConfig)
{
  firstTimeOpenShowConfig := false
  gosub, show
  WinWaitClose, %title% - Config
}

dropZoneGuis := CreateDropZoneGuis(iniPath)
OnExit("Exit")
return

; -------------------------------------------------- Labels --------------------------------------------------
createOrUpdateDropZone:
  ; Get dropZone info info
  GuiControlGet, dropZone,, dropZone
  GuiControlGet, timeFormat,, timeFormat
  GuiControlGet, fileDrop,, fileDrop
  GuiControlGet, icon,, icon
  GuiControlGet, prefix,, prefix
  GuiControlGet, suffix,, suffix
 
  ; Check if the dropZone already exists
  Loop % LV_GetCount()
  {
    Lv_GetText(dropZoneName, A_index)
    if(dropZoneName = dropZone)
    {
      LV_Modify(A_Index,,dropZone, prefix, suffix, lastDropWindowPos, fileDrop, icon, timeFormat)
      return
    }
  }
 
  LV_Add(,dropZone, prefix, suffix, lastDropWindowPos, fileDrop, icon, timeFormat)
return

drawDropWindow:
  ;http://www.autohotkey.com/board/topic/111196-drawing-boxes-on-screen-need-help-finishing/?p=655416
  GuID := "dropzone"
  LetUserSelectRect(GuiID, x1, y1, x2, y2)
  lastDropWindowPos := x1 . ":" . x2 . ":" . y1 . ":" . y2
  GuiControl,, pos, %lastDropWindowPos%

  Loop 4
    Gui, % GuiID A_Index ": Destroy"
return

dropZoneList:
  ; populate fields on a double click
  if(A_GuiEvent = "Normal")
    CopyDropZoneToForm(A_EventInfo)
  else if(A_GuiEvent = "RightClick")
    DeleteDropZoneData(A_EventInfo)
return

Exit:
  IfWinExist, %title% - Config
    SaveData(iniPath)
  ExitApp
return

fileDrop:
  FileSelectFolder, fileDrop,,, Select file folder
  if(fileDrop)
    GuiControl, , fileDrop, %fileDrop%
  else
    msgbox your folder wasn't found please select a valid folder, i.e. no the virtual ones like Libraries/Documents/Music/etc
return

icon:
  FileSelectFile, icon, 3, %A_MyDocuments%,Choose an Icon, Image files (*.jpg; *.jpeg; *.gif; *.png)
  GuiControl, , icon, %icon%
return

show:
  DeleteAllDropZones(dropZoneGuis)
  Gui, WebImageDropZoneConfig: New, hwndWIDZ, Web Image Drop Zone
  global WIDZ
  Gui, Add, ListView, x12 y10 w450 r15 gdropZoneList AltSubmit, DropZone|Prefix|Suffix|Pos|Save Path|Icon|TimeFormat
  Gui, Add, Text, x12 y300 w60 h20 , DropZone:
  Gui, Add, Edit, x72 y300 w90 h20 vdropZone , dropzone
  Gui, Add, Text, x172 y300 w60 h20 , TimeFormat:
  Gui, Add, Edit, x232 y300 w230 h20 vtimeFormat , yyyy-MM-dd_hh-ss
 
  Gui, font, s11 bold, MS sans serif
  Gui, Add, Link, x462 y300 w10 h20 , <a href="http://www.autohotkey.com/docs/commands/FormatTime.htm">?</a>
  gui, font
 
  Gui, Add, Text, x12 y330 w50 h20 , File Drop:
  Gui, Add, Edit, x72 y330 w320 h20 vfileDrop , file drop
  Gui, Add, Button, x392 y330 w70 h20 gfileDrop , Browse
 
  Gui, Add, Text, x12 y360 w40 h20 , Icon:
  Gui, Add, Edit, x72 y360 w320 h20 vicon, Edit
  Gui, Add, Button, x392 y360 w70 h20 gicon , Browse
 
  Gui, Add, Text, x12 y390 w40 h20 , Prefix:
  Gui, Add, Edit, x72 y390 w110 h20 vprefix , prefix
  Gui, Add, Text, x192 y390 w40 h20 , Suffix:
  Gui, Add, Edit, x232 y390 w110 h20 vsuffix , suffix
  Gui, Add, Button, x12 y420 w110 h20 gdrawDropWindow, DropZone Position
  Gui, Add, Edit, x132 y420 w210 h20 ReadOnly vpos , 0:100:0:100
  Gui, Add, Button, x352 y390 w110 h50 gcreateOrUpdateDropZone , Create/Update
 
  ; Generated using SmartGUI Creator 4.0
  Gui, Show, x138 y90 h450 w479, %title% - Config
  PopulateDropZoneList(iniPath)
  OnMessage(0x200, "GuiToolTip")
  Loop 6
      LV_ModifyCol(A_Index, "AutoHdr")
 
return

toggleDropZones:
for index, array in dropZoneGuis
{
  hwnd := array["hwnd"]
 
  if WinExist("ahk_id " . hwnd)
    gui, %hwnd%:Hide
  else
    gui, %hwnd%:Show
}
return

WebImageDropZoneConfigGuiClose:
WebImageDropZoneConfigGuiEscape:
  IfWinExist, %title% - Config
    SaveData(iniPath)
  Gui, WebImageDropZoneConfig:Destroy
 
  ; Update the dropzones
  dropZoneGuis := CreateDropZoneGuis(iniPath)
return



; -------------------------------------------------- Methods --------------------------------------------------
CopyDropZoneToForm(eventInfo)
{
  global lastDropWindowPos
  ; get row text
  LV_GetText(dropZone, eventInfo, 1)
  LV_GetText(prefix, eventInfo, 2)
  LV_GetText(suffix, eventInfo, 3)
  LV_GetText(pos, eventInfo, 4)
  LV_GetText(fileDrop, eventInfo, 5)
  LV_GetText(icon, eventInfo, 6)
  LV_GetText(TimeFormat, eventInfo, 7)
 
  ; update fields
  GuiControl,, dropZone, %dropZone%
  GuiControl,, prefix, %prefix%
  GuiControl,, suffix, %suffix%
  GuiControl,, pos, %pos%
  lastDropWindowPos := pos
  GuiControl,, fileDrop, %fileDrop%
  GuiControl,, icon, %icon%
  GuiControl,, TimeFormat, %TimeFormat%
}

CreateDropZoneGuis(path)
{
  dropZoneGuis := Array()
  dropZoneData := LoadData(path)
 
  for index, array in dropZoneData
  {
    extractedPos := StrSplit(array["pos"], ":")
    guiHwnd := DropZoneGui(array["dropZone"], array["icon"], extractedPos[1], extractedPos[2], extractedPos[3], extractedPos[4])
    IDT_WIDZ := IDropTarget_Create(guiHwnd, "_WIDZ", [1, 13, 15]) ; CF_TEXT, CF_UNICODETEXT, CF_HDROP
    dropZoneGuis.insert({dropZone: array["dropZone"], hwnd: guiHwnd, iDropTarget: IDT_WIDZ})
  }

  return dropZoneGuis
}

; Custom message box for the confirm dropzone delete.
Custom_MsgBox(msg_text)
{
  global showCancelConfirm, dontShowAgain
  Gui, CustomMsgBox: New, hwndCMB
  Gui, Add, Text, x12 y10 w430 h70, %msg_text%
  Gui, Add, CheckBox, x12 y90 w140 h30 vdontShowAgain , Don't show this again?
  Gui, Add, Button, x232 y90 w100 h30 gCustomMsgBoxGuiSubmit , OK
  Gui, Add, Button, x342 y90 w100 h30 gCustomMsgBoxGuiSubmit Default , Cancel
  ; Generated using SmartGUI Creator 4.0
  Gui, Show
  WinWaitClose, ahk_id %CMB%
  return buttonClicked
 
  CustomMsgBoxGuiSubmit:
    GuiControlGet, dontShowAgainChecked,, dontShowAgain
    if(dontShowAgainChecked)
      showCancelConfirm := false
   
    buttonClicked := A_GuiControl
    gosub, CustomMsgBoxGuiClose
  return

  CustomMsgBoxGuiClose:
  CustomMsgBoxGuiEscape:
  Gui, CustomMsgBox:Destroy
  return
}

DeleteDropZoneData(eventInfo)
{
  global showCancelConfirm
 
  Gui, WebImageDropZoneConfig:Default
  LV_GetText(thisDropZone, eventInfo)
 
  if(showCancelConfirm)
  {
    if(Custom_MsgBox("Are you sure you want to delete the '" . thisDropZone . "' drop zone?") = "OK")
      LV_Delete(eventInfo)
  }
  else
    LV_Delete(eventInfo)
}

DeleteAllDropZones(dropZoneGuis)
{
  ; dropZone, hwnd, iDropTarget
  for index, array in dropZoneGuis
  {
    ;~ Revoke the registration of the ListView as a potential target for OLE drag-and-drop operations.
    array["iDropTarget"].RevokeDragDrop()
    hwnd := array["hwnd"]
    Gui, %hwnd%:Destroy
  }
}

determineRealURL(url)
{
  origUrl := url
  if(InStr(url, "google.com"))
    RegExMatch(url, "(?<=\?imgurl=).*?(?=&)", url)
 
  ;~ msgbox % "url: " url "`n`norigUrl: " origUrl
  return url
}

downloadFile(origUrl, foundUrl, dropZoneInfo)
{
  SplitPath, foundUrl,,, imageFileExt
  fileDropDir := dropZoneInfo["fileDrop"]
  prefix := dropZoneInfo["prefix"]
  suffix := dropZoneInfo["suffix"]
  timeFormat := dropZoneInfo["timeFormat"]
  FormatTime, nowTime,, % timeFormat

  Inputbox, fileName, File Name Entry, Please Enter a file name. (no extension),,,,,,,, %prefix% %nowTime% %suffix%
  if(fileName = "")
    fileName :=  %prefix% %nowTime% %suffix%
 
 
  ; Only try to download the file if its a jpg, otherwise create a link
  if(RegExMatch(foundUrl, "\.\w{3,4}$"))
  {
    try
    {
      URLDownloadToFile, %foundUrl%, %fileDropDir%\%fileName%.%imageFileExt%
      if(ErrorLevel)
        return "Unable to download '" . foundUrl . "' parsed from '" . origUrl . "'"
     
      return true
    }
    catch, e
    {
      msgbox % "ErrorLevel: " ErrorLevel "`nA_LastError: " A_LastError "`nmessage: " e.message "`nWhat: " e.what "`nExtra: " e.extra "`nLine: " e.line
      return "Unable to download '" . foundUrl . "' parsed from '" . origUrl . "'"
    }
  }
  else
  {
    FileCreateShortcut, %foundUrl%, %fileDropDir%\%fileName%.lnk
    TrayTip, Link Created, Couldn't find image so a link was created instead., 15
    return true
  }
}

DropFile(dropZoneGuis, targetHwnd, url)
{
  dropZoneInfo := findDropZoneInfo(dropZoneGuis, targetHwnd)
  foundUrl := determineRealURL(url)
 
  return downloadFile(url, foundUrl, dropZoneInfo)
}

; Called to create/display dropZone gui
DropZoneGui(label, icon, x1, x2, y1, y2)
{
  static index = 0
  index += 1
 
  ; If no pos data was provided
  if(!x1)
  {
    x1 := 0
    x2 := 100
    y1 := 0
    y1 := 100
  }
 
  width := x2 - x1
  height := y2 - y1
  labelWidth := StrLen(label) * 25
  labelHeight := 32
 
  ; If the label is too long we set the labelsPerRow to 1 otherwise nothing would be displayed
  labelsPerColumn := height / labelHeight < 1 ? 1 : height / labelHeight
  labelsPerRow := width / labelWidth < 1 ? 1 : width / labelWidth

  CustomColor = EEAA99  ; Can be any RGB color (it will be made transparent below).
  Gui, New, hwndDZG%index% +LastFound +AlwaysOnTop -Caption +ToolWindow ; +ToolWindow avoids a taskbar button and an alt-tab menu item.
  Gui, Color, %CustomColor%
 
  ; If an icon was provided make it the size of the gui else use the label text
  if(icon)
    Gui, Add, Picture, w%width% h%height%, %icon%
  else
  {
    Gui, Font, s32  ; Set a large font size (32-point).
    x := 0
   
    Loop %labelsPerRow%
    {
      y := 0
      Loop %labelsPerColumn%
      {
        Gui, Add, Text, % "x" x " y" y " cLime", %label%
        y += 50
      }
      x += labelWidth
    }
  }
  ; Make all pixels of this color transparent and make the text itself translucent (150):
  WinSet, TransColor, %CustomColor% 150
  Gui, Show, x%x1% y%y1% w%width% h%height% NoActivate  ; NoActivate avoids deactivating the currently active window.
  return DZG%index%
}

Exit(ExitReason, ExitCode)
{
  global dropZoneGuis

  DeleteAllDropZones(dropZoneGuis)
  ExitApp
}

findDropZoneInfo(dropZoneGuis, targetHwnd)
{
  global iniPath
 
  data := LoadData(iniPath)
  for index, array in dropZoneGuis
    if(array["hwnd"] = targetHwnd)
      for dindex, darray in data
        if(darray["dropZone"] = array["dropZone"])
          return darray
}

GuiToolTip(wParam, lParam, Msg)
{
  MouseGetPos,,,mhwnd, OutputVarControl
 
  if(OutputVarControl = "Button3" && mhwnd = WIDZ)
Help := "After pressing 'Dropzone Position' move your mouse to the desired location; hold down the mouse button then move the mouse to select your area."
  else
    Help := ""

  ToolTip % Help
}

LetUserSelectRect(ByRef ID, ByRef X1, ByRef Y1, ByRef X2, ByRef Y2)
{ ;http://www.autohotkey.com/board/topic/111196-drawing-boxes-on-screen-need-help-finishing/?p=655416
    CoordMode, Mouse ; Required: change coord mode to screen vs relative.
    static r := 3
    ; Create the "selection rectangle" GUIs (one for each edge).
    Loop 4 {
        Gui, % ID A_Index ": -Caption +ToolWindow +AlwaysOnTop"
        Gui, % ID A_Index ": Color", Red
    }
    ; Disable LButton.
    Hotkey, *LButton, lusr_return, On
    ; Wait for user to press LButton.
    KeyWait, LButton, D
    ; Get initial coordinates.
    MouseGetPos, xorigin, yorigin
    ; Set timer for updating the selection rectangle.
    SetTimer, lusr_update, 10
    ; Wait for user to release LButton.
    KeyWait, LButton
    ; Re-enable LButton.
    Hotkey, *LButton, Off
    ; Disable timer.
    SetTimer, lusr_update, Off
    return
 
    lusr_update:
        CoordMode, Mouse ; Required: change coord mode to screen vs relative.
        MouseGetPos, x, y
        if (x = xlast && y = ylast)
            ; Mouse hasn't moved so there's nothing to do.
            return
        if (x < xorigin)
             x1 := x, x2 := xorigin
        else x2 := x, x1 := xorigin
        if (y < yorigin)
             y1 := y, y2 := yorigin
        else y2 := y, y1 := yorigin
        ; Update the "selection rectangle".
        Gui, % ID "1:Show", % "NA X" x1 " Y" y1 " W" x2-x1 " H" r
        Gui, % ID "2:Show", % "NA X" x1 " Y" y2-r " W" x2-x1 " H" r
        Gui, % ID "3:Show", % "NA X" x1 " Y" y1 " W" r " H" y2-y1
        Gui, % ID "4:Show", % "NA X" x2-r " Y" y1 " W" r " H" y2-y1
    lusr_return:
    return
}

;~ LV_Add(, array[1], array[2], array[3], array[4], array[5], array[6], array[7])
LoadData(path)
{
  FileRead, data, %path%
  dataArray := Object()
 
  Loop, Parse, data, `n, `r`n
  {
    ; If not the setttings row
    if(A_Index != 1)
    {
      array := StrSplit(A_LoopField, "|")
      if(array[1])
      {
        dataArray.Insert({dropZone: array[1], prefix: array[2], suffix: array[3], pos: array[4], fileDrop: array[5], icon: array[6], timeFormat: array[7]})
      }
    }
  }
 
  return dataArray
}

LoadSettings(path)
{
  global showCancelConfirm, firstTimeOpenShowConfig
 
  FileReadLine, data, %path%, 1
 
  array := StrSplit(data, "|")
  firstTimeOpenShowConfig := array[1] = 0 ? false : true
  showCancelConfirm := array[2] = 0 ? false : true
}

PopulateDropZoneList(path)
{
  data := LoadData(path)
  for index, array in data
    LV_Add(, array["dropZone"], array["prefix"], array["suffix"], array["pos"], array["fileDrop"], array["icon"], array["timeFormat"])
}

SaveData(path)
{
  global showCancelConfirm, firstTimeOpenShowConfig
  FileCopy, %path%, %path%.bak
  FileDelete, %path%
  data := ""
 
  ; Save the setttings
  data := firstTimeOpenShowConfig . "|"  . showCancelConfirm . "`n"
  FileAppend, %data%, %path%
 
  ; Save the list data
  Loop, % LV_GetCount()
  {
    rowData := RowText(A_Index)
    data := rowData[1] . "|" .  rowData[2] . "|" .  rowData[3] . "|" .  rowData[4] . "|" .  rowData[5] . "|" .  rowData[6] . "|" . rowData[7] . "`n"
    FileAppend, %data%, %path%
  }
  FileDelete, %path%.bak
}

RowText(rowNumber)
{
  LV_GetText(dropZone, rowNumber, 1)
  LV_GetText(prefix, rowNumber, 2)
  LV_GetText(suffix, rowNumber, 3)
  LV_GetText(pos, rowNumber, 4)
  LV_GetText(location, rowNumber, 5)
  LV_GetText(icon, rowNumber, 6)
  LV_GetText(TimeFormat, rowNumber, 7)
  return [dropZone, prefix, suffix, pos, location, icon, TimeFormat]
}

IDropTargetOnDrop_WIDZ(TargetObject, pDataObj, KeyState, X, Y, DropEffect)
{
  Static CF_NATIVE := A_IsUnicode ? 13 : 1 ; CF_UNICODETEXT  : CF_TEXT
  global dropZoneGuis
  ; if valid
  If (pEnumObj := IDataObject_EnumFormatEtc(pDataObj))
  {
    ; Loop through structure
    While IEnumFORMATETC_Next(pEnumObj, FORMATETC)
    {
      ; Populate variables with current item data
      IDataObject_ReadFormatEtc(FORMATETC, Format, Device, Aspect, Index, Type)
     
      ; We only want the text since it will have the shortcut url so continue looping until it shows up
      if(Format != CF_NATIVE)
            continue
      else
      {
        IDataObject_GetData(pDataObj, FORMATETC, Size, Data)
        url := StrGet(&Data)
        response := DropFile(dropZoneGuis, TargetObject.hwnd, url)
        if(response != true)
          msgbox % response
       
        break
      }
    }
  }
}

; ************************************************ All the code below is from https://github.com/AHK-just-me and wasn't written by me
; from https://github.com/AHK-just-me/DoDragDrop/blob/master/sources/IDropTarget.ahk
; ==================================================================================================================================
; IDropTarget interface -> msdn.microsoft.com/en-us/library/ms679679(v=vs.85).aspx
; Requires: IDataObject.ahk
; ==================================================================================================================================
; Creates a new instance of the IDropTarget object.
; Parameters:
;     HWND              -  HWND of the Gui window or control which shall be used as a drop target.
;     UserFuncSuffix    -  The suffix for the names of the user-defined functions which will be called on events (see Remarks).
;     RequiredFormats   -  An array containing the numeric clipboard formats required to permit drop.
;                          If omitted, only 15 (CF_HDROP) used for dropping files will be required.
;     Register          -  If set to True the target will be registered as a drop target on creation.
;                          Otherwise you have to call the RegisterDragDrop() method manually to activate the drop target.
;     UseHelper         -  Use the shell helper object if available (True/False).
; Return value:
;     New IDropTarget instance on success; in case of parameter errors, False.
; Remarks:
;     The interface permits up to 4 user-defined functions which will be called from the related methods:
;        IDropTargetOnEnter      Optional, called from IDropTarget.DragEnter()
;        IDropTargetOnOver       Optional, called from IDropTarget.DragOver()
;        IDropTargetOnLeave      Optional, called from IDropTarget.DragLeave()
;        IDropTargetOnDrop       Mandatory, called from IDropTarget.Drop()
;     The suffix passed in UserFuncSuffix which will be appended to this names to identify the instance specific functions.
;
;     Function parameters:
;        IDropTargetOnDrop and IDropTargetOnEnter must accept at least 6 parameters:
;           TargetObject   -  This instance.
;           pDataObj       -  A pointer to the IDataObject interface on the data object being dropped.
;           KeyState       -  The current state of the mouse buttons and keyboard modifier keys.
;           X              -  The current X coordinate of the cursor in screen coordinates.
;           Y              -  The current Y coordinate of the cursor in screen coordinates.
;           DropEffect     -  The drop effect determined by the Drop() method.
;        IDropTargetOnOver must accept at least 5 parameters:
;           TargetObject   -  This instance.
;           KeyState       -  The current state of the mouse buttons and keyboard modifier keys.
;           X              -  The current X coordinate of the cursor in screen coordinates.
;           Y              -  The current Y coordinate of the cursor in screen coordinates.
;           DropEffect     -  The drop effect determined by the Drop() method.
;        IDropTargetOnLeave must accept at least 1 parameter:
;           TargetObject   -  This instance.
;
;     What the functions must return:
;        The return value of IDropTargetOnDrop, IDropTargetOnEnter, and IDropTargetOnOver is used as the drop effect reported
;        as the result of the drop operation. In the easiest case the function returns the value passed in DropEffect.
;        Otherwise, it must return one of the following values:
;           0 (DROPEFFECT_NONE)
;           1 (DROPEFFECT_COPY)
;           2 (DROPEFFECT_MOVE)
;        The return value of IDropTargetOnLeave is not used.
;
;     As is the interface supports only left-dragging and permits DROPEFFECT_COPY and DROPEFFECT_MOVE. The default effect is
;     DROPEFFECT_COPY. It will be switched to DROPEFFECT_MOVE if either Ctrl or Shift is pressed. You can overwrite the default
;     from the IDropTargetOnEnter user function.
;
;     The dropped data have to be processed completely by the IDropTargetOnDrop user function.
; ==================================================================================================================================
IDropTarget_Create(HWND, UserFuncSuffix, RequiredFormats := "", Register := True, UseHelper := True) {
   Return New IDropTarget(HWND, UserFuncSuffix, RequiredFormats, Register, UseHelper)
}
; ==================================================================================================================================
Class IDropTarget {
   __New(HWND, UserFuncSuffix, RequiredFormats := "", Register := True, UseHelper := True) {
      Static Methods := ["QueryInterface", "AddRef", "Release", "DragEnter", "DragOver", "DragLeave", "Drop"]
      Static Params := (A_PtrSize = 8 ? [3, 1, 1, 5, 4, 1, 5] : [3, 1, 1, 6, 5, 1, 6])
      Static DefaultFormat := 15 ; CF_HDROP
      Static DropFunc := "IDropTargetOnDrop"
      Static EnterFunc := "IDropTargetOnEnter"
      Static OverFunc := "IDropTargetOnOver"
      Static LeaveFunc := "IDropTargetOnLeave"
      Static CLSID_IDTH := "{4657278A-411B-11D2-839A-00C04FD918D0}" ; CLSID_DragDropHelper
      Static IID_IDTH := "{4657278B-411B-11D2-839A-00C04FD918D0}"   ; IID_IDropTargetHelper
      If This.Base.HasKey("Ptr")
         Return False
      UserFunc := DropFunc . UserFuncSuffix
      If !IsFunc(UserFunc) || (Func(UserFunc).MinParams < 6)
         Return False
      This.DropUserFunc := Func(UserFunc)
      UserFunc := EnterFunc . UserFuncSuffix
      If (IsFunc(UserFunc) && (Func(UserFunc).MinParams > 5))
         This.EnterUserFunc := Func(UserFunc)
      UserFunc := OverFunc . UserFuncSuffix
      If (IsFunc(UserFunc) && (Func(UserFunc).MinParams > 4))
         This.OverUserFunc := Func(UserFunc)
      UserFunc := LeaveFunc . UserFuncSuffix
      If (IsFunc(UserFunc) && (Func(UserFunc).MinParams > 0))
         This.LeaveUserFunc := Func(UserFunc)
      This.HWND := HWND
      This.Registered := False
      If IsObject(RequiredFormats)
         This.Required := RequiredFormats
      Else
         This.Required := [DefaultFormat]
      This.PreferredDropEffect := 0
      SizeOfVTBL := (Methods.Length() + 2) * A_PtrSize
      This.SetCapacity("VTBL", SizeOfVTBL)
      This.Ptr := This.GetAddress("VTBL")
      DllCall("RtlZeroMemory", "Ptr", This.Ptr, "UInt", SizeOfVTBL)
      NumPut(This.Ptr + A_PtrSize, This.Ptr + 0, "UPtr")
      For Index, Method In Methods {
         CB := RegisterCallback("IDropTarget." . Method, "", Params[Index], &This)
         NumPut(CB, This.Ptr + 0, A_Index * A_PtrSize, "UPtr")
      }
      This.Helper := ComObjCreate(CLSID_IDTH, IID_IDTH)
      If (Register)
         If !This.RegisterDragDrop()
            Return False
   }
   ; -------------------------------------------------------------------------------------------------------------------------------
   ; Registers window/control as a drop target.
   ; -------------------------------------------------------------------------------------------------------------------------------
   RegisterDragDrop() {
      If !(This.Registered)
         If DllCall("Ole32.dll\RegisterDragDrop", "Ptr", This.HWND, "Ptr", This.Ptr, "Int")
            Return False
      Return (This.Registered := True)
   }
   ; -------------------------------------------------------------------------------------------------------------------------------
   ; Revokes registering of the window/control as a drop target.
   ; This method should be called before the window/control will be destroyed.
   ; -------------------------------------------------------------------------------------------------------------------------------
   RevokeDragDrop() {
      If (This.Registered)
         DllCall("Ole32.dll\RevokeDragDrop", "Ptr", This.HWND)
      Return !(This.Registered := False)
   }
   ; -------------------------------------------------------------------------------------------------------------------------------
   ; Notifies the drag-image manager, if used, to show or hide the drag image.
   ; Parameter:
   ;     Show  -  If true, the drag image will be shown; otherwise it will be hidden.
   ; -------------------------------------------------------------------------------------------------------------------------------
   HelperShow(Show := True) {
      Static HelperShow := A_PtrSize * 7
      If (This.Helper) {
         pVTBL := NumGet(This.Helper + 0, "UPtr")
         , DllCall(NumGet(pVTBL + HelperShow, "UPtr"), "Ptr", This.Helper, "UInt", !!Show)
         Return True
      }
      Return False
   }
   ; ===============================================================================================================================
   ; The following methods must not be called directly, they are reserved for internal and system use.
   ; ===============================================================================================================================
   __Delete() {
      This.RevokeDragDrop()
      While (CB := NumGet(This.Ptr + (A_PtrSize * A_Index), "Ptr"))
         DllCall("GlobalFree", "Ptr", CB)
      If (This.Helper)
         ObjRelease(This.Helper)
   }
   ; -------------------------------------------------------------------------------------------------------------------------------
   QueryInterface(RIID, PPV) {
      ; IUnknown -> msdn.microsoft.com/en-us/library/ms682521(v=vs.85).aspx
      Static IID := "{00000122-0000-0000-C000-000000000046}"
      VarSetCapacity(QID, 80, 0)
      QIDLen := DllCall("Ole32.dll\StringFromGUID2", "Ptr", RIID, "Ptr", &QID, "Int", 40, "Int")
      If (StrGet(&QID, QIDLen, "UTF-16") = IID) {
         NumPut(This, PPV + 0, "Ptr")
         Return 0 ; S_OK
      }
      Else {
         NumPut(0, PPV + 0, "Ptr")
         Return 0x80004002 ; E_NOINTERFACE
      }
   }
   ; -------------------------------------------------------------------------------------------------------------------------------
   AddRef() {
      ; IUnknown -> msdn.microsoft.com/en-us/library/ms691379(v=vs.85).aspx
      ; Reference counting is not needed in this case.
      Return 1
   }
   ; -------------------------------------------------------------------------------------------------------------------------------
   Release() {
      ; IUnknown -> msdn.microsoft.com/en-us/library/ms682317(v=vs.85).aspx
      ; Reference counting is not needed in this case.
      Return 0
   }
   ; -------------------------------------------------------------------------------------------------------------------------------
   DragEnter(pDataObj, grfKeyState, P3 := "", P4 := "", P5 := "") {
      ; DragEnter -> msdn.microsoft.com/en-us/library/ms680106(v=vs.85).aspx
      ; Params 32: IDataObject *pDataObj, DWORD grfKeyState, LONG x, LONG y, DWORD *pdwEffect
      ; Params 64: IDataObject *pDataObj, DWORD grfKeyState, POINTL pt, DWORD *pdwEffect
      Static HelperEnter := A_PtrSize * 3
      Instance := Object(A_EventInfo)
      If (A_PtrSize = 8)
         X := P2 & 0xFFFFFFFF, Y := P2 >> 32
      Else
         X := P2, Y := P3
      Effect := 0
      If !(grfKeyState & 0x02) { ; right-drag isn't supported by default
         For Each, Format In Instance.Required {
            IDataObject_CreateFormatEtc(FORMATETC, Format)
            If (Effect := IDataObject_QueryGetData(pDataObj, FORMATETC))
               Break
         }
      }
      If (Effect) && (Instance.EnterUserFunc)
         Effect := Instance.EnterUserFunc.Call(Instance, pDataObj, grfKeyState, X, Y, Effect)
      Instance.PreferredDropEffect := Effect
      ; If Ctrl and/or Shift is pressed swap the effect
      Effect ^= grfKeyState & 0x0C ? 3 : 0
      ; Call IDropTargetHelper, if created
      If (Instance.Helper) {
         VarSetCapacity(PT, 8, 0)
         , NumPut(X, PT, 0, "Int")
         , NumPut(Y, PT, 0, "Int")
         , pVTBL := NumGet(Instance.Helper + 0, "UPtr")
         , DllCall(NumGet(pVTBL + HelperEnter, "UPtr")
                 , "Ptr", Instance.Helper, "Ptr", Instance.HWND, "Ptr", pDataObj, "Ptr", &PT, "UInt", Effect, "Int")
      }
      NumPut(Effect, (A_PtrSize = 8 ? P4 : P5) + 0, "UInt")
      Return 0 ; S_OK
   }
   ; -------------------------------------------------------------------------------------------------------------------------------
   DragOver(grfKeyState, P2 := "", P3 := "", P4 := "") {
      ; DragOver -> msdn.microsoft.com/en-us/library/ms680129(v=vs.85).aspx
      ; Params 32: DWORD grfKeyState, LONG x, LONG y, DWORD *pdwEffect
      ; Params 64: DWORD grfKeyState, POINTL pt, DWORD *pdwEffect
      Static HelperOver := A_PtrSize * 5
      Instance := Object(A_EventInfo)
      If (A_PtrSize = 8)
         X := P2 & 0xFFFFFFFF, Y := P2 >> 32
      Else
         X := P2, Y := P3
      ; If Ctrl and/or Shift is pressed swap the effect
      Effect := Instance.PreferredDropEffect ^ (grfKeyState & 0x0C ? 3 : 0)
      If (Effect) && (Instance.OverUserFunc)
         Effect := Instance.OverUserFunc.Call(Instance, grfKeyState, X, Y, Effect)
      If (Instance.Helper) {
         VarSetCapacity(PT, 8, 0)
         , NumPut(X, PT, 0, "Int")
         , NumPut(Y, PT, 0, "Int")
         , pVTBL := NumGet(Instance.Helper + 0, "UPtr")
         , DllCall(NumGet(pVTBL + HelperOver, "UPtr"), "Ptr", Instance.Helper, "Ptr", &PT, "UInt", Effect, "Int")
      }
      NumPut(Effect, (A_PtrSize = 8 ? P3 : P4) + 0, "UInt")
      Return 0 ; S_OK
   }
   ; -------------------------------------------------------------------------------------------------------------------------------
   DragLeave() {
      ; DragLeave -> msdn.microsoft.com/en-us/library/ms680110(v=vs.85).aspx
      Static HelperLeave := A_PtrSize * 4
      Instance := Object(A_EventInfo)
      Instance.PreferredDropEffect := 0
      If (Instance.LeaveUserFunc)
         Instance.LeaveUserFunc.Call(Instance)
      If (Instance.Helper) {
         pVTBL := NumGet(Instance.Helper + 0, "UPtr"), DllCall(NumGet(pVTBL + HelperLeave, "UPtr"), "Ptr", Instance.Helper)
      }
      Return 0 ; S_OK
   }
   ; -------------------------------------------------------------------------------------------------------------------------------
   Drop(pDataObj, grfKeyState, P3 := "", P4 := "", P5 := "") {
      ; Drop -> msdn.microsoft.com/en-us/library/ms687242(v=vs.85).aspx
      ; Params 32: IDataObject *pDataObj, DWORD grfKeyState, LONG x, LONG y, DWORD *pdwEffect
      ; Params 64: IDataObject *pDataObj, DWORD grfKeyState, POINTL pt, DWORD *pdwEffect
      Static HelperDrop := A_PtrSize * 6
      Instance := Object(A_EventInfo)
      If (A_PtrSize = 8)
         X := P3 & 0xFFFFFFFF, Y := P3 >> 32
      Else
         X := P3, Y := P4
      Effect := Instance.PreferredDropEffect ^ (grfKeyState & 0x0C ? 3 : 0)
      Effect := Instance.DropUserFunc.Call(Instance, pDataObj, grfKeyState, X, Y, Effect)
      NumPut(Effect, (A_PtrSize = 8 ? P4 : P5) + 0, "UInt")
      If (Instance.Helper) {
         VarSetCapacity(PT, 8, 0)
         , NumPut(X, PT, 0, "Int")
         , NumPut(Y, PT, 0, "Int")
         , pVTBL := NumGet(Instance.Helper + 0, "UPtr")
         , DllCall(NumGet(pVTBL + HelperDrop, "UPtr"), "Ptr", Instance.Helper, "Ptr", pDataObj, "Ptr", &PT, "UInt", Effect, "Int")
      }
      ObjRelease(pDataObj)
      Return 0 ; S_OK
   }
}
; ==================================================================================================================================


; from https://github.com/AHK-just-me/DoDragDrop/blob/master/sources/IDataObject.ahk
; ==================================================================================================================================
; IDataObject interface -> msdn.microsoft.com/en-us/library/ms688421(v=vs.85).aspx
; Partial implementation.
; Requires: IEnumFORMATETC.ahk
; ==================================================================================================================================
IDataObject_EnumFormatEtc(pDataObj) {
   ; EnumFormatEtc -> msdn.microsoft.com/en-us/library/ms683979(v=vs.85).aspx
   ; DATADIR_GET = 1
   Static EnumFormatEtc := A_PtrSize * 8
   pVTBL := NumGet(pDataObj + 0, "UPtr")
   If !DllCall(NumGet(pVTBL + EnumFormatEtc, "UPtr"), "Ptr", pDataObj, "UInt", 1, "PtrP", ppenumFormatEtc, "Int")
      Return ppenumFormatEtc
   Return False
}
; ==================================================================================================================================
IDataObject_GetData(pDataObj, ByRef FORMATETC, ByRef Size, ByRef Data) {
   ; GetData -> msdn.microsoft.com/en-us/library/ms678431(v=vs.85).aspx
   Static GetData := A_PtrSize * 3
   Data := ""
   , Size := -1
   , VarSetCapacity(STGMEDIUM, 24, 0) ; 64-bit
   , pVTBL := NumGet(pDataObj + 0, "UPtr")
   If !DllCall(NumGet(pVTBL + GetData, "UPtr"), "Ptr", pDataObj, "Ptr", &FORMATETC, "Ptr", &STGMEDIUM, "Int") {
      If (NumGet(STGMEDIUM, "UInt") = 1) { ; TYMED_HGLOBAL
         hGlobal := NumGet(STGMEDIUM, A_PtrSize, "UPtr")
         , pGlobal := DllCall("GlobalLock", "Ptr", hGlobal, "Uptr")
         , Size := DllCall("GlobalSize", "Ptr", hGlobal, "UPtr")
         , VarSetCapacity(Data, Size, 0)
         , DllCall("RtlMoveMemory", "Ptr", &Data, "Ptr", pGlobal, "Ptr", Size)
         , DllCall("GlobalUnlock", "Ptr", hGlobal)
         , DllCall("Ole32.dll\ReleaseStgMedium", "Ptr", &STGMEDIUM)
         Return True
      }
      DllCall("Ole32.dll\ReleaseStgMedium", "Ptr", &STGMEDIUM)
   }
   Return False
}
; ==================================================================================================================================
IDataObject_QueryGetData(pDataObj, ByRef FORMATETC) {
   ; QueryGetData -> msdn.microsoft.com/en-us/library/ms680637(v=vs.85).aspx
   Static QueryGetData := A_PtrSize * 5
   pVTBL := NumGet(pDataObj + 0, "UPtr")
   Return !DllCall(NumGet(pVTBL + QueryGetData, "UPtr"), "Ptr", pDataObj, "Ptr", &FORMATETC, "Int")
}
; ==================================================================================================================================
IDataObject_SetData(pDataObj, ByRef FORMATETC, ByRef STGMEDIUM) {
   ; SetData -> msdn.microsoft.com/en-us/library/ms686626(v=vs.85).aspx
   Static SetData := A_PtrSize * 7
   pVTBL := NumGet(pDataObj + 0, "UPtr")
   Return !DllCall(NumGet(pVTBL + SetData, "UPtr"), "Ptr", pDataObj, "Ptr", &FORMATETC, "Ptr", &STGMEDIUM, "Int", True, "Int")
}
; ==================================================================================================================================
; Auxiliary functions to get/set data of the data object.
; ==================================================================================================================================
; FORMATETC structure -> msdn.microsoft.com/en-us/library/ms682242(v=vs.85).aspx
; ==================================================================================================================================
IDataObject_CreateFormatEtc(ByRef FORMATETC, Format, Aspect := 1, Index := -1, Tymed := 1) {
   ; DVASPECT_CONTENT = 1, Index all data = -1, TYMED_HGLOBAL = 1
   VarSetCapacity(FORMATETC, 32, 0) ; 64-bit
   , NumPut(Format, FORMATETC, 0, "Ushort")
   , NumPut(Aspect, FORMATETC, A_PtrSize = 8 ? 16 : 8 , "UInt")
   , NumPut(Index, FORMATETC, A_PtrSIze = 8 ? 20 : 12, "Int")
   , NumPut(Tymed, FORMATETC, A_PtrSize = 8 ? 24 : 16, "UInt")
   Return &FORMATETC
}
; ==================================================================================================================================
IDataObject_ReadFormatEtc(ByRef FORMATETC, ByRef Format, ByRef Device, ByRef Aspect, ByRef Index, ByRef Tymed) {
   Format := NumGet(FORMATETC, OffSet := 0, "UShort")
   , Device := NumGet(FORMATETC, Offset += A_PtrSize, "UPtr")
   , Aspect := NumGet(FORMATETC, Offset += A_PtrSize, "UInt")
   , Index  := NumGet(FORMATETC, Offset += 4, "Int")
   , Tymed  := NumGet(FORMATETC, Offset += 4, "UInt")
}
; ==================================================================================================================================
; Get/Set format data.
; ==================================================================================================================================
IDataObject_GetDroppedFiles(pDataObj, ByRef DroppedFiles) {
   ; msdn.microsoft.com/en-us/library/bb773269(v=vs.85).aspx
   IDataObject_CreateFormatEtc(FORMATETC, 15) ; CF_HDROP
   DroppedFiles := []
   If IDataObject_GetData(pDataObj, FORMATETC, Size, Data) {
      Offset := NumGet(Data, 0, "UInt")
      CP := NumGet(Data, 16, "UInt") ? "UTF-16" : "CP0"
      Shift := (CP = "UTF-16")
      While (File := StrGet(&Data + Offset, CP)) {
         DroppedFiles.Push(File)
         Offset += (StrLen(File) + 1) << Shift
      }
   }
   Return DroppedFiles.Length()
}
; ==================================================================================================================================
IDataObject_GetLogicalDropEffect(pDataObj, ByRef DropEffect) {
   Static LogicalDropEffect := DllCall("RegisterClipboardFormat", "Str", "Logical Performed DropEffect")
   IDataObject_CreateFormatEtc(FORMATETC, LogicalDropEffect)
   DropEffect := ""
   If IDataObject_GetData(pDataObj, FORMATETC, Size, Data) {
      DropEffect := NumGet(Data, "UChar")
      Return True
   }
   Return False
}
; ==================================================================================================================================
IDataObject_GetPerformedDropEffect(pDataObj, ByRef DropEffect) {
   Static PerformedDropEffect := DllCall("RegisterClipboardFormat", "Str", "Performed DropEffect")
   IDataObject_CreateFormatEtc(FORMATETC, PerformedDropEffect)
   DropEffect := ""
   If IDataObject_GetData(pDataObj, FORMATETC, Size, Data) {
      DropEffect := NumGet(Data, "UChar")
      Return True
   }
   Return False
}
; ==================================================================================================================================
IDataObject_GetText(pDataObj, ByRef Txt) {
   Static CF_NATIVE := A_IsUnicode ? 13 : 1 ; CF_UNICODETEXT : CF_TEXT
   IDataObject_CreateFormatEtc(FORMATETC, CF_NATIVE)
   Txt := ""
   If IDataObject_GetData(pDataObj, FORMATETC, Size, Data) {
      Txt := StrGet(Data, Size >> !!A_IsUnicode)
      Return True
   }
   Return False
}
; ==================================================================================================================================
IDataObject_SetLogicalDropEffect(pDataObj, DropEffect) {
   Static LogicalDropEffect := DllCall("RegisterClipboardFormat", "Str", "Logical Performed DropEffect")
   IDataObject_CreateFormatEtc(FORMATETC, LogicalDropEffect)
   , VarSetCapacity(STGMEDIUM, 24, 0) ; 64-bit
   , NumPut(1, STGMEDIUM, "UInt") ; TYMED_HGLOBAL
   ; 0x42 = GMEM_MOVEABLE (0x02) | GMEM_ZEROINIT (0x40)
   , hMem := DllCall("GlobalAlloc", "UInt", 0x42, "UInt", 4, "UPtr")
   , pMem := DllCall("GlobalLock", "Ptr", hMem)
   , NumPut(DropEffect, pMem + 0, "UChar")
   , DllCall("GlobalUnlock", "Ptr", hMem)
   , NumPut(hMem, STGMEDIUM, A_PtrSize, "UPtr")
   Return IDataObject_SetData(pDataObj, FORMATETC, STGMEDIUM)
}
; ==================================================================================================================================
IDataObject_SetPerformedDropEffect(pDataObj, DropEffect) {
   Static PerformedDropEffect := DllCall("RegisterClipboardFormat", "Str", "Performed DropEffect")
   IDataObject_CreateFormatEtc(FORMATETC, PerformedDropEffect)
   , VarSetCapacity(STGMEDIUM, 24, 0) ; 64-bit
   , NumPut(1, STGMEDIUM, "UInt") ; TYMED_HGLOBAL
   ; 0x42 = GMEM_MOVEABLE (0x02) | GMEM_ZEROINIT (0x40)
   , hMem := DllCall("GlobalAlloc", "UInt", 0x42, "UInt", 4, "UPtr")
   , pMem := DllCall("GlobalLock", "Ptr", hMem)
   , NumPut(DropEffect, pMem + 0, "UChar")
   , DllCall("GlobalUnlock", "Ptr", hMem)
   , NumPut(hMem, STGMEDIUM, A_PtrSize, "UPtr")
   Return IDataObject_SetData(pDataObj, FORMATETC, STGMEDIUM)
}
; ==================================================================================================================================
IDataObject_SHFileOperation(pDataObj, TargetPath, Operation, HWND := 0) {
   ; SHFileOperation -> msdn.microsoft.com/en-us/library/bb762164(v=vs.85).aspx
   If Operation Not In 1,2
      Return False
   IDataObject_CreateFormatEtc(FORMATETC, 15) ; CF_HDROP
   If IDataObject_GetData(pDataObj, FORMATETC, Size, Data) {
      Offset := NumGet(Data, 0, "UInt") ; offset of the file list
      IsUnicode := NumGet(Data, 16, "UInt") ; 1: Unicode, 0: ANSI
      TargetLen := StrPut(TargetPath, IsUnicode ? "UTF-16" : "CP0") + 2
      VarSetCapacity(Target, TargetLen << !!IsUnicode, 0)
      StrPut(TargetPath, &Target, IsUnicode ? "UTF-16" : "CP0")
      SHFOSLen := A_PtrSize * (A_PtrSize = 8 ? 7 : 8)
      VarSetCapacity(SHFOS, SHFOSLen, 0) ; SHFILEOPSTRUCT
      NumPut(HWND, SHFOS, 0, "UPtr")
      NumPut(Operation, SHFOS, A_PtrSize, "UInt") ; FO_MOVE = 1, FO_COPY = 2, so we have to swap the DropEffect
      NumPut(&Data + Offset, SHFOS, A_PtrSize * 2, "UPtr")
      NumPut(&Target, SHFOS, A_PtrSize * 3, "UPtr")
      NumPut(0x0200, SHFOS, A_PtrSize * 4, "UInt") ; FOF_NOCONFIRMMKDIR
      If (IsUnicode)
         Return DllCall("Shell32.dll\SHFileOperationW", "Ptr", &SHFOS, "Int")
      Else
         Return DllCall("Shell32.dll\SHFileOperationA", "Ptr", &SHFOS, "Int")
   }
}
; ==================================================================================================================================

; from https://github.com/AHK-just-me/DoDragDrop/blob/master/sources/IEnumFORMATETC.ahk
; ==================================================================================================================================
; IEnumFORMATETC interface -> msdn.microsoft.com/en-us/library/ms682337(v=vs.85).aspx
; Partial implementation, 'Clone' method is missing.
; ==================================================================================================================================
IEnumFORMATETC_Next(pEnumObj, ByRef FORMATETC) {
   ; Next -> msdn.microsoft.com/en-us/library/dd542673(v=vs.85).aspx
   Static Next := A_PtrSize * 3
   VarSetCapacity(FORMATETC, A_PtrSize = 8 ? 32 : 20, 0)
   , pVTBL := NumGet(pEnumObj + 0, "UPtr")
   Return !DllCall(NumGet(pVTBL + Next, "UPtr"), "Ptr", pEnumObj, "UInt", 1, "Ptr", &FORMATETC, "Ptr", 0, "Int")
}
; ----------------------------------------------------------------------------------------------------------------------------------
IEnumFORMATETC_Reset(pEnumObj) {
   ; Reset -> msdn.microsoft.com/en-us/library/dd542674(v=vs.85).aspx
   Static Reset := A_PtrSize * 5
   pVTBL := NumGet(pEnumObj + 0, "UPtr")
   Return !DllCall(NumGet(pVTBL + Reset, "UPtr"), "Ptr", pEnumObj, "Int")
}
; ----------------------------------------------------------------------------------------------------------------------------------
IEnumFORMATETC_Skip(pEnumObj, ItemCount) {
   ; Skip -> msdn.microsoft.com/en-us/library/dd542674(v=vs.85).aspx
   Static Skip := A_PtrSize * 4
   pVTBL := NumGet(pEnumObj + 0, "UPtr")
   Return !DllCall(NumGet(pVTBL + Skip, "UPtr"), "Ptr", pEnumObj, "UInt", ItemCount, "Int")
}
; ==================================================================================================================================

Special thanks to the users 'jballi' and 'just me' on ahkscript.org for the drag and drop portion.

14
Look like everything wasn't quite right yet.

Spoiler
#NoEnv  ; Recommended for performance and compatibility with future AutoHotkey releases.
SetWorkingDir %A_ScriptDir%  ; Ensures a consistent starting directory.
#SingleInstance ignore

Help(wParam, lParam, Msg)
{
  MouseGetPos,,,, OutputVarControl

  ;~ IfEqual, OutputVarControl, Button1
   ;~ Help := "Will try to convert the input multiple times if detected as Hex/Binary."

  ToolTip % Help
}

encodeUTF8( ByRef OutData, InData, inputEncoding, outputEncoding)
{
  encoding := determineEncodingFlag(inputEncoding, "encrypt")
  InDataLen := StrPutVar(InData, InData, "UTF-8") - 1
  DllCall( "Crypt32.dll\CryptBinaryToStringW", UInt,&InData, UInt,InDataLen, UInt,encoding, UInt,0, UIntP,TChars, "CDECL Int" )
  VarSetCapacity( OutData, Req := TChars * ( A_IsUnicode ? 2 : 1 ), 0 )
  DllCall( "Crypt32.dll\CryptBinaryToStringW", UInt,&InData, UInt,InDataLen, UInt,encoding, Str,OutData, UIntP,Req, "CDECL Int" )
 
  Return TChars
}

determineEncodingFlag(encoding, crypt)
{
  if(crypt = "encrypt")
  {
    if(encoding = "Binary")
      return 0x00000002
    else if(encoding = "BASE64")
      return 0x40000001
    else if(encoding = "Hexadecimal")
      return 0x00000004
  }
  else if (crypt = "decrypt")
  {
    if(encoding = "Binary")
      return 0x00000002
    else if(encoding = "BASE64")
      return 0x00000001
    else if(encoding = "Hexadecimal")
      return 0x00000008
  }
}

StrPutVar(string, ByRef var, encoding)
{
    ; Ensure capacity.
    VarSetCapacity( var, StrPut(string, encoding)
        ; StrPut returns char count, but VarSetCapacity needs bytes.
        * ((encoding="utf-16"||encoding="cp1200") ? 2 : 1) )
    ; Copy or convert the string.
    return StrPut(string, &var, encoding)
}

decodeUTF8( ByRef OutData, InData, inputEncoding)
{
  encoding := determineEncodingFlag(inputEncoding, "decrypt")
  DllCall( "Crypt32.dll\CryptStringToBinaryW", UInt,&InData, UInt,StrLen(InData), UInt,encoding, UInt,0, UIntP,Bytes, Int,0, Int,0, "CDECL Int" )
  VarSetCapacity( OutData, Req := Bytes * ( A_IsUnicode ? 2 : 1 ), 0 )
  DllCall( "Crypt32.dll\CryptStringToBinaryW", UInt,&InData, UInt,StrLen(InData), UInt,encoding, Str,OutData, UIntP,Req, Int,0, Int,0, "CDECL Int" )
  OutData := StrGet(&OutData, "cp0")
  Return Bytes
}

TxtToBin(txt)
{ ; http://www.autohotkey.com/board/topic/7835-ascii-binary-converter/?p=48740
  Loop Parse, txt
  {
    Loop 8
    {
      bin := bin (Asc(A_LoopField) >> (8 - A_Index) & 1)
    }
    bin .= " "
  }
  return SubStr(bin, 1, (StrLen(bin) - 1))
}

BinToTxt(bin)
{ ; http://www.autohotkey.com/board/topic/7835-ascii-binary-converter/?p=48740
   StringReplace, bin, bin, %A_Space%,,All
   Loop Parse, bin
   {
      x += x + (A_LoopField = "1")

      If !Mod(A_Index,8)
      {
         txt := txt Chr(x)
         x = 0
      }
   }
   Return txt
}

Rot13(string)
{ ; from LinearSpoon's Translation of The Worlds Shortest C Implementation of Rot13 http://rosettacode.org/wiki/Rot-13#AutoHotkey
  Output := ""
  Loop, Parse, string
  {
    a := ~Asc(A_LoopField)
    Output .= Chr(~a-1//(~(a|32)//13*2-11)*13)
  }
  return Output
}

ascii2Decimal(string)
{
  encoding := ""
  Loop, Parse, string
  {
    encoding .= Asc(A_LoopField) . " "
  }
  return SubStr(encoding, 1, StrLen(encoding) - 1)
}

decimal2Ascii(string)
{
  decoding := ""
  Loop, Parse, string, %A_Space%
  {
    decoding .= Chr(A_LoopField)
  }
  return decoding
}

uriEncode(str)
{ ; v 0.3 / (w) 24.06.2008 by derRaphael / zLib-Style release http://www.autohotkey.com/board/topic/6199-url-encoding/?p=193258

   b_Format := A_FormatInteger
   data := ""
   SetFormat,Integer,H
   Loop,Parse,str
      if ((Asc(A_LoopField)>0x7f) || (Asc(A_LoopField)<0x30) || (asc(A_LoopField)=0x3d))
         data .= "%" . ((StrLen(c:=SubStr(ASC(A_LoopField),3))<2) ? "0" . c : c)
      Else
         data .= A_LoopField
   SetFormat,Integer,%b_format%
   return data
}

uriDecode(str)
{ ; v 0.1 / (w) 28.06.2008 by derRaphael / zLib-Style release http://www.autohotkey.com/board/topic/6199-url-encoding/?p=193258
   Loop,Parse,str,`%
      txt := (A_Index=1) ? A_LoopField : txt chr("0x" substr(A_LoopField,1,2)) SubStr(A_LoopField,3)
   return txt
}

ConvertBase(InputBase, OutputBase, nptr)
{ ; came from somewhere very similar to http://www.autohotkey.com/board/topic/15951-base-10-to-base-36-conversion/?p=172786
    static u := A_IsUnicode ? "_wcstoui64" : "_strtoui64"
    static v := A_IsUnicode ? "_i64tow"    : "_i64toa"
    VarSetCapacity(s, 66, 0)
    value := DllCall("msvcrt.dll\" u, "Str", nptr, "UInt", 0, "UInt", InputBase, "CDECL Int64")
    DllCall("msvcrt.dll\" v, "Int64", value, "Str", s, "UInt", OutputBase, "CDECL")
    return s
}

; Uses the ConvertBase function to convert formated numbers similar to the http://www.asciitohex.com/ site
Convert(inputBase, outputBase, inputNumber)
{
  ; Binary not created correctly if hex isn't inputed in 2 digit format.
  if(inputBase = 16 && outputBase = 2)
    inputNumber := standardizeHexInputFormatForBinaryOutput(inputNumber)
 
  output := ""
  Loop, Parse, inputNumber, %A_Space%
  {
    ; convertBase ouput 0 for 16 base 0 when I need 00
    temp := ConvertBase(inputBase, outputBase, A_LoopField)
    if(temp = 0)
    {
      if(outputBase = 2)
        temp := "00000000"
      else if(outputBase = 16)
        temp := "00"
    }
   
    output .= temp . " "
  }
  StringUpper, output, output
  return SubStr(output, 1, (StrLen(output) - 1))
}

standardizeHexInputFormatForBinaryOutput(inputHex)
{
  hex := ""
  StringReplace, inputHex, inputHex, %A_Space%,,All
  Loop, Parse, inputHex
  {
    if(A_Index != 1 && Mod(A_Index - 1, 2) = 0)
    {
      hex .= " " . A_LoopField
    }
    else
    {
      hex .= A_LoopField
    }
  }
  return hex
}

convertInputToOutputEncoding(inputEncoding, string, outputEncoding)
{
  if(inputEncoding = outputEncoding)
    return string
 
  ; if the conversion is a base to base, i.e. 10(dec) to 16(hex) use the convert function
  inputEncodingBase := determineEncodingBase(inputEncoding)
  outputEncodingBase := determineEncodingBase(outputEncoding)

  if(inputEncodingBase != 0 && outputEncodingBase != 0)
  {
    return Convert(inputEncodingBase, outputEncodingBase, string)
  }
 
  ; convert any base64 to text
  if(inputEncoding = "BASE64")
    string := convertInputToText(string, inputEncoding)
 
  ; Non-base to base conversions
  if(outputEncoding = "BASE64" && inputEncoding = "Text")
    encodeUTF8(encoded, string, "BASE64", outputEncoding)
  else if(outputEncoding = "BASE64")
    encoded := ToBase64(string)
  else if(outputEncoding = "Binary" && (inputEncoding = "Text" || inputEncoding = "BASE64"))
    encoded := TxtToBin(string)
  else if(outputEncoding = "Binary")
    encodeUTF8(encoded, string, "Binary", outputEncoding)
  else if(outputEncoding = "Decimal")
    return ascii2Decimal(string)
  else if(outputEncoding = "Hexadecimal")
    encodeUTF8(encoded, string, "Hexadecimal", outputEncoding)
  else if(outputEncoding = "ROT13")
    return Rot13(string)
  else if(outputEncoding = "URI")
    return uriEncode(string)
  else if(outputEncoding = "Text" && inputEncoding != "BASE64")
    return convertInputToText(string, inputEncoding)
  else if(outputEncoding = "Text" && inputEncoding = "BASE64")
    return string
 
  return encoded
}

determineEncodingBase(encoding)
{
  if(encoding = "Binary")
    return 2
  else if(encoding = "Decimal")
    return 10
  else if(encoding = "Hexadecimal")
    return 16
  else
    return 0
}

ToBase64(string)
{
  static CharSet := "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"
 
  ; convert input to binary unless input is already binary
  if((RegExMatch(string, "^(\d{8}\s?)*$")))
  {
    StringReplace, string, string, %A_Space%,,All
    binary := string
  }
  else
  {
    binary := ""
    Loop, Parse, string
    {
      ; if the entire string is a number treat don't get the Ascii value of the numbers skip that step
      ; Pad output with zeros to each section has 8.
      if string is not integer
        binary .= SubStr("0000000" .  ConvertBase(10, 2, Asc(A_LoopField)), -7, 8)
      else
        binary .= SubStr("0000000" .  ConvertBase(10, 2, A_LoopField), -7, 8)
    }
  }
 
  ; If number of bytes(group of eight) isn't divisible by three bytes(24) add extra zeros until you have it.
  temp := Mod(StrLen(binary), 24)
  shortSection := (24 - temp)

  binary := binary . SubStr("000000000000000000000000", 1, shortSection)

  ; if the last 24,18,12,6 are zero remove them
  if(SubStr(binary, -23) = "000000000000000000000000")
    binary := SubStr(binary, 1, StrLen(binary) - 24)
  else if(SubStr(binary, -17) = "000000000000000000")
    binary := SubStr(binary, 1, StrLen(binary) - 18)
  else if(SubStr(binary, -11) = "000000000000")
    binary := SubStr(binary, 1, StrLen(binary) - 12)
  else if(SubStr(binary, -5) = "000000")
    binary := SubStr(binary, 1, StrLen(binary) - 6)
 
  ; split binary into segements of six
  binary := Trim(RegExReplace(binary, "(.{6})", "$1 "))

  ; convert segments to decimal
  base64 := ""
  Loop, Parse, binary, %A_Space%
  {
    base64 .= SubStr(CharSet, ConvertBase(2, 10, A_LoopField) + 1, 1)
  }
 
  ; If not divisible by 4 add one or two equal signs
  if(Mod(StrLen(base64), 4) > 0)
  {
    ; case where input was binary
    if(Mod(StrLen(base64), 4) < 2)
      base64 .= "A"
   
    base64 .= SubStr("==", 1, (4 - Mod(StrLen(base64), 4)))
  }
 
  return base64
}

Base64Decode(Code)
{ ;http://www.autohotkey.com/board/topic/5545-base64-coderdecoder/?p=690930
    static CharSet := "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"
    Length := StrLen(Code)

    ;remove padding if present
    If SubStr(Code,0) = "="
    {
        If SubStr(Code,-1,1) = "="
            Length -= 2
        Else
            Length --
    }

    BufferSize := Ceil((Length / 4) * 3), VarSetCapacity(Data,BufferSize) ;calculate the correct buffer size
    Index := 1, BinPos := 0
    Loop, % Length >> 2 ;process 4 characters per iteration
    {
        ;decode the characters and store them in the output buffer
        Value := ((InStr(CharSet,SubStr(Code,Index,1),1) - 1) << 18)
            | ((InStr(CharSet,SubStr(Code,Index + 1,1),1) - 1) << 12)
            | ((InStr(CharSet,SubStr(Code,Index + 2,1),1) - 1) << 6)
            | (InStr(CharSet,SubStr(Code,Index + 3,1),1) - 1)
        Index += 4
        Data .= Chr(Value >> 16) . Chr((Value >> 8) & 255) . Chr(Value & 255)
    }
    Length &= 3 ;determine the number of characters that remain
    If Length > 0 ;characters remain
    {
        ;decode the first of the remaining characters and store it in the output buffer
        Value := ((InStr(CharSet,SubStr(Code,Index,1),1) - 1) << 18)
            | ((InStr(CharSet,SubStr(Code,Index + 1,1),1) - 1) << 12)
        Data .= Chr(Value >> 16)

        ;another character remains
        If Length = 3
        {
            ;decode the character and store it in the output buffer
            Value |= (InStr(CharSet,SubStr(Code,Index + 2,1),1) - 1) << 6
            Data .= Chr((Value >> 8) & 255)
        }
    }
    Return, Data
}

convertInputToText(string, inputEncoding)
{
  if(inputEncoding = "BASE64")
    decoded := Base64Decode(string)
  else if(inputEncoding = "Binary")
    decoded := BinToTxt(string)
  else if(inputEncoding = "Decimal")
    return decimal2Ascii(string)
  else if(inputEncoding = "Hexadecimal")
    decodeUTF8(decoded, string, "Hexadecimal")
  else if(inputEncoding = "ROT13")
    return Rot13(string)
  else if(inputEncoding = "URI")
    return uriDecode(string)
  else
    return string
 
  return decoded
}



Gui, Add, Text, x12 y10 w30 h20 , Input:
Gui, Add, DropDownList, x52 y10 w310 h20 vinputEncoding Choose1 R9, Text|BASE64|Binary|Decimal|Hexadecimal|ROT13|URI Encoded
Gui, Add, Edit, x12 y40 w360 h60 vconverterInput,
;~ Gui, Add, CheckBox, x402 y10 w90 h30 hwndsmartConvertHwnd vsmartConvert, Smart Encode?
Gui, Add, Button, x392 y50 w150 h40 vencode gencode, Encode

Gui, Add, Text, x12 y120 w110 h20 , Text (ASCII / ANSI)
Gui, Add, Edit, x12 y150 w170 h140 vtextOutput ,
Gui, Add, Button, x12 y300 w80 h30 vcopyToClipboardText gcopyToClipboard, Copy to Clipboard
Gui, Add, Button, x102 y300 w80 h30 vcopyToInputText gcopyToInput, Copy to input

Gui, Add, Text, x202 y120 w110 h20 , Binary
Gui, Add, Edit, x192 y150 w170 h140 vbinaryOutput ,
Gui, Add, Button, x192 y300 w80 h30 vcopyToClipboardBinary gcopyToClipboard, Copy to Clipboard
Gui, Add, Button, x282 y300 w80 h30 vcopyToInputBinary gcopyToInput, Copy to input

Gui, Add, Text, x382 y120 w110 h20 , Decimal
Gui, Add, Edit, x372 y150 w170 h140 vdecimalOutput,
Gui, Add, Button, x372 y300 w80 h30 vcopyToClipboardDecimal gcopyToClipboard, Copy to Clipboard
Gui, Add, Button, x462 y300 w80 h30 vcopyToInputDecimal gcopyToInput, Copy to input

Gui, Add, Text, x12 y350 w110 h20 , BASE64
Gui, Add, Edit, x12 y380 w170 h140 vbase64Output,
Gui, Add, Button, x12 y530 w80 h30 vcopyToClipboardBase64 gcopyToClipboard, Copy to Clipboard
Gui, Add, Button, x102 y530 w80 h30 vcopyToInputBase64 gcopyToInput, Copy to input

Gui, Add, Text, x202 y350 w110 h20 , ROT13
Gui, Add, Edit, x192 y380 w170 h140 vrot13Output,
Gui, Add, Button, x192 y530 w80 h30 vcopyToClipboardRot13 gcopyToClipboard, Copy to Clipboard
Gui, Add, Button, x282 y530 w80 h30 vcopyToInputRot13 gcopyToInput, Copy to input

Gui, Add, Text, x372 y350 w110 h20 , URI Encoded
Gui, Add, Edit, x372 y380 w170 h140 vuriOutput,
Gui, Add, Button, x372 y530 w80 h30 vcopyToClipboardUri gcopyToClipboard, Copy to Clipboard
Gui, Add, Button, x462 y530 w80 h30 vcopyToInputUri gcopyToInput, Copy to input

Gui, Add, Text, x562 y120 w110 h20 , Hexadecimal
Gui, Add, Edit, x562 y150 w170 h140 vhexadecimalOutput,
Gui, Add, Button, x562 y300 w80 h30 vcopyToClipboardHexadecimal gcopyToClipboard, Copy to Clipboard
Gui, Add, Button, x652 y300 w80 h30 vcopyToInputHexadecimal gcopyToInput, Copy to input

Gui, Add, Text, x562 y530 w170 h20 , Made for request on donationcoder
; Generated using SmartGUI Creator 4.0
Gui, Show, xCenter yCenter h566 w746, Encoder
OnMessage(0x200, "Help")
Return

GuiClose:
ExitApp

encode:
Gui, Submit, nohide
GuiControlGet, inputEncoding,, inputEncoding
GuiControlGet, converterInput,, converterInput
;~ GuiControlGet, smartConvertEnabled,, smartConvert

inputList := "Text|BASE64|Binary|Decimal|Hexadecimal|ROT13|URI"
Loop, Parse, inputList, |
{
  ; clear the output edit field first
  Guicontrol,, % A_LoopField . "Output"
 
  Guicontrol,, % A_LoopField . "Output", % convertInputToOutputEncoding(inputEncoding, converterInput, A_LoopField)
}

return

copyToClipboard:
; Use the name of variable name of the button to get the text from the correct edit box
; Each button is named 'copyToClipboardXXXXXX' and each edit is named 'XXXOutput'
GuiControlGet, ClipBoard,, % SubStr(A_GuiControl, 16) . "Output"
return

copyToInput:
; use A_GuiControl to figure out the new input encoding
newInputEncoding := SubStr(A_GuiControl, 12)

; Populate the input encoding
GuiControl, ChooseString, inputEncoding, %newInputEncoding%

; populate input with selected output text found via A_GuiControl
GuiControlGet, output,, % newInputEncoding . "Output"
Guicontrol,, converterInput, %output%

return



15
Thanks for the input it took me a bit but I think I have everything work, turned out that the base64 was really messed up for numbers it was treating everything as a string.

Spoiler
#NoEnv  ; Recommended for performance and compatibility with future AutoHotkey releases.
SetWorkingDir %A_ScriptDir%  ; Ensures a consistent starting directory.
#SingleInstance ignore

Help(wParam, lParam, Msg)
{
  MouseGetPos,,,, OutputVarControl

  ;~ IfEqual, OutputVarControl, Button1
   ;~ Help := "Will try to convert the input multiple times if detected as Hex/Binary."

  ToolTip % Help
}

encodeUTF8( ByRef OutData, InData, inputEncoding, outputEncoding)
{
  encoding := determineEncodingFlag(inputEncoding, "encrypt")
  InDataLen := StrPutVar(InData, InData, "UTF-8") - 1
  DllCall( "Crypt32.dll\CryptBinaryToStringW", UInt,&InData, UInt,InDataLen, UInt,encoding, UInt,0, UIntP,TChars, "CDECL Int" )
  VarSetCapacity( OutData, Req := TChars * ( A_IsUnicode ? 2 : 1 ), 0 )
  DllCall( "Crypt32.dll\CryptBinaryToStringW", UInt,&InData, UInt,InDataLen, UInt,encoding, Str,OutData, UIntP,Req, "CDECL Int" )
 
  Return TChars
}

determineEncodingFlag(encoding, crypt)
{
  if(crypt = "encrypt")
  {
    if(encoding = "Binary")
      return 0x00000002
    else if(encoding = "BASE64")
      return 0x40000001
    else if(encoding = "Hexadecimal")
      return 0x00000004
  }
  else if (crypt = "decrypt")
  {
    if(encoding = "Binary")
      return 0x00000002
    else if(encoding = "BASE64")
      return 0x00000001
    else if(encoding = "Hexadecimal")
      return 0x00000008
  }
}

StrPutVar(string, ByRef var, encoding)
{
    ; Ensure capacity.
    VarSetCapacity( var, StrPut(string, encoding)
        ; StrPut returns char count, but VarSetCapacity needs bytes.
        * ((encoding="utf-16"||encoding="cp1200") ? 2 : 1) )
    ; Copy or convert the string.
    return StrPut(string, &var, encoding)
}

decodeUTF8( ByRef OutData, InData, inputEncoding)
{
  encoding := determineEncodingFlag(inputEncoding, "decrypt")
  DllCall( "Crypt32.dll\CryptStringToBinaryW", UInt,&InData, UInt,StrLen(InData), UInt,encoding, UInt,0, UIntP,Bytes, Int,0, Int,0, "CDECL Int" )
  VarSetCapacity( OutData, Req := Bytes * ( A_IsUnicode ? 2 : 1 ), 0 )
  DllCall( "Crypt32.dll\CryptStringToBinaryW", UInt,&InData, UInt,StrLen(InData), UInt,encoding, Str,OutData, UIntP,Req, Int,0, Int,0, "CDECL Int" )
  OutData := StrGet(&OutData, "cp0")
  Return Bytes
}

TxtToBin(txt)
{ ; http://www.autohotkey.com/board/topic/7835-ascii-binary-converter/?p=48740
  Loop Parse, txt
  {
    Loop 8
    {
      bin := bin (Asc(A_LoopField) >> (8 - A_Index) & 1)
    }
    bin .= " "
  }
  return SubStr(bin, 1, (StrLen(bin) - 1))
}

BinToTxt(bin)
{ ; http://www.autohotkey.com/board/topic/7835-ascii-binary-converter/?p=48740
   StringReplace, bin, bin, %A_Space%,,All
   Loop Parse, bin
   {
      x += x + (A_LoopField = "1")

      If !Mod(A_Index,8)
      {
         txt := txt Chr(x)
         x = 0
      }
   }
   Return txt
}

Rot13(string)
{ ; from LinearSpoon's Translation of The Worlds Shortest C Implementation of Rot13 http://rosettacode.org/wiki/Rot-13#AutoHotkey
  Output := ""
  Loop, Parse, string
  {
    a := ~Asc(A_LoopField)
    Output .= Chr(~a-1//(~(a|32)//13*2-11)*13)
  }
  return Output
}

ascii2Decimal(string)
{
  encoding := ""
  Loop, Parse, string
  {
    encoding .= Asc(A_LoopField) . " "
  }
  return SubStr(encoding, 1, StrLen(encoding) - 1)
}

decimal2Ascii(string)
{
  decoding := ""
  Loop, Parse, string, %A_Space%
  {
    decoding .= Chr(A_LoopField)
  }
  return decoding
}

uriEncode(str)
{ ; v 0.3 / (w) 24.06.2008 by derRaphael / zLib-Style release http://www.autohotkey.com/board/topic/6199-url-encoding/?p=193258

   b_Format := A_FormatInteger
   data := ""
   SetFormat,Integer,H
   Loop,Parse,str
      if ((Asc(A_LoopField)>0x7f) || (Asc(A_LoopField)<0x30) || (asc(A_LoopField)=0x3d))
         data .= "%" . ((StrLen(c:=SubStr(ASC(A_LoopField),3))<2) ? "0" . c : c)
      Else
         data .= A_LoopField
   SetFormat,Integer,%b_format%
   return data
}

uriDecode(str)
{ ; v 0.1 / (w) 28.06.2008 by derRaphael / zLib-Style release http://www.autohotkey.com/board/topic/6199-url-encoding/?p=193258
   Loop,Parse,str,`%
      txt := (A_Index=1) ? A_LoopField : txt chr("0x" substr(A_LoopField,1,2)) SubStr(A_LoopField,3)
   return txt
}

ConvertBase(InputBase, OutputBase, nptr)
{ ; came from somewhere very similar to http://www.autohotkey.com/board/topic/15951-base-10-to-base-36-conversion/?p=172786
    static u := A_IsUnicode ? "_wcstoui64" : "_strtoui64"
    static v := A_IsUnicode ? "_i64tow"    : "_i64toa"
    VarSetCapacity(s, 66, 0)
    value := DllCall("msvcrt.dll\" u, "Str", nptr, "UInt", 0, "UInt", InputBase, "CDECL Int64")
    DllCall("msvcrt.dll\" v, "Int64", value, "Str", s, "UInt", OutputBase, "CDECL")
    return s
}

; Uses the ConvertBase function to convert formated numbers similar to the http://www.asciitohex.com/ site
Convert(inputBase, outputBase, inputNumber)
{
  ; Binary not created correctly if hex isn't inputed in 2 digit format.
  if(inputBase = 16 && outputBase = 2)
    inputNumber := standardizeHexInputFormatForBinaryOutput(inputNumber)
 
  output := ""
  Loop, Parse, inputNumber, %A_Space%
  {
    ; convertBase ouput 0 for 16 base 0 when I need 00
    temp := ConvertBase(inputBase, outputBase, A_LoopField)
    if(temp = 0)
    {
      if(outputBase = 2)
        temp := "00000000"
      else if(outputBase = 16)
        temp := "00"
    }
   
    output .= temp . " "
  }
  StringUpper, output, output
  return SubStr(output, 1, (StrLen(output) - 1))
}

standardizeHexInputFormatForBinaryOutput(inputHex)
{
  hex := ""
  StringReplace, inputHex, inputHex, %A_Space%,,All
  Loop, Parse, inputHex
  {
    if(A_Index != 1 && Mod(A_Index - 1, 2) = 0)
    {
      hex .= " " . A_LoopField
    }
    else
    {
      hex .= A_LoopField
    }
  }
  return hex
}

convertInputToOutputEncoding(inputEncoding, string, outputEncoding)
{
  if(inputEncoding = outputEncoding)
    return string
 
  ; if the conversion is a base to base, i.e. 10(dec) to 16(hex) use the convert function
  inputEncodingBase := determineEncodingBase(inputEncoding)
  outputEncodingBase := determineEncodingBase(outputEncoding)

  if(inputEncodingBase != 0 && outputEncodingBase != 0)
  {
    return Convert(inputEncodingBase, outputEncodingBase, string)
  }
 
  ; convert any base64 to text
  if(inputEncoding = "BASE64")
    string := convertInputToText(string, inputEncoding)
 
  ; Non-base to base conversions
  if(outputEncoding = "BASE64" && inputEncoding = "Text")
    encodeUTF8(encoded, string, "BASE64", outputEncoding)
  else if(outputEncoding = "BASE64")
    encoded := ToBase64(string)
  else if(outputEncoding = "Binary" && inputEncoding = "Text")
    encoded := TxtToBin(string)
  else if(outputEncoding = "Binary")
    encodeUTF8(encoded, string, "Binary", outputEncoding)
  else if(outputEncoding = "Decimal")
    return ascii2Decimal(string)
  else if(outputEncoding = "Hexadecimal")
    encodeUTF8(encoded, string, "Hexadecimal", outputEncoding)
  else if(outputEncoding = "ROT13")
    return Rot13(string)
  else if(outputEncoding = "URI")
    return uriEncode(string)
  else if(outputEncoding = "Text" && inputEncoding != "BASE64")
    return convertInputToText(string, inputEncoding)
 
  return encoded
}

determineEncodingBase(encoding)
{
  if(encoding = "Binary")
    return 2
  else if(encoding = "Decimal")
    return 10
  else if(encoding = "Hexadecimal")
    return 16
  else
    return 0
}

ToBase64(string)
{
  static CharSet := "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"
 
  ; convert input to binary
  binary := ""
  Loop, Parse, string
  {
    ; if the entire string is a number treat don't get the Ascii value of the numbers skip that step
    ; Pad output with zeros to each section has 8.
    if string is not integer
      binary .= SubStr("0000000" .  ConvertBase(10, 2, Asc(A_LoopField)), -7, 8)
    else
      binary .= SubStr("0000000" .  ConvertBase(10, 2, A_LoopField), -7, 8)
  }
 
  ; If number of bytes(group of eight) isn't divisible by three bytes(24) add extra zeros until you have it.
  temp := Mod(StrLen(binary), 24)
  shortSection := (24 - temp)

  binary := binary . SubStr("000000000000000000000000", 1, shortSection)

  ; if the last 24,18,12,6 are zero remove them
  if(SubStr(binary, -23) = "000000000000000000000000")
    binary := SubStr(binary, 1, StrLen(binary) - 24)
  else if(SubStr(binary, -17) = "000000000000000000")
    binary := SubStr(binary, 1, StrLen(binary) - 18)
  else if(SubStr(binary, -11) = "000000000000")
    binary := SubStr(binary, 1, StrLen(binary) - 12)
  else if(SubStr(binary, -5) = "000000")
    binary := SubStr(binary, 1, StrLen(binary) - 6)
 
  ; split binary into segements of six
  binary := Trim(RegExReplace(binary, "(.{6})", "$1 "))

  ; convert segments to decimal
  base64 := ""
  Loop, Parse, binary, %A_Space%
  {
    base64 .= SubStr(CharSet, ConvertBase(2, 10, A_LoopField) + 1, 1)
  }
 
  ; If not divisible by 4 add one or two equal signs
  if(Mod(StrLen(base64), 4) > 0)
    base64 .= SubStr("==", 1, (4 - Mod(StrLen(base64), 4)))
 
  return base64
}

convertInputToText(string, inputEncoding)
{
  if(inputEncoding = "BASE64")
    decodeUTF8(decoded, string, "Base64")
  else if(inputEncoding = "Binary")
    decoded := BinToTxt(string)
  else if(inputEncoding = "Decimal")
    return decimal2Ascii(string)
  else if(inputEncoding = "Hexadecimal")
    decodeUTF8(decoded, string, "Hexadecimal")
  else if(inputEncoding = "ROT13")
    return Rot13(string)
  else if(inputEncoding = "URI")
    return uriDecode(string)
  else
    return string
 
  return decoded
}



Gui, Add, Text, x12 y10 w30 h20 , Input:
Gui, Add, DropDownList, x52 y10 w310 h20 vinputEncoding Choose1 R9, Text|BASE64|Binary|Decimal|Hexadecimal|ROT13|URI Encoded
Gui, Add, Edit, x12 y40 w360 h60 vconverterInput,
;~ Gui, Add, CheckBox, x402 y10 w90 h30 hwndsmartConvertHwnd vsmartConvert, Smart Encode?
Gui, Add, Button, x392 y50 w150 h40 vencode gencode, Encode

Gui, Add, Text, x12 y120 w110 h20 , Text (ASCII / ANSI)
Gui, Add, Edit, x12 y150 w170 h140 vtextOutput ,
Gui, Add, Button, x12 y300 w80 h30 vcopyToClipboardText gcopyToClipboard, Copy to Clipboard
Gui, Add, Button, x102 y300 w80 h30 vcopyToInputText gcopyToInput, Copy to input

Gui, Add, Text, x202 y120 w110 h20 , Binary
Gui, Add, Edit, x192 y150 w170 h140 vbinaryOutput ,
Gui, Add, Button, x192 y300 w80 h30 vcopyToClipboardBinary gcopyToClipboard, Copy to Clipboard
Gui, Add, Button, x282 y300 w80 h30 vcopyToInputBinary gcopyToInput, Copy to input

Gui, Add, Text, x382 y120 w110 h20 , Decimal
Gui, Add, Edit, x372 y150 w170 h140 vdecimalOutput,
Gui, Add, Button, x372 y300 w80 h30 vcopyToClipboardDecimal gcopyToClipboard, Copy to Clipboard
Gui, Add, Button, x462 y300 w80 h30 vcopyToInputDecimal gcopyToInput, Copy to input

Gui, Add, Text, x12 y350 w110 h20 , BASE64
Gui, Add, Edit, x12 y380 w170 h140 vbase64Output,
Gui, Add, Button, x12 y530 w80 h30 vcopyToClipboardBase64 gcopyToClipboard, Copy to Clipboard
Gui, Add, Button, x102 y530 w80 h30 vcopyToInputBase64 gcopyToInput, Copy to input

Gui, Add, Text, x202 y350 w110 h20 , ROT13
Gui, Add, Edit, x192 y380 w170 h140 vrot13Output,
Gui, Add, Button, x192 y530 w80 h30 vcopyToClipboardRot13 gcopyToClipboard, Copy to Clipboard
Gui, Add, Button, x282 y530 w80 h30 vcopyToInputRot13 gcopyToInput, Copy to input

Gui, Add, Text, x372 y350 w110 h20 , URI Encoded
Gui, Add, Edit, x372 y380 w170 h140 vuriOutput,
Gui, Add, Button, x372 y530 w80 h30 vcopyToClipboardUri gcopyToClipboard, Copy to Clipboard
Gui, Add, Button, x462 y530 w80 h30 vcopyToInputUri gcopyToInput, Copy to input

Gui, Add, Text, x562 y120 w110 h20 , Hexadecimal
Gui, Add, Edit, x562 y150 w170 h140 vhexadecimalOutput,
Gui, Add, Button, x562 y300 w80 h30 vcopyToClipboardHexadecimal gcopyToClipboard, Copy to Clipboard
Gui, Add, Button, x652 y300 w80 h30 vcopyToInputHexadecimal gcopyToInput, Copy to input

Gui, Add, Text, x562 y530 w170 h20 , Made for request on donationcoder
; Generated using SmartGUI Creator 4.0
Gui, Show, xCenter yCenter h566 w746, Encoder
OnMessage(0x200, "Help")
Return

GuiClose:
ExitApp

encode:
Gui, Submit, nohide
GuiControlGet, inputEncoding,, inputEncoding
GuiControlGet, converterInput,, converterInput
;~ GuiControlGet, smartConvertEnabled,, smartConvert

inputList := "Text|BASE64|Binary|Decimal|Hexadecimal|ROT13|URI"
Loop, Parse, inputList, |
{
  ; clear the output edit field first
  Guicontrol,, % A_LoopField . "Output"
 
  Guicontrol,, % A_LoopField . "Output", % convertInputToOutputEncoding(inputEncoding, converterInput, A_LoopField)
}

return

copyToClipboard:
; Use the name of variable name of the button to get the text from the correct edit box
; Each button is named 'copyToClipboardXXXXXX' and each edit is named 'XXXOutput'
GuiControlGet, ClipBoard,, % SubStr(A_GuiControl, 16) . "Output"
return

copyToInput:
; use A_GuiControl to figure out the new input encoding
newInputEncoding := SubStr(A_GuiControl, 12)

; Populate the input encoding
GuiControl, ChooseString, inputEncoding, %newInputEncoding%

; populate input with selected output text found via A_GuiControl
GuiControlGet, output,, % newInputEncoding . "Output"
Guicontrol,, converterInput, %output%

return



16
Thanks for the feed back ashecorven!  Sorry about the conversion issues, it was one of my main worries, I realize that if you're using a conversion tool you need it to be rock solid.

To clarify:

- HEX to binary is actually doing text to binary.
- Binary to HEX is actually doing text to hex.
So for these use cases what you want is to decode the HEX to text then encode that text to Binary verses encoding the HEX to Binary? And you want to do the same for the Binary to HEX?

Also is it possible to have it encode to all types at once? i.e. Choose only the input type and it outputs to multiple text boxes, then each could be copied to clipboard, input box, etc.
I'll work on this while I wait for your reply on the first question.

17
Hi gr3gw,

The ShellExView tool from Nirsoft will answer your questions, the tool includes a 'File Extensions' column with values like 'Directory', 'AllFilesystemObjects', and many file extensions.
This should help you understand where the entries are coming from.

18
Post New Requests Here / Re: IDEA: Comments Column Notes
« on: August 07, 2015, 02:47 PM »
This script with add/modify comments on folders via the Desktop.ini, to do this it makes the folder a system folder.
I couldn't figure out how to get explorer to reliably refresh but know that eventually the comments you choose will appear.

Use the script by installing AutoHotkey, double clicking on the script, and pressing alt + z.


;
; ==========================================================================================================
; Author               : LifeWeaver <[email protected]>
; Script Name        : SetFolderComments
; Script Version     :
; Homepage          :
;
; Creation Date      : 08/07/2015
; Modification Date :
;
; Description       : Lets you set comments on a folder via Desktop.ini
; ===================
;
; ----------------------------------------------------------------------------------------------------------

#NoEnv  ; Recommended for performance and compatibility with future AutoHotkey releases.
SetWorkingDir %A_ScriptDir%  ; Ensures a consistent starting directory.
#SingleInstance force

ActiveExplorerWindow()
{
  for window in ComObjCreate("Shell.Application").Windows
    if window.HWND = WinExist("A")
      return window
}

ExplorerItemsSelected(window)
{
  return window.Document.SelectedItems().count
}

SetFolderComments(folderPath, comments)
{
  desktopIniPath := folderPath . "\desktop.ini"
  ifExist %desktopIniPath%
  {
    ; desktop.ini file exists edit the InfoTip
    FileRead, desktopIniContents, %desktopIniPath%
  }
  else
  {
    ; set default desktop.ini contents
    desktopIniContents := "[.ShellClassInfo]`nInfoTip=`n"
  }
 
  FileDelete, %desktopIniPath%
  desktopIniContents := RegExReplace(desktopIniContents, "(?<=InfoTip=).*$", comments)
 
  FileAppend, %desktopIniContents%, %desktopIniPath%
  if(ErrorLevel)
  {
    msgbox problem(%A_LastError%) appending to %desktopIniPath%
  }
  else
  {
    ; Had issues with permission, running via hidden cmd
    Run, %comspec% /c attrib +S "%folderPath%" && attrib +H +S +A "%desktopIniPath%",,Hide
  }
 
  ; Update explorer
  DllCall( "Shell32\SHChangeNotify", UInt,0x08000000, UInt,0, Int,0, Int,0 ) ; SHCNE_ASSOCCHANGED
}

RemoveFolderComments(folderPath)
{
  IniDelete, %folderPath%, .ShellClassInfo, InfoTip
}

#IfWinActive
!z::
window := ActiveExplorerWindow()
InputBox, comment, Folder Comment, Enter folder(s) comment
; if an item(s) is/are selected set the comment on all files selected
if(ExplorerItemsSelected(window))
{
  for item in window.Document.SelectedItems()
    SetFolderComments(item.Path, comment)
}
else
{
  folderPath := window.Document.Folder.Self.path
  SetFolderComments(folderPath, comment)
}

return


Note: Autohotkey is need to run this script, although you could compile it and merely have an .exe.
Script runs on: Windows 7 Professional, AutoHotkey 1.1.15.04 Unicode build

19
Coding Snacks / Re: Packrat's tool for "Idea Surfing" the web
« on: July 27, 2015, 02:10 PM »
Hi questorfla,

While I'm not sure on the exact requirements it sounds like you know some AHK so you could probably modify this solution to fit your exact needs.
Script runs on: Windows 7 Professional, AutoHotkey 1.1.15.04 Unicode build

To use:
  • Have script running
  • Have url of webpage you want to save in clipboard
  • Press Alt+z to activate script
  • Select folder you want the files in, optionally creating a folder via the provided dialog.
  • It's done and will open the 'additional_info.txt' file in Notepad++, the script will also put the folder path in your clipboard
  • If there is a problem saving the .mht file you'll see a messagebox

Save_Webpage_As_MHT(url, saveFile)
{ ; https://groups.google.com/d/msg/microsoft.public.scripting.wsh/97WUK2_3U_4/mZJyxKf_FfAJ
  message := ComObjCreate("CDO.Message")
  conf := ComObjCreate("CDO.Configuration")
  message.Configuration := conf
  message.CreateMHTMLBody(url)
  stream := message.GetStream()
  stream.SaveToFile(saveFile)
  message := ""
  conf := ""
  stream := ""
  IfExist, %saveFile%
    return true
  else
    return false
}

Open_File_With_Notepad_Plus_Plus(file)
{
  notepad_Plus_Plus_Path := A_ProgramFiles . "\Notepad++\notepad++.exe"
  
  IfNotExist, %notepad_Plus_Plus_Path%
    notepad_Plus_Plus_Path := A_ProgramFiles . " (x86)\Notepad++\notepad++.exe"

  Run, "%notepad_Plus_Plus_Path%" "%file%"
}

#IfWinActive
!z::

; Persume url was in clipboard when script was called
url := Clipboard

; Get download folder
downloadsFolder := SubStr(A_Desktop, 1, StrLen(A_Desktop) - 7) . "Downloads"

; Dialog to get selected folder and create .mht file save path
FileSelectFolder, selectedFolder, %downloadsFolder%,, Select a download folder
archiveSavePath := selectedFolder . "\webpageSnapshot-" . A_Now . ".mht"

if (!Save_Webpage_As_MHT(url, archiveSavePath))
  msgbox Problem creating %archiveSavePath% for url: %url%
else
{
  FileCreateShortcut, %url%, %selectedFolder%\link.lnk
  FileAppend,, %selectedFolder%\additional_info.txt

  Open_File_With_Notepad_Plus_Plus(selectedFolder . "\additional_info.txt")
  Clipboard := selectedFolder
}

return

Note: If you really wanted to have a way to use this via the 'right-click' you could modify the script to take a command line parameter and compile it, then add a 'right-click' menu option via regedit.exe similar to here.

Also you might be able to integrate with your favorite browser to use URLDownloadToFile.

20
Just wanted to say welcome to the site lifeweaver, and thank you for sharing your code  :up: :up: :up:

Thanks I've lurked fore a while and was glad to find something I could contribute to.

21
Hi ashecorven,

Seeing as Skywire has been busy I decided to attempt your request.

Note: Autohotkey is need to run this script, although you could compile it and merely have an .exe.
Script runs on: Windows 7 Professional, AutoHotkey 1.1.15.04 Unicode build

Spoiler
Note: a lot of these functions I found posted by AutoHotkey community members, when so I documented it with a url or name.
#NoEnv  ; Recommended for performance and compatibility with future AutoHotkey releases.
SetWorkingDir %A_ScriptDir%  ; Ensures a consistent starting directory.
#SingleInstance ignore

Help(wParam, lParam, Msg)
{
  MouseGetPos,,,, OutputVarControl

  IfEqual, OutputVarControl, Button1
Help := "Will try to convert the input multiple times if detected as Hex/Binary."
  else IfEqual, OutputVarControl, Button2
Help := "Will replace your current clipboard"

  ToolTip % Help
}

determineEncoding(string)
{
  BINARY_REGEX := "^(\d{8}\s?)*$"
  ;~ BASE64_REGEX := "^([A-Za-z0-9+\/]{4})*([A-Za-z0-9+\/]{4}|[A-Za-z0-9+\/]{3}=|[A-Za-z0-9+\/]{2}==)$"
  HEX_REGEX := "^([0-9A-Fa-f]{2}\s?)+$"
  ;~ DECIMAL_REGEX := "^([0-9]{2,3}\s?)+$"
  
  if(RegExMatch(string, BINARY_REGEX))
    return "Binary"
  else if(RegExMatch(string, HEX_REGEX))
    return "Hex"
  else
    return false
}

StrPutVar(string, ByRef var, encoding)
{
    ; Ensure capacity.
    VarSetCapacity( var, StrPut(string, encoding)
        ; StrPut returns char count, but VarSetCapacity needs bytes.
        * ((encoding="utf-16"||encoding="cp1200") ? 2 : 1) )
    ; Copy or convert the string.
    return StrPut(string, &var, encoding)
}

determineEncodingFlag(encoding, crypt)
{
  if(crypt = "encrypt")
  {
    if(encoding = "Binary")
      return 0x00000002
    else if(encoding = "BASE64")
      return 0x40000001
    else if(encoding = "Hex")
      return 0x00000004
  }
  else if (crypt = "decrypt")
  {
    if(encoding = "Binary")
      return 0x00000002
    else if(encoding = "BASE64")
      return 0x00000006
    else if(encoding = "Hex")
      return 0x00000008
  }
}

encodeUTF8( ByRef OutData, InData, inputEncoding)
{
  if(inputEncoding = "Binary")
  {
    OutData := TxtToBin(InData)
    return StrLen(OutData)
  }
  
  encoding := determineEncodingFlag(inputEncoding, "encrypt")
  InDataLen := StrPutVar(InData, InData, "UTF-8") - 1
  DllCall( "Crypt32.dll\CryptBinaryToStringW", UInt,&InData, UInt,InDataLen, UInt,encoding, UInt,0, UIntP,TChars, "CDECL Int" )
  VarSetCapacity( OutData, Req := TChars * ( A_IsUnicode ? 2 : 1 ), 0 )
  DllCall( "Crypt32.dll\CryptBinaryToStringW", UInt,&InData, UInt,InDataLen, UInt,encoding, Str,OutData, UIntP,Req, "CDECL Int" )
  
  if(inputEncoding = "Hex")
  {
    StringReplace, OutData, OutData, %A_Space%%A_Space%, %A_Space%, All
    
    ; Not sure if I really want to remove the newlines for hex
    StringReplace, OutData, OutData, `r`n,,All
  }
  
  Return TChars
}

decodeUTF8( ByRef OutData, InData, inputEncoding)
{
  if(inputEncoding = "Binary")
  {
    OutData := BinToTxt(InData)
    return StrLen(OutData)
  }
  
  encoding := determineEncodingFlag(inputEncoding, "decrypt")
  DllCall( "Crypt32.dll\CryptStringToBinaryW", UInt,&InData, UInt,StrLen(InData), UInt,encoding, UInt,0, UIntP,Bytes, Int,0, Int,0, "CDECL Int" )
  VarSetCapacity( OutData, Req := Bytes * ( A_IsUnicode ? 2 : 1 ), 0 )
  DllCall( "Crypt32.dll\CryptStringToBinaryW", UInt,&InData, UInt,StrLen(InData), UInt,encoding, Str,OutData, UIntP,Req, Int,0, Int,0, "CDECL Int" )
  OutData := StrGet(&OutData, "cp0")
  Return Bytes
}

TxtToBin(txt)
{ ; http://www.autohotkey.com/board/topic/7835-ascii-binary-converter/?p=48740
  Loop Parse, txt
  {
    Loop 8
    {
      bin := bin (Asc(A_LoopField) >> (8 - A_Index) & 1)
    }
    bin .= " "
  }
   Return bin
}

BinToTxt(bin)
{ ; http://www.autohotkey.com/board/topic/7835-ascii-binary-converter/?p=48740
   StringReplace, bin, bin, %A_Space%,,All
   Loop Parse, bin
   {
      x += x + (A_LoopField = "1")

      If !Mod(A_Index,8)
      {
         txt := txt Chr(x)
         x = 0
      }
   }
   Return txt
}

Rot13(string)
{ ; from LinearSpoon's Translation of The Worlds Shortest C Implementation of Rot13 http://rosettacode.org/wiki/Rot-13#AutoHotkey
  Output := ""
  Loop, Parse, string
  {
    a := ~Asc(A_LoopField)
    Output .= Chr(~a-1//(~(a|32)//13*2-11)*13)
  }
  return Output
}

ascii2Decimal(string)
{
  encoding := ""
  Loop, Parse, string
  {
    encoding .= Asc(A_LoopField) . " "
  }
  return SubStr(encoding, 1, StrLen(encoding) - 1)
}

decimal2Ascii(string)
{
  decoding := ""
  Loop, Parse, string, %A_Space%
  {
    decoding .= Chr(A_LoopField)
  }
  return decoding
}

uriEncode(str)
{ ; v 0.3 / (w) 24.06.2008 by derRaphael / zLib-Style release http://www.autohotkey.com/board/topic/6199-url-encoding/?p=193258
b_Format := A_FormatInteger
data := ""
SetFormat,Integer,H
Loop,Parse,str
if ((Asc(A_LoopField)>0x7f) || (Asc(A_LoopField)<0x30) || (asc(A_LoopField)=0x3d))
data .= "%" . ((StrLen(c:=SubStr(ASC(A_LoopField),3))<2) ? "0" . c : c)
Else
data .= A_LoopField
SetFormat,Integer,%b_format%
return data
}

uriDecode(str)
{ ; v 0.1 / (w) 28.06.2008 by derRaphael / zLib-Style release http://www.autohotkey.com/board/topic/6199-url-encoding/?p=193258
Loop,Parse,str,`%
txt := (A_Index=1) ? A_LoopField : txt chr("0x" substr(A_LoopField,1,2)) SubStr(A_LoopField,3)
return txt
}

convertInputToText(string, inputEncoding)
{
  if(inputEncoding = "BASE64")
    decodeUTF8(decoded, string, "Base64")
  else if(inputEncoding = "Binary")
    decodeUTF8(decoded, string, "Binary")
  else if(inputEncoding = "Decimal")
    return decimal2Ascii(string)
  else if(inputEncoding = "Hex")
    decodeUTF8(decoded, string, "Hex")
  else if(inputEncoding = "ROT13")
    return Rot13(string)
  else if(inputEncoding = "URI Encoded")
    return uriDecode(string)
  
  return decoded
}

convertInputToOutputEncoding(inputEncoding, string, outputEncoding)
{
  if(outputEncoding = "BASE64")
    encodeUTF8(encoded, string, "Base64")
  else if(outputEncoding = "Binary")
    encodeUTF8(encoded, string, "Binary")
  else if(outputEncoding = "Decimal")
    return ascii2Decimal(string)
  else if(outputEncoding = "Hex")
    encodeUTF8(encoded, string, "Hex")
  else if(outputEncoding = "ROT13")
    return Rot13(string)
  else if(outputEncoding = "URI Encoded")
    return uriEncode(string)
  else if(outputEncoding = "")
    return convertInputToText(string, inputEncoding)
  else if(outputEncoding = "Text")
    return convertInputToText(string, inputEncoding)
  
  return encoded
}

Gui, Add, Text, x22 y20 w40 h20 , Input:
Gui, Add, DropDownList, x92 y20 w280 h20 vinputEncoding Choose1 R9, Text|BASE64|Binary|Decimal|Hex|ROT13|URI Encoded
;~ Gui, Add, Button, x452 y10 w110 h40 vguessEncoding gguessEncoding , Guess encoding
Gui, Add, Edit, x32 y60 w530 h270 vconverterInput ,

Gui, Add, Text, x22 y340 w40 h20 , Output:
Gui, Add, DropDownList, x92 y340 w280 h20 voutputEncoding goutputEncoding Choose1 R9, Text|BASE64|Binary|Decimal|Hex|ROT13|URI Encoded
Gui, Add, CheckBox, x462 y340 w100 h20 hwndsmartConvertHwnd vsmartConvert , Smart Convert?
Gui, Add, Edit, x32 y370 w530 h270 vconverterOutput ,
Gui, Add, Button, x32 y650 w140 h30 gcopyOutputToClipboard hwndcopyToClipboardHwnd , Copy Output to Clipboard
Gui, Add, Button, x242 y650 w150 h30 gcopyOutputToInput , Copy Output to Input
Gui, Add, Button, x462 y650 w100 h30 vencode gencode , Encode

; Generated using SmartGUI Creator 4.0
Gui, Show, xCenter yCenter h705 w585, Converter
OnMessage(0x200, "Help")
Return

GuiClose:
ExitApp

encode:
Gui, Submit, nohide
GuiControlGet, inputEncoding,, inputEncoding
GuiControlGet, converterInput,, converterInput
GuiControlGet, outputEncoding,, outputEncoding
GuiControlGet, smartConvertEnabled,, smartConvert

outputText := convertInputToOutputEncoding(inputEncoding, converterInput, outputEncoding)

if(smartConvertEnabled)
{
  result := DetermineEncoding(outputText)
  While result != false && result != outputEncoding
  {
    outputText := convertInputToText(outputText, result)
    result := DetermineEncoding(outputText)
  }
}

Guicontrol,, converterOutput, %outputText%
return

copyOutputToClipboard:
GuiControlGet, ClipBoard,, converterOutput
return

copyOutputToInput:
GuiControlGet, currentOutputEncoding,, outputEncoding
GuiControlGet, output,, converterOutput
Guicontrol,, converterInput, %output%
Guicontrol,, converterOutput
GuiControl, ChooseString, inputEncoding, %currentOutputEncoding%
GuiControl, Choose, outputEncoding, 1
GuiControl, Enable, smartConvert
return

outputEncoding:
GuiControlGet, outputEncoding,, outputEncoding
if(outputEncoding != "Text")
{
  GuiControl,, smartConvert, 0
  GuiControl, Disable, smartConvert
}
else if(outputEncoding = "Text")
{
  GuiControl, Enable, smartConvert
}
return



22
You might try this script, it's written in Autohotkey so you may need to look at a tutorial in their site but should work.

copyText()
{
  oldClip := clipboard
  newClip :=
  clipboard :=
  Send, {ctrl down}
  Sleep, 10
  Send, {c down}
  Sleep, 10
  Send, {c up}
  Sleep, 10
  Send, {ctrl up}
  clipWait, .01
  if ErrorLevel ; If the first copy failed do it again
  {
    Send, {ctrl down}
    Sleep, 10
    Send, {c down}
    Sleep, 10
    Send, {c up}
    Sleep, 10
    Send, {ctrl up}
  }
  newClip := clipboard
  clipboard := oldClip
 
  ; Release duplicate clipboard content from memory, could have large file in clipboard
  VarSetCapacity(oldClip, 0)
  return newClip
}

#IfWinActive ahk_class Net UI Tool Window
Rbutton::
Send s
linkText := copyText()
currentEmailText := ComObjActive("Outlook.Application").ActiveExplorer().Selection.Item(1).body
regexMatchText := "(?<=" . linkText . "\s<)[^>]*"
RegExMatch(currentEmailText, regexMatchText, selectedOutlookLink)
FileCreateShortcut, %selectedOutlookLink%, %A_Desktop%\test.lnk
return
#IfWinActive

To use it rightclick on on the link then rightclick again, it doesn't create a new context menu item but works for me on Windows 7 and outlook 2013.

Pages: [1]