Page 6 of 6

Re: Automation Challenge

Posted: 05 Nov 2020, 00:48
by malcev

Code: Select all

Global ini := "D:\test.ini" ; Path to your INI file
midiInDevice := 2
midiOutDevice := 3


setbatchlines -1
Global midiInHandle, MIDIHDR2, mode := ""
DoubleClickTime := DllCall("GetDoubleClickTime")
DllCall("LoadLibrary", "str", "winmm.dll", "ptr")
hr := DllCall("winmm.dll\midiOutOpen", "ptr*", midiOutHandle, "uint", midiOutDevice, "ptr", 0, "uint", 0, "uint", 0)
if hr or ErrorLevel
{
   msgbox % "midiOutOpen error `nhr = " hr "`nErrorLevel = " ErrorLevel
   exitapp
}
hr := DllCall("winmm.dll\midiInOpen", "ptr*", midiInHandle, "uint", midiInDevice, "ptr", A_ScriptHwnd, "uint", 0, "uint", MIDI_CALLBACK_WINDOW := 0x10000)
if hr or ErrorLevel
{
   msgbox % "midiInOpen error `nhr = " hr "`nErrorLevel = " ErrorLevel
   exitapp
}
hr := DllCall("winmm.dll\midiInStart", "ptr", midiInHandle)
if hr or ErrorLevel
{
   msgbox % "midiInStart error `nhr = " hr "`nErrorLevel = " ErrorLevel
   exitapp
}
buffer_size := 16000   ; up to 64k
VarSetCapacity(midiInBuffer, buffer_size, 0)
VarSetCapacity(MIDIHDR2, 10*A_PtrSize+8, 0)
NumPut(&midiInBuffer, MIDIHDR2, 0)
NumPut(buffer_size, MIDIHDR2, A_PtrSize, "uint")
NumPut(buffer_size, MIDIHDR2, A_PtrSize+4, "uint")
DllCall("winmm.dll\midiInPrepareHeader", "ptr", midiInHandle, "ptr", &MIDIHDR2, "uint", 10*A_PtrSize+8)
DllCall("winmm.dll\midiInAddBuffer", "ptr", midiInHandle, "ptr", &MIDIHDR2, "uint", 10*A_PtrSize+8)
OnMessage(MIDI_LONGDATA := 0x3C4, "MidiInCallback")
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

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)
   DllCall("winmm.dll\midiInAddBuffer", "ptr", midiInHandle, "ptr", &MIDIHDR2, "uint", 10*A_PtrSize+8)
   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
}

Re: Automation Challenge

Posted: 05 Nov 2020, 01:21
by elad770
Hahaha, I was refreshing my page many times, not realizing you are at page 6 LOL

Testing now

Standby...

Re: Automation Challenge

Posted: 05 Nov 2020, 01:25
by elad770
:superhappy: :superhappy: :superhappy: :superhappy: :superhappy: :superhappy: :superhappy: :superhappy: :superhappy: :superhappy: :superhappy: :superhappy: :superhappy:

OMG!

Re: Automation Challenge

Posted: 05 Nov 2020, 01:30
by elad770
Everything seems to work flawlessly!!!

malcev, seriously??? I don't know who you are or where you are from but I can't describe to you how I reacted. 1:30 am and I screamed from the basement! LOL

Can you please tell me if you have PayPal? Please......

Re: Automation Challenge

Posted: 05 Nov 2020, 01:33
by elad770
Can we do a tiny and really quick bug fix?

Re: Automation Challenge

Posted: 05 Nov 2020, 01:34
by malcev
::)) I have send my PayPal in PM to You.
Yes We can.

Re: Automation Challenge

Posted: 05 Nov 2020, 01:41
by elad770
Actually, it's not a bug at all. More like a behavioral change

Firstly I just want to say that the cancel button does exactly what the ok button does. they both map the sysex. But, could be this is not even relevant.

Can we please Not having me press any confirmation button?
At the moment I need to click on OK after the sysex is in and Another OK after the msg dialog that syas it was mapped
All i want is that when the message is in (after i press the Synth) a tiny confirmation window will appear saying: "Successful" and will close after 1sec
I don't want to click any OK's

Re: Automation Challenge

Posted: 05 Nov 2020, 01:52
by elad770
Basically

I only need to press F3

Dialog box appears

I press on my Synth Button

A dialog box says Successful and disappears automatically after 1sec

Re: Automation Challenge

Posted: 05 Nov 2020, 01:58
by malcev
Do You want dialog box or just tooltip?

Re: Automation Challenge

Posted: 05 Nov 2020, 02:04
by elad770
One second

I'm googling the term tooltip .... LOL :lol:

Re: Automation Challenge

Posted: 05 Nov 2020, 02:09
by malcev

Code: Select all

#persistent
tooltip ok

Re: Automation Challenge

Posted: 05 Nov 2020, 02:11
by elad770
If you are already a perfectionist

I would like a tooltip but it should fade in 0.5sec and fade out 0.5sec. Can I add my own audible effect instead of the system sound? when it fades in with a successful message?

These are all Bonuses for me my friend. I already own mount Everest right now. Feel free to call it for today

Re: Automation Challenge

Posted: 05 Nov 2020, 02:12
by elad770
malcev wrote:
05 Nov 2020, 02:09

Code: Select all

#persistent
tooltip ok
What should i do with that?

Re: Automation Challenge

Posted: 05 Nov 2020, 02:22
by malcev
I answered You in PM.
Lets continue there.

Re: Automation Challenge

Posted: 05 Nov 2020, 02:26
by elad770
Got it, I'm there

Re: Automation Challenge

Posted: 05 Nov 2020, 09:31
by elad770
Just to conclude here.

I'm very grateful and thankful for the members who helped me out here.

even though, it's very hard for me financially, I'm a man of my word.

I was helped with solving something I was troubled with for a long time and this community earned this donation (see attached)

Thank you, everyone!! :bravo:

Re: Automation Challenge

Posted: 05 Nov 2020, 09:49
by mikeyww
:bravo: :dance: :D Thank you for your generosity, Elad! I'm sure that your contribution will help the AHK world.