Jump to content
BetaLeaf

[Solved]How to create a Function with flags in a Function for use with Hotkeyset

Recommended Posts

BetaLeaf

Hi guys. I am trying to make a soundboard app. 

Here is the code I have so far

#include "Misc.au3"
#RequireAdmin;needed to work in some games.
#include "array.au3"
Opt("WinTitleMatchMode", -2)
If @OSArch = "x64" Then
    Global $VLC_Path = "C:\Program Files (x86)\VideoLAN\VLC\vlc.exe"
    Global $VLC_WorkingDir = "C:\Program Files (x86)\VideoLAN\VLC\"
Else
    Global $VLC_Path = "C:\Program Files\VideoLAN\VLC\vlc.exe"
    Global $VLC_WorkingDir = "C:\Program Files\VideoLAN\VLC\"
EndIf
Global $sectionData = IniReadSectionNames(@ScriptDir & "\SoundBoard.ini")
If @error Then
    IniWriteSection(@ScriptDir & "\SoundBoard.ini", "Sound1", 'File="' & @UserProfileDir & '\Music\SampleTrack.mp3"' & @CRLF & 'StartTime="12"' & @CRLF & 'EndTime="34"' & @CRLF & 'PlaybackDevice="Microsoft Soundmapper"' & @CRLF & 'Hotkey="+{numpad9}"')
    MsgBox(16, "SoundBoard", "SoundBoard.ini is missing. It has been created for you.")
    ShellExecute(@ScriptDir & "\SoundBoard.ini", "", "", "edit")
    InputBox("SoundBoard", "Notes:" & @CRLF & "StartTime and EndTime are in seconds. Available Hotkeys can be found at the following url:", "https://www.autoitscript.com/autoit3/docs/functions/Send.htm")
    Exit
EndIf
For $i = 1 To $sectionData[0]
    Local $iArray = IniReadSection(@ScriptDir & "\SoundBoard.ini", $sectionData[$i])
    For $j = 1 To UBound($iArray) - 1
        Local $result = Assign("SoundBoard" & $i & "_" & $j, IniRead(@ScriptDir & "\SoundBoard.ini", $sectionData[$i], $iArray[$j][0], $iArray[$j][1]), 2)
        If $result = 1 Then
            Consolewrite("Variable Assigned: SoundBoard" & $i & "_" & $j & @CRLF & "Data=" & $iArray[$j][1]&@CRLF)
        Else
            Consolewrite("Variable was not assigned: SoundBoard" & $i & "_" & $j & @CRLF & "Data=" & $iArray[$j][1]&@CRLF)
        EndIf
        
    Next
Next
For $i = 1 To $sectionData[0]
    Local $Hotkey = Eval("SoundBoard"&$i&"_5")
    ConsoleWrite("Processing Hotkey "&$Hotkey&@CRLF)

;NEED HELP HERE
    
;   HotKeySet($Hotkey,"")
Next
While 1
    Sleep(500);idle to prevent unnecessary work. 10 is the minimal we can set this value to.
WEnd
Func LoadVLC($iPlayFile, $iPlayFileStartTime, $iPlayFileEndTime, $iPlayAudioDevice = "Microsoft Soundmapper")
    ShellExecuteWait($VLC_Path, '--qt-start-minimized --play-and-exit --start-time="' & $iPlayFileStartTime & '" --stop-time="' & $iPlayFileEndTime & '" --aout=waveout --waveout-audio-device="' & $iPlayAudioDevice & '" "' & $iPlayFile & '"', $VLC_WorkingDir, "", @SW_HIDE)
    Beep(500, 200)
EndFunc   ;==>LoadVLC

For example, I have a song called "MoonlightSonata.mp3" and I want to activate it with hotkey !{numpad9}. However, hotkeyset does not allow sending of flags so I cannot use LoadVLC as it is now. I need to create a function that stores the flags using the data from the earlier Inireads. Ik how to use the data but not how to create the function to store that data. I looked at IsFunc() second example but I do not understand. Sorry if I am not being clear on what I am trying to do. My brain is fried right now after trying various things for an hour. Any help would be appreciated. 

The idea is to be able to have a dedicated hotkey for each sound I want to play so I will need to have my script create a new function by itself using the data from the INI.

hotkeyset("$hotkey1","MySoundBoard1")
hotkeyset("$hotkey2","MySoundBoard2")
func MySoundBoard1()
    LoadVLC("MoonlightSonata.mp3") ;the other flags are optional and will not be set for simplicity.
endfunc
func MySoundBoard1()
    LoadVLC("TheBananaSong.mp3")
endfunc

Honestly I don't care how it is done as long as I have a dedicated hotkey for each entry in my ini.  An example of such an entry looks like

[Sound1]
File="C:\Users\BetaL\Music\SampleTrack1.mp3"
StartTime="12"
EndTime="34"
PlaybackDevice="Microsoft Soundmapper"
Hotkey="!{numpad8}"

[Sound2]
File="C:\Users\BetaL\Music\SampleTrack2.mp3"
StartTime="24"
EndTime="43"
PlaybackDevice="Microsoft Soundmapper"
Hotkey="!{numpad9}"

Am I making any sense? Please let me know.

 

Edit: Huge thanks to @Melba23 for the learning experience, his time, and help.

Edited by BetaLeaf
To give thanks.

False Positive Reporter - Mass email all anti virus vendors with an attachment of your program for fast and easy whitelisting.

PortableApps.com App Creation Wizard  - A simple GUI-based Wizard for creating PortableApps.

SoundBoard - Play any song or sound you want at the press of a hotkey.

My GitHub Page: https://github.com/BetaLeaf

Share this post


Link to post
Share on other sites
Melba23

BetaLeaf,

Using your ini format I have recast the script and I believe it now does what you require:

;#RequireAdmin;needed to work in some games. <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< This does not make me very happy <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<

#include "Misc.au3"
#include "Array.au3"

Opt("WinTitleMatchMode", -2)

If @OSArch = "x64" Then
    Global $VLC_Path = "C:\Program Files (x86)\VideoLAN\VLC\vlc.exe"
    Global $VLC_WorkingDir = "C:\Program Files (x86)\VideoLAN\VLC\"
Else
    Global $VLC_Path = "C:\Program Files\VideoLAN\VLC\vlc.exe"
    Global $VLC_WorkingDir = "C:\Program Files\VideoLAN\VLC\"
EndIf

$sIniName = @ScriptDir & "\SoundBoard.ini"

; Read ini section names
Global $aSectionList = IniReadSectionNames($sIniname)

; Create data array to hold ini data for each HotKey
Global $aHotKeyData[UBound($aSectionList)][5]
;_ArrayDisplay($aHotKeyData, "", Default, 8)

If @error Then
    IniWriteSection($sIniname, "Sound1", 'File="' & @UserProfileDir & '\Music\SampleTrack.mp3"' & @CRLF & 'StartTime="12"' & @CRLF & 'EndTime="34"' & @CRLF & 'PlaybackDevice="Microsoft Soundmapper"' & @CRLF & 'Hotkey="+{numpad9}"')
    MsgBox(16, "SoundBoard", "SoundBoard.ini is missing. It has been created for you.")
    ShellExecute($sIniname, "", "", "edit")
    InputBox("SoundBoard", "Notes:" & @CRLF & "StartTime and EndTime are in seconds. Available Hotkeys can be found at the following url:", "https://www.autoitscript.com/autoit3/docs/functions/Send.htm")
    Exit
EndIf

; For each section
For $i = 1 To $aSectionList[0]

    ; Read ini section
    $aSection = IniReadSection($sIniname, $aSectionList[$i])

    ; Fill HotKey data array                                                                ; example content
    $aHotKeyData[$i][0] = IniRead($sIniName, $aSectionList[$i], "HotKey", "Error")          ; !{numpad8}
    $aHotKeyData[$i][1] = IniRead($sIniName, $aSectionList[$i], "File", "Error")            ; C:\Users\BetaL\Music\SampleTrack1.mp3
    $aHotKeyData[$i][2] = IniRead($sIniName, $aSectionList[$i], "StartTime", "Error")       ; 12
    $aHotKeyData[$i][3] = IniRead($sIniName, $aSectionList[$i], "EndTime", "Error")         ; 34
    $aHotKeyData[$i][4] = IniRead($sIniName, $aSectionList[$i], "PlayBackDevice", "Error")  ; Microsoft Soundmapper

    ; Set HotKey to common function
    HotKeySet($aHotKeyData[$i][0], "_HotKeyFunc")

Next

;_ArrayDisplay($aHotKeyData, "", Default, 8)

While 1
    Sleep(10);idle to prevent unnecessary work. 10 is the minimal we can set this value to.
WEnd

Func _HotKeyFunc()

    ;Get HotKey pressed
    $sHotKeyPressed = @HotKeyPressed

    ;ConsoleWrite($sHotKeyPressed & @CRLF)

    ; Find HotKey pressed in the data array
    $iIndex = _ArraySearch($aHotKeyData, $sHotKeyPressed)
    ; Check found
    If $iIndex <> -1 Then
        ; Create parameter using the data in the array
        $sParam = '--qt-start-minimized --play-and-exit --start-time="' & $aHotKeyData[$iIndex][2] & '" --stop-time="' & $aHotKeyData[$iIndex][3] & '" --aout=waveout --waveout-audio-device="' & _
        $aHotKeyData[$iIndex][4] & '" "' & $aHotKeyData[$iIndex][1] & '"'
        ; Simulate passing commandline to VLC
        ConsoleWrite("ShellExecuteWait:" & @CRLF & $VLC_Path & @CRLF & $sParam & @CRLF & $VLC_WorkingDir & @CRLF & @CRLF)
        Beep(500, 200)
    Else
        ConsoleWrite("Not a valid HotKey" & @CRLF)
    EndIf

EndFunc

I have commented out a number of _ArrayDisplay/ConsoleWrite lines - just uncomment them to see what happens at the various stages.

M23

  • Like 1

Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind._______My UDFs:

Spoiler

ArrayMultiColSort ---- Sort arrays on multiple columns
ChooseFileFolder ---- Single and multiple selections from specified path treeview listing
Date_Time_Convert -- Easily convert date/time formats, including the language used
ExtMsgBox --------- A highly customisable replacement for MsgBox
GUIExtender -------- Extend and retract multiple sections within a GUI
GUIFrame ---------- Subdivide GUIs into many adjustable frames
GUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView items
GUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeView
Marquee ----------- Scrolling tickertape GUIs
NoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxes
Notify ------------- Small notifications on the edge of the display
Scrollbars ----------Automatically sized scrollbars with a single command
StringSize ---------- Automatically size controls to fit text
Toast -------------- Small GUIs which pop out of the notification area

 

Share this post


Link to post
Share on other sites
BetaLeaf

Amazing @Melba23, I wasn't aware of @HotKeyPressed. I greatly appreciate your help.

 

About the #requireadmin. I'm not going to try and defend myself. Instead I will just simply tell you why that was even there. I have friends on Dota 2 that like to hear music while they play the game and in order to activate the hotkey in the game, admin is required. If I don't then the hotkey doesn't recognize it was pressed. How I send audio from my soundboard is a simple matter. I just connect a headphone cable that is male on both ends, one into my mic jack, the other into my headphone jack. That is where the playback device flag comes in.

@Melba23 Once again I thank you from the bottom of my heart. You have provided me with a fantastic learning experience and I greatly appreciate your kindness, time, and expertise. You didn't have to help at all but you did. I am grateful.

Jeff Savage ~ BetaLeaf

Edited by BetaLeaf

False Positive Reporter - Mass email all anti virus vendors with an attachment of your program for fast and easy whitelisting.

PortableApps.com App Creation Wizard  - A simple GUI-based Wizard for creating PortableApps.

SoundBoard - Play any song or sound you want at the press of a hotkey.

My GitHub Page: https://github.com/BetaLeaf

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

  • Similar Content

    • AndreasNWWWWW
      By AndreasNWWWWW
      I got a question:  i am trying to run different functions based upon what i select in these radio buttons.(code below)
      it needs to check server 1. then run function 1 or function 2 after what i selected in the checkbox.
      once that function is done it moves to the next one, until it has been trough all 5 
       
      iv'e tried using while loops with different while $i equals to something but then i manualy need to go in and edit the script every time.
      #include <ButtonConstants.au3> #include <GUIConstantsEx.au3> #include <StaticConstants.au3> #include <WindowsConstants.au3> #Region ### START Koda GUI section ### Form= $Form1 = GUICreate("Form1", 615, 437, 192, 124) $Server2 = GUICtrlCreateLabel("Server2", 216, 95, 41, 17) $server1 = GUICtrlCreateLabel("Server1", 216, 72, 41, 17) $server4 = GUICtrlCreateLabel("Server4", 216, 144, 41, 17) $server3 = GUICtrlCreateLabel("Server3", 216, 119, 41, 17) $server5 = GUICtrlCreateLabel("Server5", 216, 170, 41, 17) $Start = GUICtrlCreateButton("Start", 240, 248, 147, 25) $Checkbox1 = GUICtrlCreateCheckbox("function1", 288, 72, 97, 17) $Checkbox2 = GUICtrlCreateCheckbox("function2", 392, 72, 97, 17) $Checkbox3 = GUICtrlCreateCheckbox("function1", 288, 96, 97, 17) $Checkbox4 = GUICtrlCreateCheckbox("function2", 392, 96, 97, 17) $Checkbox5 = GUICtrlCreateCheckbox("function1", 288, 120, 97, 17) $Checkbox6 = GUICtrlCreateCheckbox("function2", 392, 120, 97, 17) $Checkbox7 = GUICtrlCreateCheckbox("function1", 288, 144, 97, 17) $Checkbox8 = GUICtrlCreateCheckbox("function2", 392, 144, 97, 17) $Checkbox9 = GUICtrlCreateCheckbox("function1", 288, 170, 97, 17) $Checkbox10 = GUICtrlCreateCheckbox("function2", 392, 170, 97, 17) GUISetState(@SW_SHOW) #EndRegion ### END Koda GUI section ### While 1 $nMsg = GUIGetMsg() Switch $nMsg Case $GUI_EVENT_CLOSE Exit EndSwitch WEnd  
    • guinness
      By guinness
      Right now the script will exit immediately if I don't pause it somehow (obvious of course).
      I was  curious on people's opinions of how they do it or what option they prefer below? Thanks
      Option 1 (I prefer)
      #include <MsgBoxConstants.au3> HotKeySet('^!p', SomeFunc) ProcessWaitClose(@AutoItPID) Func SomeFunc() MsgBox($MB_SYSTEMMODAL, "Title", "This message box will timeout after 10 seconds or select the OK button.", 10) EndFunc Option 2 (in the help file)
      #include <MsgBoxConstants.au3> HotKeySet('^!p', SomeFunc) While Sleep(100) WEnd Func SomeFunc() MsgBox($MB_SYSTEMMODAL, "Title", "This message box will timeout after 10 seconds or select the OK button.", 10) EndFunc Option 3
      #include <MsgBoxConstants.au3> HotKeySet('^!p', SomeFunc) While 1 GUIGetMsg() ; Use the internal sleep WEnd Func SomeFunc() MsgBox($MB_SYSTEMMODAL, "Title", "This message box will timeout after 10 seconds or select the OK button.", 10) EndFunc  
    • wsc77320
      By wsc77320
      Maybe I am trying this all wrong, but hope someone can help. I have a GUI and want to click a button which will start a function to get a folder location. Then I need to pass that location to a variable to use outside the function. Here is a sample of the code;It prompts to choose a file location and the message box displays the choice but that is all inside the function. I need to pass the path selected outside the function. OR need a different way of doing this, maybe my approach is wrong.
      $Label_Drive=GUICtrlCreateLabel("Use the select button and choose where profiles will be stored.", 15, 120, 240, 25)
      $BTN_Set_BKP_Path = GUICtrlCreateButton("Select Location", 250, 120, 90, 30) ;left,top,width,heigth
      GUICtrlSetOnEvent($BTN_Set_BKP_Path, "Location")
       
      Func Location()
      $BKP_Path = FileSelectFolder("Select a folder where profiles will be stored.", "c:\")
      MsgBox(0,"Select Path", "You set the path as " & $BKP_Path)
      EndFunc
       
      $Label_BKP_Path=GUICtrlCreateLabel("Current path is " & $BKP_Path & ".", 15, 150, 300, 25)
       
       
    • Karnalsyn
      By Karnalsyn
      As with a lot of programming, the less manual repetition done to achieve the same outcome...the better.
      I package programs for network deployment at the organization I work for. Sometimes these applications require verbose messaging to the user, and sometimes by special request we have to turn that off and deploy silently.
      The way I currently handle these 2 scenarios is this.
      I have a function that builds the splashwin display screen to variable size depending on message length, and displays the desired message to the end user.
      Then at each point throughout my script as I need to make the user aware of what is currently happening, I inject a splashwin function call with the unique message pertaining to that specific event. ie. "Installing Microsoft Office, please wait..."
      In effort to build a more universal script to handle any type of request submitted. I've incorporated a switch command of '/silent'
      If cmdlineraw detects the usage of that switch when the script is triggered it sets a variable flag, ie. $silent = "on"
      Then at every splashwin call I make, I'm prefixing it with an IF statement that checks for the flag, and then does NOT display the message if that flag is "on". Or does display it if its not. Has worked for me just fine. But while I grow my programming skills and look for more streamlined ways of handling areas I find myself creating repetition. I'm curious if I can relocate that flag check. Taking it out of every single splashwin call, and injecting it into the function itself.
      Example of how I currently display or hide the splashwin based on command line...
      If StringInStr($cmdlineraw, "/silent", 0) Then
          $SilentSwitch = "ON"
      EndIf
      If $SilentSwitch = "OFF" Then SplashWin($Uninstalling & $ProductInfo[1][0])
      Some scripts have dozens of those splashwin calls littered throughout, so Is this the best approach I can take already? Or as stated earlier, can I pull the IF statement away from the splashwin call. And left the function as a whole either activate or deactivate as a result of the command line check.
    • AndreyS
      By AndreyS
      Dear developers and creators of the language, please explain to me why when pressing the combination Crtl + Shift + C from the 5th or the 10th time "sticks / sinks" Ctrl or Shift? And then you need to press Ctrl or Shift again to reset their triggering. I only need to use hot keys like in the example!
      The code is a small example. Its essence is that when a user in the editor selects any number and presses a combination, then it increases by 1. 
      Dim $x HotKeySet("+^c","Calc") While 1 Sleep(10000) WEnd Func Calc() Send("^c") Sleep(50) $x=ClipGet()+1 ClipPut($x) Send("^v") EndFunc I thought that in my program some kind of glitch was searching for a reason for a long time. And it turned out that apparently somehow the work of some functions used in the example is not compatible. 
      Tell me, please, what is the problem?
×