But You can test it.
Run script press f3 and push key on Your midi device.
Also Script should react on programs that You open with double mouse clicks only.
Code: Select all
Global ini := "D:\test.ini" ; Path to your INI file
setbatchlines -1
Global mode := ""
DoubleClickTime := DllCall("GetDoubleClickTime")
DllCall("LoadLibrary", "Str", "winmm.dll", "Ptr")
DllCall("winmm.dll\midiOutOpen", "ptr*", midiOutHandle, "uint", 3, "ptr", 0, "uint", 0, "uint", 0)
OnMessage(MIDI_LONGDATA := 0x3C4, "MidiInCallback")
OpenMidiIn()
return
#If WinActive("ahk_class Progman") or WinActive("ahk_class WorkerW") or WinActive("ahk_class CabinetWClass") or WinActive("ahk_class ExploreWClass")
F3:: ; Map the file to a string
file := Explorer_GetSelection().1 ; Get the path of file selected in Windows Explorer
if !file
{
msgbox file not selected
return
}
mode := "listen"
SplitPath, file, fn ; Get the file name
InputBox, SysexMessage, %fn%, Current mapping: %file%`n`nEnter new mapping.,, 300, 125 ; Ask user for string assignment
if InStr(SysexMessage, "del")
{
SysexMessage := StrReplace(SysexMessage, "del")
IniRead, file, %ini%, maps, %SysexMessage%
IniDelete, %ini%, maps, % SysexMessage
IniDelete, %ini%, maps, % file
MsgBox, 64, Deleted, % "Mapped: " file "`n`n To: " SysexMessage " [DELETED]"
}
else if (SysexMessage != "")
{
IniRead, oldfile, %ini%, maps, %SysexMessage%
IniRead, oldSysexMessage, %ini%, maps, %file%
IniDelete, %ini%, maps, % oldfile
IniDelete, %ini%, maps, % oldSysexMessage
IniWrite, %file%, %ini%, maps, %SysexMessage% ; Save the assignment
IniWrite, %SysexMessage%, %ini%, maps, %file% ; Save the assignment
{
If ErrorLevel
MsgBox, 48, Error, An error occurred during the mapping.
Else
MsgBox, 64, Changed, % "Mapped: " file "`n`n To: " SysexMessage
}
}
mode := ""
Return
#If MouseUnderFile()
~LButton::
if (A_PriorHotkey = A_ThisHotKey) and (A_TimeSincePriorHotkey <= DoubleClickTime) and (file := Explorer_GetSelection().1)
{
IniRead, SysexMessage, %ini%, maps, %file%
If !(SysexMessage ~= "^ERROR$|^$")
{
SysexArray := StrSplit(SysexMessage, A_Space)
VarSetCapacity(SysexBin, SysexArray.MaxIndex(), 0)
loop % SysexArray.MaxIndex()
NumPut("0x" SysexArray[A_Index], &SysexBin, A_Index-1, "uchar")
VarSetCapacity(MIDIHDR, 10*A_PtrSize+8, 0)
NumPut(&SysexBin, MIDIHDR, 0)
NumPut(SysexArray.MaxIndex(), MIDIHDR, A_PtrSize, "uint")
NumPut(SysexArray.MaxIndex(), MIDIHDR, A_PtrSize+4, "uint")
DllCall("winmm.dll\midiOutPrepareHeader", "ptr", midiOutHandle, "ptr", &MIDIHDR, "uint", 10*A_PtrSize+8)
DllCall("winmm.dll\midiOutLongMsg", "ptr", midiOutHandle, "ptr", &MIDIHDR, "uint", 10*A_PtrSize+8)
loop
{
hr := DllCall("winmm.dll\midiOutUnprepareHeader", "ptr", midiOutHandle, "ptr", &MIDIHDR, "uint", 10*A_PtrSize+8)
if (hr != 65) ; MIDIERR_STILLPLAYING
break
sleep 10
}
}
}
return
#If
OpenMidiIn()
{
count := DllCall("winmm.dll\midiOutGetNumDevs") - 1
if (count = 0)
{
msgbox no midi devices
exitapp
}
loop % count
{
id := A_Index-1
hr := DllCall("winmm.dll\midiInOpen", "ptr*", midiInHandle, "uint", id, "ptr", A_ScriptHwnd, "uint", 0, "uint", MIDI_CALLBACK_WINDOW := 0x10000)
if hr or ErrorLevel
{
Continue
msgbox % "midiInOpen error `nid = " id "`nhr = " hr "`nErrorLevel = " ErrorLevel
exitapp
}
hr := DllCall("winmm.dll\midiInStart", "ptr", midiInHandle)
if hr or ErrorLevel
{
Continue
msgbox % "midiInStart error `nid = " id "`nhr = " hr "`nErrorLevel = " ErrorLevel
exitapp
}
}
return
}
MidiInCallback(wParam, lParam, msg)
{
Critical
Data := NumGet(lParam+0, 0, "ptr")
BytesRecorded := NumGet(lParam+0, A_PtrSize+4, "uint") ; dwBytesRecorded
loop % BytesRecorded
SysexMessage .= Format("{:02X}", NumGet(Data+0, A_Index-1, "uchar")) " "
SysexMessage := SubStr(SysexMessage, 1, -1)
if (mode = "listen")
{
ControlSetText, Edit1, % SysexMessage, ahk_class #32770, Enter new mapping.
return
}
IniRead, file, %ini%, maps, %SysexMessage% ; Find the assigned string that matches this file
If !(file ~= "^ERROR$|^$") ; An assigned string was found
Run, %file%
return
}
Explorer_GetSelection() {
; https://www.autohotkey.com/boards/viewtopic.php?style=17&t=60403#p255256
array := []
WinGetClass, winClass, % "ahk_id " (hWnd := WinExist("A"))
If !(winClass ~="Progman|WorkerW|(Cabinet|Explore)WClass")
Return
shellWindows := ComObjCreate("Shell.Application").Windows
If !(winClass ~= "Progman|WorkerW") {
For window in shellWindows
If (hWnd = window.HWND) && (shellFolderView := window.Document)
Break
} Else shellFolderView := shellWindows.FindWindowSW(0, 0, SWC_DESKTOP := 8, 0, SWFO_NEEDDISPATCH := 1).Document
For item in shellFolderView.SelectedItems
result .= (result = "" ? "" : "`n") . item.Path, array.Push(item.Path)
If !result
result := shellFolderView.Folder.Self.Path
Return array
}
MouseUnderFile()
{
MouseGetPos,,, id
WinGetClass, class, ahk_id %id%
if (class = "Progman") or (class = "WorkerW") or (class = "CabinetWClass") or (class = "ExploreWClass")
return true
}