Page 3 of 6

Re: Automation Challenge

Posted: 03 Nov 2020, 17:08
by mikeyww
You're right. We already sold this to Microsoft. Better luck next time.

:wave: :D

OK, you inspired me to go get a 32-key MIDI controller. It will take me about a week to figure this out!

Re: Automation Challenge

Posted: 03 Nov 2020, 17:17
by elad770
I'm not sure I understand your question.

My midi controller is connected right now and messages are coming in.

I activated your script and i understand that i need to press something (F1?) and see if it capture something?

Re: Automation Challenge

Posted: 03 Nov 2020, 17:21
by malcev
No, You have to press midi buttons and see msgbox in ahk.

Re: Automation Challenge

Posted: 03 Nov 2020, 17:24
by elad770
mikeyww wrote:
03 Nov 2020, 17:08
You're right. We already sold this to Microsoft. Better luck next time.

:wave: :D

OK, you inspired me to go get a 32-key MIDI controller. It will take me about a week to figure this out!

I'm just speechless Mikey! You have no idea how much I appreciate the fact that you are being a sport when it comes to my ignorance.

I KNOW THAT YOU ARE BOTH RIGHT and probably you both understand and got it to work, but if I don't have a step by step of what EXACTLY I need to be doing for you to assess whether it works or not, it will be challenging

I speak fluent Hebrew and English but when you dominate code you tend to speak like a coder and my brain is detecting it like a new language. Try to guide me like this:

1. Download this script, copy paste, and run it
2. Enter the script and inline xxxx change it to the name of your midi device
3. open a folder and press on F3,F3,F10
4. Hit your controller
5. Does it responds? Did you notice a message coming in?

Something like that.

I promise you guys I can follow directions very well but with specificity

Re: Automation Challenge

Posted: 03 Nov 2020, 17:27
by elad770
malcev wrote:
03 Nov 2020, 17:21
No, You have to press midi buttons and see msgbox in ahk.
Ok, that's a specific command i can follow! Yeh!

I understood that there's a line in the script called msgbox where the midi message is suppose to appear?
Ok, i can do that

1. Run the script
2. Hit a key on my keboard
3. Enter the script to see if there's something appear in the msgbox

Standby...

Re: Automation Challenge

Posted: 03 Nov 2020, 17:30
by elad770
Nothing happened

Re: Automation Challenge

Posted: 03 Nov 2020, 17:32
by malcev
Run this script.
Hit your controller.
Do You see any messages?

Code: Select all

Global mode := ""
DllCall("LoadLibrary", "Str", "winmm.dll", "Ptr")
OnMessage(MIDI_OPEN := 0x3C1, "MidiInCallback")
OnMessage(MIDI_CLOSE := 0x3C2, "MidiInCallback")
OnMessage(MIDI_DATA := 0x3C3, "MidiInCallback")
OnMessage(MIDI_LONGDATA := 0x3C4, "MidiInCallback")
OnMessage(MIDI_ERROR := 0x3C5, "MidiInCallback")
OnMessage(MIDI_LONGERROR := 0x3C6, "MidiInCallback")
OnMessage(MIDI_MOREDATA := 0x3CC, "MidiInCallback")
OpenMidiIn()
return

f1::
mode := "listen"
; some code
mode := ""
return



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
      {
         msgbox % "midiInOpen error `nid = " id "`nhr = " hr "`nErrorLevel = " ErrorLevel
         exitapp
      }
      hr := DllCall("winmm.dll\midiInStart", "ptr", midiInHandle)
      if hr or ErrorLevel
      {
         msgbox % "midiInStart error `nid = " id "`nhr = " hr "`nErrorLevel = " ErrorLevel
         exitapp
      }
   }
   return
}
MidiInCallback(wParam, lParam, msg)
{
   Critical
   highByte := lParam & 0xF0 
   lowByte := lParam & 0x0F
   data1 := (lParam >> 8) & 0xFF
   data2 := (lParam >> 16) & 0xFF
   if (data2 = 0)
      return
   key := highByte "-" lowByte "-" data1
   if (mode = "listen")
   {
      msgbox % "listen`n" key
      return
   }
   ; here get info from ini file if key exist then run its value
   msgbox  % "run`n" key
   return
}

Re: Automation Challenge

Posted: 03 Nov 2020, 18:10
by elad770
Yes Sir!!!! Something came up!

I ran the script and hit a regular key, any key.

This message comes up (see attached)

Re: Automation Challenge

Posted: 03 Nov 2020, 18:18
by malcev
Why do You have error in second message box?
What is written there?

Re: Automation Challenge

Posted: 03 Nov 2020, 18:23
by elad770
Sorry for that.

Here you go...

Re: Automation Challenge

Posted: 03 Nov 2020, 18:26
by elad770
I had a lot of programs running in the background. LOOPmidi, Midi-osx. Misi2key

I closed everything and this is the message that appears

Re: Automation Challenge

Posted: 03 Nov 2020, 18:33
by malcev
Try to restart computer.

Re: Automation Challenge

Posted: 03 Nov 2020, 18:42
by elad770
Same behavior.

The same message comes up. But it does respond to the midi press on my keyboard.

Here's the whole action

https://youtu.be/yDNOGqHIcCw

Re: Automation Challenge

Posted: 03 Nov 2020, 19:23
by malcev
Strange, but OK.
I combined mikeyww code with mine.
Change path of ini file to Yours
Then select any file, press f3
Hit your controller
after that You should see key name in inputbox
Press OK.
Hit your controller once again - file will open.
To delete key of you controller - select any file press f3, hit controller button that You want to delete, and write "DEL" before or after key in input box.

Code: Select all

Global ini := "D:\temp\mwMIDI.ini" ; Path to your INI file

setbatchlines -1
Global mode := ""
DllCall("LoadLibrary", "Str", "winmm.dll", "Ptr")
OnMessage(MIDI_OPEN := 0x3C1, "MidiInCallback")
OnMessage(MIDI_CLOSE := 0x3C2, "MidiInCallback")
OnMessage(MIDI_DATA := 0x3C3, "MidiInCallback")
OnMessage(MIDI_LONGDATA := 0x3C4, "MidiInCallback")
OnMessage(MIDI_ERROR := 0x3C5, "MidiInCallback")
OnMessage(MIDI_LONGERROR := 0x3C6, "MidiInCallback")
OnMessage(MIDI_MOREDATA := 0x3CC, "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, newMidi, %fn%, Current mapping: %midi%`n`nEnter new mapping.,, 300, 125 ; Ask user for string assignment
if InStr(newMidi, "del")
{
   newMidi := RegexReplace(newMidi, "[a-zA-Z\s]")
   IniRead, file, %ini%, maps, %newMidi%
   IniDelete, %ini%, maps, % newMidi ; Delete the assignment
   MsgBox, 64, Deleted, % "Mapped: " file "`n`n        To: " newMidi " [DELETED]"
}
else if (newMidi != "")
{
   IniWrite, %file%, %ini%, maps, %newMidi% ; Save the assignment
   {
      If ErrorLevel
         MsgBox, 48, Error, An error occurred during the mapping.
      Else
         MsgBox, 64, Changed, % "Mapped: " file "`n`n        To: " newMidi
   }
}
mode := ""
Return
#IfWinActive


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
   highByte := lParam & 0xF0 
   lowByte := lParam & 0x0F
   data1 := (lParam >> 8) & 0xFF
   data2 := (lParam >> 16) & 0xFF
   if (data2 = 0)
      return
   key := highByte "-" lowByte "-" data1
   if (mode = "listen")
   {
      ControlSetText, Edit1, % key, ahk_class #32770, Enter new mapping.
      return
   }
   IniRead, file, %ini%, maps, %key% ; 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
}

Re: Automation Challenge

Posted: 03 Nov 2020, 20:33
by elad770
I'm very excited to try it.

Before I do, one final question because I didn't get it before:

What is INI file? Where is it located?

I understand how to change the path in the script but I still don't know where is it by default?

Re: Automation Challenge

Posted: 03 Nov 2020, 20:38
by malcev
It is configuration file.
It can be at any location.
If ini does not exist, script creates it.

Re: Automation Challenge

Posted: 03 Nov 2020, 20:39
by elad770
Got it!

Trying it now.. Fingures crossed

Re: Automation Challenge

Posted: 03 Nov 2020, 20:43
by elad770
This is the message that i get - error message

- The script excute without errors
- F3 pop up open
- Midi is receiving - a midi message

Upon hitting OK - the error message appears

Re: Automation Challenge

Posted: 03 Nov 2020, 20:44
by elad770
I don't know if this is related but out of curiosity i checked the target folder i placed for the INI file ---> C:\Users\eladb\Desktop\TEST

I saw that no file was created

Maybe i should change to lower case folder name?

Didn't work, same error message appears

Re: Automation Challenge

Posted: 03 Nov 2020, 20:51
by malcev
May be there is no folder test on desktop?
Run this code, what errorlevel You will get?

Code: Select all

Global ini := "D:\test.ini" ; Path to your INI file

setbatchlines -1
Global mode := ""
DllCall("LoadLibrary", "Str", "winmm.dll", "Ptr")
OnMessage(MIDI_OPEN := 0x3C1, "MidiInCallback")
OnMessage(MIDI_CLOSE := 0x3C2, "MidiInCallback")
OnMessage(MIDI_DATA := 0x3C3, "MidiInCallback")
OnMessage(MIDI_LONGDATA := 0x3C4, "MidiInCallback")
OnMessage(MIDI_ERROR := 0x3C5, "MidiInCallback")
OnMessage(MIDI_LONGERROR := 0x3C6, "MidiInCallback")
OnMessage(MIDI_MOREDATA := 0x3CC, "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, newMidi, %fn%, Current mapping: %midi%`n`nEnter new mapping.,, 300, 125 ; Ask user for string assignment
if InStr(newMidi, "del")
{
   newMidi := RegexReplace(newMidi, "[a-zA-Z\s]")
   IniRead, file, %ini%, maps, %newMidi%
   IniDelete, %ini%, maps, % newMidi ; Delete the assignment
   MsgBox, 64, Deleted, % "Mapped: " file "`n`n        To: " newMidi " [DELETED]"
}
else if (newMidi != "")
{
   IniWrite, %file%, %ini%, maps, %newMidi% ; Save the assignment
   {
      If ErrorLevel
         MsgBox, 48, Error, An error occurred during the mapping. errorlevel - %errorlevel%
      Else
         MsgBox, 64, Changed, % "Mapped: " file "`n`n        To: " newMidi
   }
}
mode := ""
Return
#IfWinActive


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
   highByte := lParam & 0xF0 
   lowByte := lParam & 0x0F
   data1 := (lParam >> 8) & 0xFF
   data2 := (lParam >> 16) & 0xFF
   if (data2 = 0)
      return
   key := highByte "-" lowByte "-" data1
   if (mode = "listen")
   {
      ControlSetText, Edit1, % key, ahk_class #32770, Enter new mapping.
      return
   }
   IniRead, file, %ini%, maps, %key% ; 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
}