Jump to content
VlcUser

Controlling VLC

Recommended Posts

VlcUser

hello, and thank you in advance.

i just downloaded AutoIt after giving up trying to automate this procedure myself using other automation programs. Hopefully, what i've been reading is true, and AutoIt will be able to do the following for me.

You can assume the following: VLC is running. An MP4 is loaded and playing. The window title can change as different MP4s get loaded, but "VLC media player" is always part of the title. If an MP4 is actually playing, the string _edit.mp4 becomes part of the window title as well. The script will only be called on demand. There are exactly two monitors...the laptop and one HDMI external.

Sometimes VLC plays an MP3, and so VLC should only appear on the laptop. But when an MP4 get played, i need it on the external (extended) HDMI monitor, in full screen. The script can be invoked by the same procedure in my application that chooses the MP4 and sends it to VLC. Optionally, i could have the user click a button in my application to invoke the AutoIt script:

Here is the exact sequence of keystrokes i use manually to accomplish what i need:

Click on VLC to make it the active window

Hold down WIN and SHIFT then tap the left arrow key ...this sends the VLC window to the alternate monitor

Hold down the ALT key, tab V then F .... this makes VLC play in full screen  (   view menu > fullscreen )

When the MP4 finishes playing, VLC automatically returns to the small window.  (can autoit detect that the mp4 is finished playing because all my MP4 titles have the string _edit.mp4 in them, so can AutoIt look at the window title and determine that it does not contain that string?)

Hold down WIN and SHIFT then tap the left arrow key ...this sends the VLC window back to the laptop ... (If AutoIt cannot detect the end of the MP4, this could be another button in my application that calls an AutoIt script to do this step.)

 

Again, thank you. i may have some other automation needs and would consider $$ in return.

 

Share this post


Link to post
Share on other sites
VlcUser

sorry, correction to the previous post:

Hold down the ALT key, tab V then F .... this makes VLC play in full screen  (   view menu > fullscreen )

should not say "tab", it should say "tap" and be:

Hold down the ALT key, tap V then F .... this makes VLC play in full screen  (   view menu > fullscreen )

 

Share this post


Link to post
Share on other sites
JLogan3o13

@VLCUser welcome to the forum. Please understand this forum is dedicated to helping people who want to learn and improve their own scripts; it is not a place where you put in a request and someone does the code for you. You will need to show some effort if you would like help in return. I would suggest doing a forum search on VLC to begin with; there are a number of threads on automating this application. Once you have done some reading, try something on your own and if you run into issues post the code here so we can assist.


√-1 2^3 ∑ π, and it was delicious!

Share this post


Link to post
Share on other sites
VlcUser

Sorry to give the impression that I had not tried solving this. I spent literally all day today just trying to get autoit to tell me if VLC was active or not, and couldn't even get that far, although I cut and pasted from example scripts about automating notepad.

in frustration and desperation, I turned to this forum, hoping someone could solve in a short time what has already taken me a day with nil result.

 Could you please direct me to the proper forum to post my query?

Share this post


Link to post
Share on other sites
BatMan22
Posted (edited)
10 minutes ago, VlcUser said:

Sorry to give the impression that I had not tried solving this. I spent literally all day today just trying to get autoit to tell me if VLC was active or not, and couldn't even get that far, although I cut and pasted from example scripts about automating notepad.

in frustration and desperation, I turned to this forum, hoping someone could solve in a short time what has already taken me a day with nil result.

 Could you please direct me to the proper forum to post my query?

I'll make it really easy for you because I know it's hard to start.. That being said, you will need to finish it yourself as I don't even have VLC installed and I'm at work, also you showed zero effort. Like.. not even a single line of code to show you have something or tried something.

The Commands you need are: 

1) WinExist - Checks to see if the window exists

2) WinActivate - Bring the window to the front

3) Send - Sends Keys

3a) To hold down alt for your purposes it sounds like I would do (easiest way to understand)

Send("{AltDown}")

Send("v")

Send("f")

Send("{altup}")

3b) Send("#+{LEFT}")  ; This is Windows / Shift / Left (could be wrong, but I think it's right)

 

Post what you have and I'll gladly help you with the rest. Good luck.

Edited by BatMan22

Share this post


Link to post
Share on other sites
VlcUser

Thank you so much, Batman, i will work on your advice

as a newbie on this forum, i didn't know that it was expected for me to post my unsuccessful efforts to prove my commitment to solving my problem. Here is the final (unsuccessful) edit of what i've been trying (just to get AutoIt to acknowledge VLC is running):

Share this post


Link to post
Share on other sites
VlcUser
#include <MsgBoxConstants.au3>

Opt("WinTextMatchMode", -2)
WinActivate ("CLASS:VLC media player","")

If WinActive("[CLASS:VLC media player]") Then ; Check if VLC is currently active.
    MsgBox($MB_SYSTEMMODAL, "", "WinActive" & @CRLF & "VLC is active.")
Else
    MsgBox($MB_SYSTEMMODAL, "", "WinActive" & @CRLF & "VLC is not active.")
EndIf

 

Share this post


Link to post
Share on other sites
Bilgus

Ok so first off lets lay out some ground rules for your script

1. automagically transfer the vlc window to external monitor when video is playing 

1.5 move it back when finished?

2. full screen it

2.5 move back to previous position?

-----

3/0. you want this script to be running in background waiting for this

so instead of this how about we make our script name vlc.exe and call vlc_orig.exe and pass through any command line to the orig vlc.exe =>vlc_orig.exe and then have it fall back to looking for a playing video?

Share this post


Link to post
Share on other sites
VlcUser

Hi, Bilgus

Basically, you've got the idea. Up to now, i've always been OK with VLC running on the laptop display because i've only used mp3s. i am now implementing mp4s as well, so i could play a number of mp3s, then an mp4 etc etc, the clips get picked totally at random.

My application (already written) runs an internal set of commands which picks the clip and sends it to VLC. This set of internal commands knows if it sent an mp3 or an mp4 and if it's an mp4, can then also tell the computer to execute the AutoIt script.

So:

The vlc window just finished playing mp3(s) on the laptop screen, when i send an mp4, i want it to go to the extended monitor...windows will do this to the active window with a WIN+SHIFT+LEFTARROW key combination. Once VLC is on that screen, i need to go full screen, so with VLC still active  (ALT V F).

When the mp4 is finished playing, VLC automatically exits full screen (which is good...) and then another WIN+SHIFT+LEFTARROW key combination will send VLC back to the laptop.

The suggestion of calling vlc_orig.exe from a script called vlc.exe has already been tried, but doesn't work because VLC is already running. It seems that  VLC only reads the parameters --fullscreen when it initially starts up, however, VLC is already running and won't jump to fullscreen if i send that parameter again (i have VLC set to run one instance only, because during the course of running my program over a few hours, i could easily send over 300 clips to it.)

At this point, i am just trying to even see if i can get AutoIt to pause playing in VLC...that way i know that at least i am sending to the application. So far (unsuccessful):

Opt("WinTextMatchMode", 2)
WinActivate ("VLC media player","")
Sleep (500)
Send ("{space}")

Thank you!

Share this post


Link to post
Share on other sites
Bilgus
Posted (edited)

Ok so I got what probably the hardest part worked out

Sleep(1000) ; Just to give us some time to get hand off mouse/kb
Global Const $aFileTypes = ["mp4", "avi", "mkv"]
Global $sFileTypes = Build_File_Types($aFileTypes)

Global $g_MatchVLC_Win_Name = "VLC media player"
Global $g_MatchVLC_Win = "[REGEXPTITLE:(?i)(" & $sFileTypes & ")(.*" & $g_MatchVLC_Win_Name & ")]" ; "[REGEXPCLASS:(?i)(.*VLC video.*)" ;
Global $g_MatchVLC_Win_Fb = "[REGEXPTITLE:(?i)(.*" & $g_MatchVLC_Win_Name & ")]" ;Fallback Matching
Global $g_MatchVLC_Win_Fb_TEXT = "VLC (Direct3D output)"

Opt("SendKeyDelay", 10)
Opt("SendKeyDownDelay", 50)
Global $g_KeystoSend = "#+{left}f" ;(#Win)(+SHIFT){left}f

If _IsCompiled() Then ;Skip for now
    Local $Path = @ScriptDir & "\Vlc_Orig.exe"
    Local $Switches = $CmdLineRaw

    ; Run
    Run(Chr(34) & $Path & Chr(34) & " " & $Switches, @ScriptDir)
EndIf

ConsoleWrite("Begin" & @CRLF)

ActivateVLC_Win()
Send($g_KeystoSend)

Sleep(1000)

ConsoleWrite("End" & @CRLF)


Func _IsCompiled() ;wakillon
    Return @Compiled
EndFunc

Func ActivateVLC_Win()
    Do
        WinActivate($g_MatchVLC_Win, "")
        WinWaitActive($g_MatchVLC_Win, "", 5) ; Wait for active window for number of seconds
        $bIsAct = WinActive($g_MatchVLC_Win)

        If Not $bIsAct Then ;Fallback
            WinActivate($g_MatchVLC_Win_Fb, $g_MatchVLC_Win_Fb_TEXT)
            WinWaitActive($g_MatchVLC_Win_Fb, $g_MatchVLC_Win_Fb_TEXT, 5)
            $bIsAct = WinActive($g_MatchVLC_Win_Fb, $g_MatchVLC_Win_Fb_TEXT)
        EndIf
        ConsoleWrite("VLC is " & ($bIsAct ? "" : "not ") & "active" & @CRLF)
    Until ($bIsAct)
EndFunc

Func Build_File_Types($aExtensions)
    Local $sRet = ""
    For $i = 0 To UBound($aExtensions) - 1
        $sRet &= ".*\." & $aExtensions[$i] & "|"
    Next
    $sRet = StringTrimRight($sRet, 1) ;Remove the trailing '|'
    ConsoleWrite("FileTypes: " & $sRet & @CRLF)
    Return $sRet
EndFunc

I first did just file extension matching but I noticed it wasn't always working with really long file names

since they get cut off so I also implemented a fallback mechanism it looks for 'VLC (Direct3D output)'

as the window text your video output text might be different...

Edited by Bilgus
  • Like 1

Share this post


Link to post
Share on other sites
Bilgus

As for intercepting the command line you could capture the file names there and decide to move based on that info.. etc.

  • Like 1

Share this post


Link to post
Share on other sites
VlcUser

Bilgus:

wow! i had absolutely no idea that sending 6 keystrokes would get so involved!  PM sent to you.

Share this post


Link to post
Share on other sites
Bilgus
Posted (edited)

VlcUser here is what I made the script into for my needs.

You will probably need to change a few things for your use case

Spoiler
#Region ;**** Directives created by AutoIt3Wrapper_GUI ****
#AutoIt3Wrapper_Outfile=VLC_86.exe
#AutoIt3Wrapper_Outfile_x64=VLC_64.exe
#AutoIt3Wrapper_AU3Check_Parameters=-q -d -w 1 -w 2 -w 3 -w 4 -w 5 -w 6 -w 7
#EndRegion ;**** Directives created by AutoIt3Wrapper_GUI ****

#include <StringConstants.au3>
#include <Array.au3>
#include <Misc.au3>

Global $gsINI_PATH = @AppDataDir & "\" & @ScriptName & "_PassThrough.ini" ;Needs to be in @AppDataDir to have write access

If FileExists(@ScriptDir & "\" & @ScriptName & "_PassThrough.ini") Then
    $gsINI_PATH = @ScriptDir & "\" & @ScriptName & "_PassThrough.ini"
EndIf ;Override with ini file in script directory, not writeable though

Global Const $gsCFG = "Config"
Global Const $giACTWAIT = 5 ;wait #seconds for window to become active

Global Enum $geCfg_Close = 0, $geCfg_Max, $geCfg_Sz, $geCfg_Delay, $geCfg_DnDelay, $geCfg_Exec, _
        $geCfg_ActCd, $geCfg_InACd, $geCfg_KeysAct, $geCfg_KeysInA, $geCfg_FileT, $geCfg_WName, $geCfg_WTxt
Global Const $gaSettings = ["CloseOnInactive", "MaximizeOnActivate", "ExitOnFilesLessThanMB", "KeyDelayMS", _
        "KeyDownDelayMS", "Exec_Name", "ActiveWindowCoords", "InactiveWindowCoords", _
        "KeysOnActivate", "KeysOnInactive", "FileTypes", "WindowName", "WindowText_Fallback"]

Global $g_bClose = (IniRead($gsINI_PATH, $gsCFG, $gaSettings[$geCfg_Close], 0) = 0 ? False : True)
Global $g_bMaxonAct = (IniRead($gsINI_PATH, $gsCFG, $gaSettings[$geCfg_Max], 0) = 0 ? False : True)

Global $g_iMinSz = IniRead($gsINI_PATH, $gsCFG, $gaSettings[$geCfg_Sz], "0") ;Mb
Global $g_iKeyDelay = IniRead($gsINI_PATH, $gsCFG, $gaSettings[$geCfg_Delay], 100)
Global $g_iKeyDnDelay = IniRead($gsINI_PATH, $gsCFG, $gaSettings[$geCfg_DnDelay], 50)

Global $g_sExec = IniRead($gsINI_PATH, $gsCFG, $gaSettings[$geCfg_Exec], StringTrimRight(@ScriptName, 4) & "_Orig.exe")

Global $g_sWinPosAct = IniRead($gsINI_PATH, $gsCFG, $gaSettings[$geCfg_ActCd], "0")
Global $g_sWinPosInact = IniRead($gsINI_PATH, $gsCFG, $gaSettings[$geCfg_InACd], "0") ;Mb

Global $g_sKeysSend_Act = IniRead($gsINI_PATH, $gsCFG, $gaSettings[$geCfg_KeysAct], "f") ;(#Win)(+Shift)(arrow)(f)ull screen
Global $g_sKeysSend_Inact = IniRead($gsINI_PATH, $gsCFG, $gaSettings[$geCfg_KeysInA], "")

Global $g_sFileTypes = IniRead($gsINI_PATH, $gsCFG, $gaSettings[$geCfg_FileT], "mp4,avi,mkv,wmv") ;What files should be intercepted?
Global $g_sMatchWin_Name = IniRead($gsINI_PATH, $gsCFG, $gaSettings[$geCfg_WName], "VLC media player")
Global $g_sMatchWin_FbTxt = IniRead($gsINI_PATH, $gsCFG, $gaSettings[$geCfg_WTxt], "VLC (Direct3D output)")

;------------------------------------------------------------------------------------
Global $gsFileTypesMatch = BuildFileTypes($g_sFileTypes)
Global $gsMatchVLC_Win = "[REGEXPTITLE:(?i)(" & $gsFileTypesMatch & ")(.*" & $g_sMatchWin_Name & ")]"
Global $gsMatchVLC_Win_Fb = "[REGEXPTITLE:(?i)(.*" & $g_sMatchWin_Name & ")]" ;Fallback Matching
Global $gaWinPosAct = GetRectFromString($g_sWinPosAct)
Global $gaWinPosInact = GetRectFromString($g_sWinPosInact)

Global $gPID = 0
Global $gPosInit
;------------------------------------------------------------------------------------
If Not FileExists($gsINI_PATH) Then
    Settings_Save()
    MsgBox(0, "Pass Through First Run", "Settings stored in:" & @CRLF & $gsINI_PATH)
EndIf

OnAutoItExitRegister("_Exit")

Opt("SendKeyDelay", $g_iKeyDelay)
Opt("SendKeyDownDelay", $g_iKeyDnDelay)

;Main--------------------------------------------------------------------------------------
RunPassThrough()

Global $ghVlc, $gsTitle
Do
    $ghVlc = WaitActiveVLC_Win($gaWinPosAct, $g_sKeysSend_Act)
    $gsTitle = WinGetTitle($ghVlc)
Until (WaitNotExists_Win($ghVlc, $gsTitle, $gaWinPosInact, $g_sKeysSend_Inact) Or $g_bClose)

If $g_bClose And WinExists($ghVlc) Then WinClose($ghVlc)
_Exit()
;------------------------------------------------------------------------------------------

Func _Exit()
    ;sets hotkeys and saves settings
    OnAutoItExitUnRegister("_Exit")
    ;HotKeySet ("key" , Settings())
    HotKeySet("{F1}", _Help)
    HotKeySet("{ESC}", _Exit_Now)
    ToolTip("Pass Through F1 - Help, ESC - Quit without saving", 0, 0)
    Sleep(5000)
    ToolTip("", 0, 0)
    ;HotKeySet ("key")
    HotKeySet("{F1}")
    HotKeySet("{ESC}")

    Settings_Save()
    Exit
EndFunc   ;==>_Exit

Func _Exit_Now()
    OnAutoItExitUnRegister("_Exit")
    Exit
EndFunc   ;==>_Exit_Now

Func _Help()
    MsgBox(0, "Pass Through", "Settings stored in:" & @CRLF & $gsINI_PATH & _
            @CRLF & @CRLF & _
            "Invoked: " & @ScriptDir & "\" & $g_sExec & " " & $CmdLineRaw & _
            @CRLF & "FileTypes: " & $gsFileTypesMatch & @CRLF)
EndFunc   ;==>_Help

Func _IsCompiled() ;wakillon
    Return @Compiled
EndFunc   ;==>_IsCompiled

Func BuildFileTypes($sExtensions)
    ;Build a regexp string of file extensions from a comma separated one
    ;"txt,exe,com" => ".*\.txt,.*\.exe,.*\.com" ('\' escapes the '.')
    Local $sRet = ""
    $sExtensions = StringStripWS($sExtensions, $STR_STRIPALL)
    If Not StringIsASCII($sExtensions) Then Return ""
    Local $aExt = StringSplit($sExtensions, ",", $STR_ENTIRESPLIT + $STR_NOCOUNT)
    For $i = 0 To UBound($aExt) - 1
        $sRet &= ".*\." & $aExt[$i] & "|"
    Next
    $sRet = StringTrimRight($sRet, 1) ;Remove the trailing '|'
    ;ConsoleWrite("FileTypes: " & $sRet & @CRLF)
    ;MsgBox(0, "FileTypes", $sRet)
    Return $sRet
EndFunc   ;==>BuildFileTypes

Func GetRectFromString($sCoords)
    ;takes rect passed in string 'x, y, w, h' converts to array
    ;Returns [x, y, w, h] if string is valid or 0 if invalid
    ;You should check if return is an array with IsArray()
    $sCoords = StringStripWS($sCoords, $STR_STRIPALL)
    If Not StringIsASCII($sCoords) Then Return ""
    If $sCoords = "0" Or StringLen($sCoords) < 7 Then Return "" ;'0,0,0,0 = 7'
    Local $aRect = StringSplit($sCoords, ",", $STR_ENTIRESPLIT + $STR_NOCOUNT)
    ;_ArrayDisplay($aRect, "Rect From String")
    Return $aRect
EndFunc   ;==>GetRectFromString

Func RunPassThrough()
    ;calls the original file passing through commandline arguments
    If _IsCompiled() Then ;Skip for now
        Local $sPath = @ScriptDir & "\" & $g_sExec
        Local $sSwitches = $CmdLineRaw
        ;MsgBox(0, "Pass Through", $sPath & @CRLF & $sSwitches)

        $gPID = Run(Chr(34) & $sPath & Chr(34) & " " & $sSwitches, "") ; Run

        If $g_iMinSz And $CmdLine[0] > 1 And _ ; less than #Mb Exit script
                FileExists($CmdLine[2]) And _ ; but leave program running
                FileGetSize($CmdLine[2]) < $g_iMinSz * (1024 * 1024) Then
            _Exit_Now()
        EndIf

        If _Singleton(@ScriptName, 1) = 0 Then _Exit_Now() ;single instance of script ONLY
        Sleep(1000) ;Wait a moment for the file to load
    EndIf
EndFunc   ;==>RunPassThrough

Func Settings()
    ;;Maybe do a gui for settings here
    ;$gaWinPosAct = WinGetPos()..
    ;$gaWinPosInact = WinGetPos()..
EndFunc   ;==>Settings

Func Settings_Save()
    If Not _IsCompiled() Then Return
    IniWrite($gsINI_PATH, $gsCFG, $gaSettings[$geCfg_Exec], $g_sExec)
    IniWrite($gsINI_PATH, $gsCFG, $gaSettings[$geCfg_Close], $g_bClose ? 1 : 0)
    IniWrite($gsINI_PATH, $gsCFG, $gaSettings[$geCfg_Max], $g_bMaxonAct ? 1 : 0)
    IniWrite($gsINI_PATH, $gsCFG, $gaSettings[$geCfg_Sz], $g_iMinSz) ;Mb
    IniWrite($gsINI_PATH, $gsCFG, $gaSettings[$geCfg_Delay], $g_iKeyDelay)
    IniWrite($gsINI_PATH, $gsCFG, $gaSettings[$geCfg_DnDelay], $g_iKeyDnDelay)

    IniWrite($gsINI_PATH, $gsCFG, $gaSettings[$geCfg_KeysAct], $g_sKeysSend_Act)
    IniWrite($gsINI_PATH, $gsCFG, $gaSettings[$geCfg_KeysInA], $g_sKeysSend_Inact)
    IniWrite($gsINI_PATH, $gsCFG, $gaSettings[$geCfg_FileT], $g_sFileTypes)
    IniWrite($gsINI_PATH, $gsCFG, $gaSettings[$geCfg_WName], $g_sMatchWin_Name)
    IniWrite($gsINI_PATH, $gsCFG, $gaSettings[$geCfg_WTxt], $g_sMatchWin_FbTxt)

    IniWrite($gsINI_PATH, $gsCFG, $gaSettings[$geCfg_InACd], IsArray($gaWinPosInact) ? _ArrayToString($gaWinPosInact, ",") : 0)
    IniWrite($gsINI_PATH, $gsCFG, $gaSettings[$geCfg_ActCd], IsArray($gaWinPosAct) ? _ArrayToString($gaWinPosAct, ",") : 0)
EndFunc   ;==>Settings_Save

Func WaitActiveVLC_Win($aRect, $sKeys)
    ; Loops waiting for a trigger from vlc window either filename(s)
    ; in the title or window name and text
    ; if PID is defined and doesn't exist closes script
    ; Returns window handle
    Local $hWin = 0
    Local $bIsAct
    Do
        WinActivate($gsMatchVLC_Win, "")
        $hWin = WinWaitActive($gsMatchVLC_Win, "", $giACTWAIT) ; Wait for active window for number of seconds
        $bIsAct = ($hWin = 0 ? False : True)

        If Not $bIsAct Then ;Fallback
            WinActivate($gsMatchVLC_Win_Fb, $g_sMatchWin_FbTxt)
            $hWin = WinWaitActive($gsMatchVLC_Win_Fb, $g_sMatchWin_FbTxt, $giACTWAIT)

            $bIsAct = ($hWin = 0 ? False : True)
            If $bIsAct Then ExitLoop
            If $gPID And Not ProcessExists($gPID) And Not WinExists($gsMatchVLC_Win) Then _Exit()
            Sleep(1000)
        EndIf

        ;ConsoleWrite("VLC is " & ($bIsAct ? "" : "not ") & "active" & @CRLF)
    Until ($bIsAct)

    WinMoveArray($hWin, $aRect)

    If $sKeys <> "" Then ControlSend($hWin, "", 0, $sKeys) ;Send($sKeys)
    Sleep(100)

    If $g_bMaxonAct Then
        WinSetState($hWin, "", @SW_MAXIMIZE)
    EndIf

    Return $hWin
EndFunc   ;==>WaitActiveVLC_Win

Func WaitNotExists_Win($hWin, $sTitle, $aRect, $sKeys)
    ;Returns False if Title Does Not exist but $hWin DOES exist
    ;Returns True if $hWin + $title DOES NOT exist
    WinWaitClose($sTitle)

    If WinExists($hWin) Then
        If $sKeys <> "" Then ControlSend($hWin, "", 0, $sKeys) ;Send($sKeys)
        Sleep(100)
        If $g_bMaxonAct Then WinSetState($hWin, "", @SW_RESTORE)

        WinMoveArray($hWin, $aRect)
        ;ConsoleWrite("Inactive" & @CRLF)
        Return False
    EndIf
    Return True
EndFunc   ;==>WaitNotExists_Win

Func WinMoveArray($hWin, $aC)
    ;Moves $hWin to coords specified by array
    If IsArray($aC) And UBound($aC) == 4 Then
        ;_ArrayDisplay($aC, "Win Move")
        WinMove($hWin, "", $aC[0], $aC[1], $aC[2], $aC[3])
    EndIf
EndFunc   ;==>WinMoveArray

 

After Compiling:

If you want to use it as a pass through you'll need to name the script Vlc.exe and the original vlc.exe to Vlc_Orig.exe.

On first run it will create a settings.ini with default settings and msgbox the location

you can then change the settings but you will have to stop the script and re-run for them to take effect

Running VLC.exe again only runs the script passes on the new commandline and exits the script

the previous script stays running....

DEFAULTS TO:
[Config]
Exec_Name=VLC_Orig.exe
CloseOnInactive=0
MaximizeOnActivate=0
ExitOnFilesLessThanMB=0
KeyDelayMS=100
KeyDownDelayMS=50
KeysOnActivate=f
KeysOnInactive=
FileTypes=mp4,avi,mkv,wmv
WindowName=VLC media player
WindowText_Fallback=VLC (Direct3D output)
InactiveWindowCoords=0
ActiveWindowCoords=0
;------------------------------------------------
[Config]
Exec_Name=VLC_Orig.exe
CloseOnInactive=0 ;1 - Closes the vlc_orig.exe when the video ends
MaximizeOnActivate=0 ;1 - Maximizes window when video is detected
ExitOnFilesLessThanMB=0 ;0-1000x?? - on first run if file is less than this the script is ended but vlc continues
KeyDelayMS=100
KeyDownDelayMS=50
KeysOnActivate=f ;-keys to press when video is detected what you originally wanted would be #+{left}f
KeysOnInactive= ;-keys to press when video stops you wanted #+{right}
FileTypes=mp4,avi,mkv,wmv ;-Comma separated list of valid video files
WindowName=VLC media player ;
WindowText_Fallback=VLC (Direct3D output) ;if valid ext not found fallback to looking for windowname and this text
InactiveWindowCoords=0 ;- moves window to this position on video stop 0 ignores or format 0,0,1000,1000 => x,y,w,h
ActiveWindowCoords=0 ;- moves window to this position on video stop 0 ignores or format 0,0,1000,1000 => x,y,w,h

 

If you don't want to use it as a pass through you'll probably need to change it a bit to do what you want

 

Edited by Bilgus
Old Code

Share this post


Link to post
Share on other sites
Bilgus
Posted (edited)

Ok so Small update: I Set the script up to register a window message when run as a pass through

that way when you load a new file it passes a message back to the "Parent" script

so it knows ahed of time that a video file has been passed and in this case it won't

bounce the screen back to the inactive position only to bounce it back to the active position with the new file

Spoiler
;Bilgus 2018
#Region ;**** Directives created by AutoIt3Wrapper_GUI ****
#AutoIt3Wrapper_Outfile=VLC_86.exe
#AutoIt3Wrapper_Outfile_x64=VLC_64.exe
#AutoIt3Wrapper_AU3Check_Parameters=-q -d -w 1 -w 2 -w 3 -w 4 -w 5 -w 6 -w 7
#EndRegion ;**** Directives created by AutoIt3Wrapper_GUI ****

#include <StringConstants.au3>
#include <Misc.au3>

Global $gsINI_PATH = @AppDataDir & "\" & @ScriptName & "_PassThrough.ini" ;Needs to be in @AppDataDir to have write access

If FileExists(@ScriptDir & "\" & @ScriptName & "_PassThrough.ini") Then
    $gsINI_PATH = @ScriptDir & "\" & @ScriptName & "_PassThrough.ini"
EndIf ;Override with ini file in script directory, not writeable though

Global Const $gsCFG = "Config"
Global Const $giACTWAIT = 5 ;wait #seconds for window to become active

Global Enum $geCfg_Close = 0, $geCfg_Max, $geCfg_Sz, $geCfg_Delay, $geCfg_DnDelay, $geCfg_Exec, _
        $geCfg_ActCd, $geCfg_InACd, $geCfg_KeysAct, $geCfg_KeysInA, $geCfg_FileT, $geCfg_WName, _
        $geCfg_WTxt

Global Const $gaSettings = ["CloseOnInactive", "MaximizeOnActivate", "ExitOnFilesLessThanMB", "KeyDelayMS", _
        "KeyDownDelayMS", "Exec_Name", "ActiveWindowCoords", "InactiveWindowCoords", _
        "KeysOnActivate", "KeysOnInactive", "FileTypes", "WindowName", "WindowText_Fallback"]

Global $g_bClose = (IniRead($gsINI_PATH, $gsCFG, $gaSettings[$geCfg_Close], 0) = 0 ? False : True)
Global $g_bMaxonAct = (IniRead($gsINI_PATH, $gsCFG, $gaSettings[$geCfg_Max], 0) = 0 ? False : True)

Global $g_iMinSz = IniRead($gsINI_PATH, $gsCFG, $gaSettings[$geCfg_Sz], "0") ;Mb
Global $g_iKeyDelay = IniRead($gsINI_PATH, $gsCFG, $gaSettings[$geCfg_Delay], 100)
Global $g_iKeyDnDelay = IniRead($gsINI_PATH, $gsCFG, $gaSettings[$geCfg_DnDelay], 50)

Global $g_sExec = IniRead($gsINI_PATH, $gsCFG, $gaSettings[$geCfg_Exec], StringTrimRight(@ScriptName, 4) & "_Orig.exe")

Global $g_sWinPosAct = IniRead($gsINI_PATH, $gsCFG, $gaSettings[$geCfg_ActCd], "0")
Global $g_sWinPosInact = IniRead($gsINI_PATH, $gsCFG, $gaSettings[$geCfg_InACd], "0") ;Mb

Global $g_sKeysSend_Act = IniRead($gsINI_PATH, $gsCFG, $gaSettings[$geCfg_KeysAct], "f") ;(#Win)(+Shift)(arrow)(f)ull screen
Global $g_sKeysSend_Inact = IniRead($gsINI_PATH, $gsCFG, $gaSettings[$geCfg_KeysInA], "")

Global $g_sFileTypes = IniRead($gsINI_PATH, $gsCFG, $gaSettings[$geCfg_FileT], "mp4,avi,mkv,wmv") ;What files should be intercepted?
Global $g_sMatchWin_Name = IniRead($gsINI_PATH, $gsCFG, $gaSettings[$geCfg_WName], "VLC media player")
Global $g_sMatchWin_FbTxt = IniRead($gsINI_PATH, $gsCFG, $gaSettings[$geCfg_WTxt], "VLC (Direct3D output)")

;------------------------------------------------------------------------------------
Global $gsFileTypesMatch = BuildFileTypes($g_sFileTypes)
Global $gsMatchVLC_Win = "[REGEXPTITLE:(?i)(" & $gsFileTypesMatch & ")(.*" & $g_sMatchWin_Name & ")]"
Global $gsMatchVLC_Win_Fb = "[REGEXPTITLE:(?i)(.*" & $g_sMatchWin_Name & ")]" ;Fallback Matching
Global $gaWinPosAct = GetRectFromString($g_sWinPosAct)
Global $gaWinPosInact = GetRectFromString($g_sWinPosInact)

Global $gPID = 0
Global $gPosInit

Global Const $_HWND_BROADCAST = 0xFFFF
Global $gbActivated = False
Global $giActMsg = 0
Global $gsErr = ""
Global $ghVlc

;Main--------------------------------------------------------------------------------------
If Not FileExists($gsINI_PATH) Then
    Settings_Save()
    MsgBox(0, "Pass Through First Run", "Settings stored in:" & @CRLF & $gsINI_PATH)
EndIf

Opt("SendKeyDelay", $g_iKeyDelay)
Opt("SendKeyDownDelay", $g_iKeyDnDelay)


If _IsCompiled() Then
    $giActMsg = _Create_Message("@ScriptFullPath" & "_msg")
    RunPassThrough()
    _Create_MessageHandler($giActMsg, "Activated_Ext")
EndIf

OnAutoItExitRegister("_Exit")

Do
    $ghVlc = WaitActiveVLC_Win($gaWinPosAct, $g_sKeysSend_Act)
Until (WaitNotExists_Win($ghVlc, $gaWinPosInact, $g_sKeysSend_Inact) Or $g_bClose)

If $g_bClose And WinExists($ghVlc) Then WinClose($ghVlc)
Exit
;^Main^------------------------------------------------------------------------------------

Func _Create_Message($sMessage)
    Local $iMsg = WinAPI_RegisterWindowMessage($sMessage)
    If $iMsg = 0 Then $gsErr &= "IPC Message Creation Failure " & $sMessage & @CRLF
    Return $iMsg
EndFunc   ;==>_Create_Message

Func _Create_MessageHandler($iMsg, $sFunction)
    If $iMsg <> 0 Then
        Opt("GUIOnEventMode", 1)
        GUICreate(@ScriptName & "_IPC", 0, 0, 0, 0, 0, 0) ; create a top level window
        GUIRegisterMsg($iMsg, $sFunction)
    EndIf
EndFunc   ;==>_Create_MessageHandler

Func _Exit()
    ;sets hotkeys and saves settings

    ;HotKeySet ("key" , Settings())
    HotKeySet("{F1}", _Help)
    HotKeySet("{ESC}", _Exit_Now)
    ToolTip("Pass Through F1 - Help, ESC - Quit without saving", 0, 0)
    Sleep(5000)
    ToolTip("", 0, 0)
    ;HotKeySet ("key")
    HotKeySet("{F1}")
    HotKeySet("{ESC}")

    Settings_Save()

    Exit
EndFunc   ;==>_Exit

Func _Exit_Now()
    OnAutoItExitUnRegister("_Exit")
    Exit
EndFunc   ;==>_Exit_Now

Func _Help()
    MsgBox(0, "Pass Through", "Settings stored in:" & @CRLF & $gsINI_PATH & _
            @CRLF & @CRLF & _
            "Invoked: " & @ScriptDir & "\" & $g_sExec & " " & $CmdLineRaw & _
            @CRLF & "FileTypes: " & $gsFileTypesMatch & @CRLF & _
            "Errors:" & $gsErr & @CRLF)
EndFunc   ;==>_Help

Func _IsCompiled() ;wakillon
    Return True ;@Compiled
EndFunc   ;==>_IsCompiled
;------------------------------------------------------------------------------------------
Func Activated_Ext()
    $gbActivated = True
EndFunc   ;==>Activated_Ext

Func ArrayToStr($aArray)
    Local $sRet = ""
    If Not IsArray($aArray) Then Return SetError(1, 0, 0)
    For $i = 0 To UBound($aArray) - 1
        $sRet &= $aArray[$i] & ","
    Next
    $sRet = StringTrimRight($sRet, 1) ;Remove the trailing ','
    Return $sRet
EndFunc   ;==>ArrayToStr

Func BuildFileTypes($sExtensions)
    ;Build a regexp string of file extensions from a comma separated one
    ;"txt,exe,com" => ".*\.txt,.*\.exe,.*\.com" ('\' escapes the '.')
    Local $sRet = ""
    $sExtensions = StringStripWS($sExtensions, $STR_STRIPALL)
    If Not StringIsASCII($sExtensions) Then Return ""
    Local $aExt = StringSplit($sExtensions, ",", $STR_ENTIRESPLIT + $STR_NOCOUNT)
    For $i = 0 To UBound($aExt) - 1
        $sRet &= ".*\." & $aExt[$i] & "|"
    Next
    $sRet = StringTrimRight($sRet, 1) ;Remove the trailing '|'
    Return $sRet
EndFunc   ;==>BuildFileTypes

Func GetRectFromString($sCoords)
    ;takes rect passed in string 'x, y, w, h' converts to array
    ;Returns [x, y, w, h] if string is valid or 0 if invalid
    ;You should check if return is an array with IsArray()
    $sCoords = StringStripWS($sCoords, $STR_STRIPALL)
    If Not StringIsASCII($sCoords) Then Return ""
    If $sCoords = "0" Or StringLen($sCoords) < 7 Then Return "" ;'0,0,0,0 = 7'
    Local $aRect = StringSplit($sCoords, ",", $STR_ENTIRESPLIT + $STR_NOCOUNT)
    ;_ArrayDisplay($aRect, "Rect From String")
    Return $aRect
EndFunc   ;==>GetRectFromString

Func RunPassThrough()
    ;calls the original file passing through commandline arguments
    Local $sPath = @ScriptDir & "\" & $g_sExec
    Local $sSwitches = $CmdLineRaw
    ;MsgBox(0, "Pass Through", $sPath & @CRLF & $sSwitches)

    $gPID = Run(Chr(34) & $sPath & Chr(34) & " " & $sSwitches, "") ; Run

    If $g_iMinSz And $CmdLine[0] > 1 And _ ; less than #Mb Exit script
            FileExists($CmdLine[2]) And _ ; but leave program running
            FileGetSize($CmdLine[2]) < $g_iMinSz * (1024 * 1024) Then
        _Exit_Now()
    EndIf

    If _Singleton(@ScriptName, 1) = 0 Then
        If $CmdLine[0] > 1 And $giActMsg <> 0 And FileExists($CmdLine[2]) Then
            If StringRegExp($CmdLine[2], $gsFileTypesMatch) Then
                WinAPI_PostMessage($_HWND_BROADCAST, $giActMsg, 0, 0)
            EndIf
        EndIf
        _Exit_Now() ;single instance of script ONLY
    EndIf
    Sleep(1000) ;Wait a moment for the file to load
EndFunc   ;==>RunPassThrough

Func Settings()
    ;;Maybe do a gui for settings here
    ;$gaWinPosAct = WinGetPos()..
    ;$gaWinPosInact = WinGetPos()..
EndFunc   ;==>Settings

Func Settings_Save()
    If Not _IsCompiled() Then Return
    IniWrite($gsINI_PATH, $gsCFG, $gaSettings[$geCfg_Exec], $g_sExec)
    IniWrite($gsINI_PATH, $gsCFG, $gaSettings[$geCfg_Close], $g_bClose ? 1 : 0)
    IniWrite($gsINI_PATH, $gsCFG, $gaSettings[$geCfg_Max], $g_bMaxonAct ? 1 : 0)
    IniWrite($gsINI_PATH, $gsCFG, $gaSettings[$geCfg_Sz], $g_iMinSz) ;Mb
    IniWrite($gsINI_PATH, $gsCFG, $gaSettings[$geCfg_Delay], $g_iKeyDelay)
    IniWrite($gsINI_PATH, $gsCFG, $gaSettings[$geCfg_DnDelay], $g_iKeyDnDelay)

    IniWrite($gsINI_PATH, $gsCFG, $gaSettings[$geCfg_KeysAct], $g_sKeysSend_Act)
    IniWrite($gsINI_PATH, $gsCFG, $gaSettings[$geCfg_KeysInA], $g_sKeysSend_Inact)
    IniWrite($gsINI_PATH, $gsCFG, $gaSettings[$geCfg_FileT], $g_sFileTypes)
    IniWrite($gsINI_PATH, $gsCFG, $gaSettings[$geCfg_WName], $g_sMatchWin_Name)
    IniWrite($gsINI_PATH, $gsCFG, $gaSettings[$geCfg_WTxt], $g_sMatchWin_FbTxt)

    IniWrite($gsINI_PATH, $gsCFG, $gaSettings[$geCfg_InACd], ArrayToStr($gaWinPosInact))
    IniWrite($gsINI_PATH, $gsCFG, $gaSettings[$geCfg_ActCd], ArrayToStr($gaWinPosAct))
EndFunc   ;==>Settings_Save

Func WinAPI_PostMessage($hWnd, $iMsg, $wParam, $lParam)
    Local $aResult = DllCall("user32.dll", "bool", "PostMessage", "hwnd", $hWnd, "uint", $iMsg, "wparam", $wParam, "lparam", $lParam)
    If @error Then Return SetError(@error, @extended, False)
    Return $aResult[0]
EndFunc   ;==>WinAPI_PostMessage

Func WinAPI_RegisterWindowMessage($sMessage)
    Local $aResult = DllCall("user32.dll", "uint", "RegisterWindowMessageW", "wstr", $sMessage)
    If @error Then Return SetError(@error, @extended, 0)
    Return $aResult[0]
EndFunc   ;==>WinAPI_RegisterWindowMessage

Func WaitActiveVLC_Win($aRect, $sKeys)
    ; Loops waiting for a trigger from vlc window either filename(s)
    ; in the title or window name and text
    ; if PID is defined and doesn't exist closes script
    ; Returns window handle
    Local $hWin = 0
    Local $bIsAct
    Do
        WinActivate($gsMatchVLC_Win, "")
        $hWin = WinWaitActive($gsMatchVLC_Win, "", $giACTWAIT) ; Wait for active window for number of seconds
        $bIsAct = ($hWin = 0 ? False : True)

        If Not $bIsAct Then ;Fallback
            WinActivate($gsMatchVLC_Win_Fb, $g_sMatchWin_FbTxt)
            $hWin = WinWaitActive($gsMatchVLC_Win_Fb, $g_sMatchWin_FbTxt, $giACTWAIT)

            $bIsAct = ($hWin = 0 ? False : True)
            If $bIsAct Then ExitLoop
            If $gPID And Not ProcessExists($gPID) And Not WinExists($gsMatchVLC_Win) Then Exit
            Sleep(1000)
        EndIf

        ;ConsoleWrite("VLC is " & ($bIsAct ? "" : "not ") & "active" & @CRLF)
    Until ($bIsAct)

    WinMoveArray($hWin, $aRect)

    If $sKeys <> "" Then ControlSend($hWin, "", 0, $sKeys) ;Send($sKeys)
    Sleep(100)

    If $g_bMaxonAct Then
        WinSetState($hWin, "", @SW_MAXIMIZE)
    EndIf

    Return $hWin
EndFunc   ;==>WaitActiveVLC_Win

Func WaitNotExists_Win($hWin, $aRect, $sKeys)
    ;Returns False if Title Does Not exist but $hWin DOES exist
    ;Returns True if $hWin + $title DOES NOT exist
    Do
        $gbActivated = False
        WinWaitClose(WinGetTitle($ghVlc))
    Until (Not $gbActivated)

    If WinExists($hWin) Then
        If $sKeys <> "" Then ControlSend($hWin, "", 0, $sKeys) ;Send($sKeys)
        Sleep(100)
        If $g_bMaxonAct Then WinSetState($hWin, "", @SW_RESTORE)

        WinMoveArray($hWin, $aRect)
        Return False
    EndIf
    Return True
EndFunc   ;==>WaitNotExists_Win

Func WinMoveArray($hWin, $aC)
    ;Moves $hWin to coords specified by array
    If IsArray($aC) And UBound($aC) == 4 Then
        ;_ArrayDisplay($aC, "Win Move")
        WinMove($hWin, "", $aC[0], $aC[1], $aC[2], $aC[3])
    EndIf
EndFunc   ;==>WinMoveArray

 

 

Edited by Bilgus
Old code

Share this post


Link to post
Share on other sites
VlcUser

Hi, Bilgus

i have been studying and playing with your script since you posted it a few hours ago, and first i have to say WOW and THANK YOU.

when i play an mp3, it plays normally, and the VLC window stays on the laptop...perfect!

when i play an mp3, VLC immediately displays and plays it in full screen, and when it finishes, VLC returns to normal...perfect!

the mp4 does not go to the alternate (extended) display, it plays on the laptop. Upon examining your script line by line and playing with it, i edited as follows:

i exited the script, and deleted the .ini file it created, then edited the line in your script:

Global $g_sKeysSend_Act = IniRead($gsINI_PATH, $gsCFG, $gaSettings[$geCfg_KeysAct], "f") ;(#Win)(+Shift)(arrow)(f)ull screen

to read

Global $g_sKeysSend_Act = IniRead($gsINI_PATH, $gsCFG, $gaSettings[$geCfg_KeysAct], "#+{left}f") ;(#Win)(+Shift)(arrow)(f)ull screen

so that it would send the key combination to make the active window jump to the alternate video.

Then i ran the script, and played an mp3...all perfect once again.

I played an mp4 file, and there was no change, the mp4 still played in fullscreen on the laptop. i checked the .ini file and it had indeed stored "#+{left}f":

[Config]
Exec_Name=bilgus_Orig.exe
CloseOnInactive=0
MaximizeOnActivate=0
ExitOnFilesLessThanMB=0
KeyDelayMS=100
KeyDownDelayMS=50
KeysOnActivate=#+{left}f
KeysOnInactive=
FileTypes=mp4,avi,mkv,wmv
WindowName=VLC media player
WindowText_Fallback=VLC (Direct3D output)
InactiveWindowCoords=0
ActiveWindowCoords=0

in desperation, i thought i'd try the "damn the torpedoes, full speed ahead" tactic, and so i also edited this line (in two places where i found it):

If $sKeys <> "" Then ControlSend($hWin, "", 0, $sKeys) ;Send($sKeys)

to this

If $sKeys <> "" Then ControlSend($hWin, "", 0, "#+{left}f") ;Send("#+{left}f")

but that failed miserably. i am in over my head, fer sure!

any suggestions? thank you so much, and i sent you another PM

Share this post


Link to post
Share on other sites
Bilgus

I made it so you can edit the entries in the .ini file to do this rather than editing the script that probably why you are having the issue

if you missed the part about creating an ini file at first run when you close your vlc window it should show a short message about press F1 for help Esc..

Press F1 and make not of the directory it placed the ini in

go there and open the ini look for the line KeysOnInactive= and set that to the opposite of what you set

KeysOnActivate=#+{left}f to without the f

so KeysOnInactive=#+{right}

OR

you can just set the coordinates directly

InactiveWindowCoords=0, 0, 500, 300

and the active one you'll probably have to play with as I'm not sure where exactly its coordinates would be but try

ActiveWindowCoords=-10000, 0, 5000, 3000

or

ActiveWindowCoords=10000, 0, 5000, 3000

or hey if that part works right just leave this one at 0

KeysOnActivate=#+{left}f

InactiveWindowCoords=0, 0, 500, 300

ActiveWindowCoords=0

Share this post


Link to post
Share on other sites
Bilgus

Just so we are clear FileTypes are the files that ACTIVATE it

all other files are INACTIVE mp3, wav, wma.....jpg?

so mp4,avi,mkv,wmv all call the ACTIVE functions

Here is my ini file for instance

[Config]
Exec_Name=VLC_Orig.exe
CloseOnInactive=0
ExitOnFilesLessThanMB=0
KeyDelayMS=100
KeyDownDelayMS=50
KeysOnActivate=f
KeysOnInactive=
FileTypes=mp4,avi,mkv,wmv
WindowName=VLC media player
WindowText_Fallback=VLC (Direct3D output)
InactiveWindowCoords=0,0,700,500
ActiveWindowCoords=10000,0,5000,5000
MaximizeOnActivate=1

my extended screen is off to the right...

Share this post


Link to post
Share on other sites
VlcUser

k, will try this asap, especially with the co-ords...my extended is off to the right as well...

 

did you get my PM?

 

Share this post


Link to post
Share on other sites
VlcUser
Posted (edited)

Bilgus, YOU ROCK! i put in the co-ords you suggested, then played around with the inactivewindow coords (using AU3Info) and it works perfectly!!!!

Everybody clap for Bilgus!!!!:D

Edited by VlcUser
hit submit accidentally...duh

Share this post


Link to post
Share on other sites
Bilgus
Posted (edited)

Here is an update with a settings window press F4 at the message on close to pop it up

Spoiler
;Bilgus 2018
#Region ;**** Directives created by AutoIt3Wrapper_GUI ****
;;#AutoIt3Wrapper_Icon=VlcMover.ico
#AutoIt3Wrapper_Outfile=VLC86.exe
#AutoIt3Wrapper_Outfile_x64=VLC64.exe
#AutoIt3Wrapper_AU3Check_Parameters=-q -d -w 1 -w 2 -w 3 -w 4 -w 5 -w 6 -w 7
#EndRegion ;**** Directives created by AutoIt3Wrapper_GUI ****

;GUIConstantsEx
Global $GUI_EVENT_CLOSE = -0x3
Global $GUI_CHECKED = 0x1
Global $GUI_ENABLE = 0x40
Global $GUI_DISABLE = 0x80
;WindowsConstants
Global Const $WS_OVERLAPPEDWINDOW = 0x00CF0000
; StringStripWS Constants
Global Const $STR_STRIPALL = 8 ; Strip all spaces (over-rides all other flags)
; StringSplit Constants
Global Const $STR_ENTIRESPLIT = 1 ; Entire delimiter marks the split
Global Const $STR_NOCOUNT = 2 ; Disable the return count
;Authorization Structures
Global Const $tagSECURITY_ATTRIBUTES = "dword Length;ptr Descriptor;bool InheritHandle"
;
Global $gsINI_PATH = @AppDataDir & "\" & @ScriptName & "_PassThrough.ini" ;Needs to be in @AppDataDir to have write access

If FileExists(@ScriptDir & "\" & @ScriptName & "_PassThrough.ini") Then
    $gsINI_PATH = @ScriptDir & "\" & @ScriptName & "_PassThrough.ini"
EndIf ;Override with ini file in script directory, not writeable though

Global Const $gsCFG = "Config"
Global Const $giACTWAIT = 5 ;wait #seconds for window to become active

Global Enum $geCfg_Close = 0, $geCfg_Max, $geCfg_Sz, $geCfg_Delay, $geCfg_DnDelay, $geCfg_Exec, _
        $geCfg_ActCd, $geCfg_InACd, $geCfg_KeysAct, $geCfg_KeysInA, $geCfg_FileT, $geCfg_WName, _
        $geCfg_WTxt

Global Const $gaSettings = ["CloseOnInactive", "MaximizeOnActivate", "ExitOnFilesLessThanMB", "KeyDelayMS", _
        "KeyDownDelayMS", "Exec_Name", "ActiveWindowCoords", "InactiveWindowCoords", _
        "KeysOnActivate", "KeysOnInactive", "FileTypes", "WindowName", "WindowText_Fallback"]

Global $g_bClose = (IniRead($gsINI_PATH, $gsCFG, $gaSettings[$geCfg_Close], 0) = 0 ? False : True)
Global $g_bMaxonAct = (IniRead($gsINI_PATH, $gsCFG, $gaSettings[$geCfg_Max], 0) = 0 ? False : True)

Global $g_iMinSz = IniRead($gsINI_PATH, $gsCFG, $gaSettings[$geCfg_Sz], "0") ;Mb
Global $g_iKeyDelay = IniRead($gsINI_PATH, $gsCFG, $gaSettings[$geCfg_Delay], 100)
Global $g_iKeyDnDelay = IniRead($gsINI_PATH, $gsCFG, $gaSettings[$geCfg_DnDelay], 50)

Global $g_sExec = IniRead($gsINI_PATH, $gsCFG, $gaSettings[$geCfg_Exec], StringTrimRight(@ScriptName, 4) & "_Orig.exe")

Global $g_sWinPosAct = IniRead($gsINI_PATH, $gsCFG, $gaSettings[$geCfg_ActCd], "0")
Global $g_sWinPosInact = IniRead($gsINI_PATH, $gsCFG, $gaSettings[$geCfg_InACd], "0") ;Mb

Global $g_sKeysSend_Act = IniRead($gsINI_PATH, $gsCFG, $gaSettings[$geCfg_KeysAct], "f") ;(#Win)(+Shift)(arrow)(f)ull screen
Global $g_sKeysSend_Inact = IniRead($gsINI_PATH, $gsCFG, $gaSettings[$geCfg_KeysInA], "")

Global $g_sFileTypes = IniRead($gsINI_PATH, $gsCFG, $gaSettings[$geCfg_FileT], "mp4,avi,mkv,wmv") ;What files should be intercepted?
Global $g_sMatchWin_Name = IniRead($gsINI_PATH, $gsCFG, $gaSettings[$geCfg_WName], "VLC media player")
Global $g_sMatchWin_FbTxt = IniRead($gsINI_PATH, $gsCFG, $gaSettings[$geCfg_WTxt], "VLC (Direct3D output)")

;------------------------------------------------------------------------------------
Global $gsFileTypesMatch = BuildFileTypes($g_sFileTypes)
Global $gsMatchVLC_Win = "[REGEXPTITLE:(?i)(" & $gsFileTypesMatch & ")(.*" & $g_sMatchWin_Name & ")]"
Global $gsMatchVLC_Win_Fb = "[REGEXPTITLE:(?i)(.*" & $g_sMatchWin_Name & ")]" ;Fallback Matching
Global $gaWinPosAct = GetRectFromString($g_sWinPosAct)
Global $gaWinPosInact = GetRectFromString($g_sWinPosInact)

Global $gPID = 0
Global $gPosInit

Global Const $_HWND_BROADCAST = 0xFFFF
Global $gbActivated = False
Global $giActMsg = 0
Global $gsErr = ""
Global $ghVlc

;Main--------------------------------------------------------------------------------------
If Not FileExists($gsINI_PATH) Then
    Settings_Save()
    MsgBox(0, "Pass Through First Run", "Settings stored in:" & @CRLF & $gsINI_PATH)
EndIf

Opt("SendKeyDelay", $g_iKeyDelay)
Opt("SendKeyDownDelay", $g_iKeyDnDelay)


If _IsCompiled() Then
    $giActMsg = _Create_Message("@ScriptFullPath" & "_msg")
    RunPassThrough()
    _Create_MessageHandler($giActMsg, "Activated_Ext")
EndIf

OnAutoItExitRegister("_Exit")

Do
    $ghVlc = WaitActiveVLC_Win($gaWinPosAct, $g_sKeysSend_Act)
Until (WaitNotExists_Win($ghVlc, $gaWinPosInact, $g_sKeysSend_Inact) Or $g_bClose)

If $g_bClose And WinExists($ghVlc) Then WinClose($ghVlc)
Exit
;^Main^------------------------------------------------------------------------------------

Func _Create_Message($sMessage)
    Local $iMsg = WinAPI_RegisterWindowMessage($sMessage)
    If $iMsg = 0 Then $gsErr &= "IPC Message Creation Failure " & $sMessage & @CRLF
    Return $iMsg
EndFunc   ;==>_Create_Message

Func _Create_MessageHandler($iMsg, $sFunction)
    If $iMsg <> 0 Then
        Opt("GUIOnEventMode", 1)
        GUICreate(@ScriptName & "_IPC", 0, 0, 0, 0, 0, 0) ; create a top level window
        GUIRegisterMsg($iMsg, $sFunction)
    EndIf
EndFunc   ;==>_Create_MessageHandler

Func _Exit()
    ;sets hotkeys and saves settings

    HotKeySet("{F4}", Settings)
    HotKeySet("{F1}", _Help)
    HotKeySet("{ESC}", _Exit_Now)
    ToolTip("Pass Through F1 - Help, F4 - Settings, ESC - Quit without saving", 0, 0)
    Sleep(5000)
    ToolTip("", 0, 0)
    HotKeySet("{F4}")
    HotKeySet("{F1}")
    HotKeySet("{ESC}")

    Settings_Save()

    Exit
EndFunc   ;==>_Exit

Func _Exit_Now()
    OnAutoItExitUnRegister("_Exit")
    Exit
EndFunc   ;==>_Exit_Now

Func _Help()
    MsgBox(0, "Pass Through", "Settings stored in:" & @CRLF & $gsINI_PATH & _
            @CRLF & @CRLF & _
            "Invoked: " & @ScriptDir & "\" & $g_sExec & " " & $CmdLineRaw & _
            @CRLF & "FileTypes: " & $gsFileTypesMatch & @CRLF & _
            "Errors:" & $gsErr & @CRLF)
EndFunc   ;==>_Help

Func _IsCompiled() ;wakillon
    Return True ;@Compiled
EndFunc   ;==>_IsCompiled

Func _Singleton($sOccurrenceName, $iFlag = 0) ;Valik
    Local Const $ERROR_ALREADY_EXISTS = 183
    Local Const $SECURITY_DESCRIPTOR_REVISION = 1
    Local $tSecurityAttributes = 0

    If BitAND($iFlag, 2) Then
        ; The size of SECURITY_DESCRIPTOR is 20 bytes.  We just
        ; need a block of memory the right size, we aren't going to
        ; access any members directly so it's not important what
        ; the members are, just that the total size is correct.
        Local $tSecurityDescriptor = DllStructCreate("byte;byte;word;ptr[4]")
        ; Initialize the security descriptor.
        Local $aRet = DllCall("advapi32.dll", "bool", "InitializeSecurityDescriptor", _
                "struct*", $tSecurityDescriptor, "dword", $SECURITY_DESCRIPTOR_REVISION)
        If @error Then Return SetError(@error, @extended, 0)
        If $aRet[0] Then
            ; Add the NULL DACL specifying access to everybody.
            $aRet = DllCall("advapi32.dll", "bool", "SetSecurityDescriptorDacl", _
                    "struct*", $tSecurityDescriptor, "bool", 1, "ptr", 0, "bool", 0)
            If @error Then Return SetError(@error, @extended, 0)
            If $aRet[0] Then
                ; Create a SECURITY_ATTRIBUTES structure.
                $tSecurityAttributes = DllStructCreate($tagSECURITY_ATTRIBUTES)
                ; Assign the members.
                DllStructSetData($tSecurityAttributes, 1, DllStructGetSize($tSecurityAttributes))
                DllStructSetData($tSecurityAttributes, 2, DllStructGetPtr($tSecurityDescriptor))
                DllStructSetData($tSecurityAttributes, 3, 0)
            EndIf
        EndIf
    EndIf

    Local $aHandle = DllCall("kernel32.dll", "handle", "CreateMutexW", "struct*", $tSecurityAttributes, "bool", 1, "wstr", $sOccurrenceName)
    If @error Then Return SetError(@error, @extended, 0)
    Local $aLastError = DllCall("kernel32.dll", "dword", "GetLastError")
    If @error Then Return SetError(@error, @extended, 0)
    If $aLastError[0] = $ERROR_ALREADY_EXISTS Then
        If BitAND($iFlag, 1) Then
            DllCall("kernel32.dll", "bool", "CloseHandle", "handle", $aHandle[0])
            If @error Then Return SetError(@error, @extended, 0)
            Return SetError($aLastError[0], $aLastError[0], 0)
        Else
            Exit -1
        EndIf
    EndIf
    Return $aHandle[0]
EndFunc   ;==>_Singleton
;------------------------------------------------------------------------------------------
Func Activated_Ext()
    $gbActivated = True
EndFunc   ;==>Activated_Ext

Func ArrayToStr($aArray)
    Local $sRet = ""
    If Not IsArray($aArray) Then Return SetError(1, 0, 0)
    For $i = 0 To UBound($aArray) - 1
        $sRet &= $aArray[$i] & ","
    Next
    $sRet = StringTrimRight($sRet, 1) ;Remove the trailing ','
    Return $sRet
EndFunc   ;==>ArrayToStr

Func BuildFileTypes($sExtensions)
    ;Build a regexp string of file extensions from a comma separated one
    ;"txt,exe,com" => ".*\.txt,.*\.exe,.*\.com" ('\' escapes the '.')
    Local $sRet = ""
    $sExtensions = StringStripWS($sExtensions, $STR_STRIPALL)
    If Not StringIsASCII($sExtensions) Then Return ""
    Local $aExt = StringSplit($sExtensions, ",", $STR_ENTIRESPLIT + $STR_NOCOUNT)
    For $i = 0 To UBound($aExt) - 1
        $sRet &= ".*\." & $aExt[$i] & "|"
    Next
    $sRet = StringTrimRight($sRet, 1) ;Remove the trailing '|'
    Return $sRet
EndFunc   ;==>BuildFileTypes

Func GetRectFromString($sCoords)
    ;takes rect passed in string 'x, y, w, h' converts to array
    ;Returns [x, y, w, h] if string is valid or 0 if invalid
    ;You should check if return is an array with IsArray()
    $sCoords = StringStripWS($sCoords, $STR_STRIPALL)
    If Not StringIsASCII($sCoords) Then Return ""
    If $sCoords = "0" Or StringLen($sCoords) < 7 Then Return "" ;'0,0,0,0 = 7'
    Local $aRect = StringSplit($sCoords, ",", $STR_ENTIRESPLIT + $STR_NOCOUNT)
    ;_ArrayDisplay($aRect, "Rect From String")
    Return $aRect
EndFunc   ;==>GetRectFromString

Func RunPassThrough()
    ;calls the original file passing through commandline arguments
    Local $sPath = @ScriptDir & "\" & $g_sExec
    Local $sSwitches = $CmdLineRaw
    ;MsgBox(0, "Pass Through", $sPath & @CRLF & $sSwitches)

    $gPID = Run(Chr(34) & $sPath & Chr(34) & " " & $sSwitches, "") ; Run

    If $g_iMinSz And $CmdLine[0] > 1 And _ ; less than #Mb Exit script
            FileExists($CmdLine[2]) And _ ; but leave program running
            FileGetSize($CmdLine[2]) < $g_iMinSz * (1024 * 1024) Then
        _Exit_Now()
    EndIf

    If _Singleton(@ScriptName, 1) = 0 Then
        If $CmdLine[0] > 1 And $giActMsg <> 0 And FileExists($CmdLine[2]) Then
            If StringRegExp($CmdLine[2], $gsFileTypesMatch) Then
                WinAPI_PostMessage($_HWND_BROADCAST, $giActMsg, 0, 0)
            EndIf
        EndIf
        _Exit_Now() ;single instance of script ONLY
    EndIf
    Sleep(1000) ;Wait a moment for the file to load
EndFunc   ;==>RunPassThrough

Func Settings()
    Opt("GUIOnEventMode", 0)
    Local $iY = 60
    Local $nMsg
    #Region ### START Koda GUI section ###
    Local $hDummy = GUICtrlCreateDummy()
    Local $hForm1_2 = $hDummy ;Used for positioning
    Local $hB_ACORD = $hDummy ;
    Local $hB_ICORD = $hDummy ;
    Local $aPos = 0 ;
    Local $hForm1_1 = GUICreate("Pass Through Settings", 287, 225 + $iY, 192, 124)

    GUICtrlCreateLabel("Execute", 8, 2, 74, 17)
    Local $hI_EXEC = GUICtrlCreateInput($g_sExec, 100, 0, 180, 21)
    GUICtrlCreateLabel("Win Text FB", 8, 30, 74, 17)
    Local $hI_FBT = GUICtrlCreateInput($g_sMatchWin_FbTxt, 100, 27, 180, 21)

    GUICtrlCreateLabel("Activated Settings", 8, 8 + $iY, 130, 17)
    GUICtrlSetFont(-1, 10, 800, 0, "MS Sans Serif")

    GUICtrlCreateLabel("File Extensions", 8, 30 + $iY, 74, 17)
    Local $hI_FEXT = GUICtrlCreateInput($g_sFileTypes, 130, 27 + $iY, 150, 21)

    GUICtrlCreateLabel("Send Keys", 8, 53 + $iY, 55, 17)
    Local $hI_ASK = GUICtrlCreateInput($g_sKeysSend_Act, 130, 49 + $iY, 150, 21)

    GUICtrlCreateLabel("Coordinates (x, y, w, h)", 8, 75 + $iY, 111, 17)
    Local $hI_ACORD = GUICtrlCreateInput(ArrayToStr($gaWinPosAct), 130, 72 + $iY, 150, 21)
    Local $hB_ASTCC = GUICtrlCreateButton("Set With Helper", 130, 96 + $iY, 150, 17)
    Local $hC_AMAXM = GUICtrlCreateCheckbox("Maximize", 8, 96 + $iY, 89, 17)
    GUICtrlSetState($hC_AMAXM, $g_bMaxonAct ? 1 : 4)

    GUICtrlCreateLabel("Inactivated Settings", 8, 127 + $iY, 146, 17)
    GUICtrlSetFont(-1, 10, 800, 0, "MS Sans Serif")

    GUICtrlCreateLabel("Send Keys", 8, 155 + $iY, 55, 17)
    Local $hI_ISK = GUICtrlCreateInput($g_sKeysSend_Inact, 130, 151 + $iY, 150, 21)

    GUICtrlCreateLabel("Coordinates (x, y, w, h)", 8, 178 + $iY, 111, 17)
    Local $hI_ICORD = GUICtrlCreateInput(ArrayToStr($gaWinPosInact), 130, 175 + $iY, 150, 21)
    Local $hB_ISTCC = GUICtrlCreateButton("Set With Helper", 130, 199 + $iY, 150, 17)

    Local $hB_Cancel = GUICtrlCreateButton("Cancel", 8, 200 + $iY, 49, 17)
    Local $hB_Save = GUICtrlCreateButton("Save", 71, 200 + $iY, 49, 17)
    GUISetState(@SW_SHOW, $hForm1_1)
    #EndRegion ### END Koda GUI section ###

    While 1
        $nMsg = GUIGetMsg()
        Switch $nMsg
            Case $hB_Cancel
                ContinueCase
            Case $GUI_EVENT_CLOSE
                If WinExists($hForm1_2) Then
                    GUICtrlSetState($hB_ASTCC, $GUI_ENABLE)
                    GUICtrlSetState($hB_ISTCC, $GUI_ENABLE)
                    GUIDelete($hForm1_2)
                    $hB_ICORD = $hDummy
                    $hB_ACORD = $hDummy
                    $hForm1_2 = $hDummy
                    ContinueCase ;SKIPEXIT
                EndIf
                GUIDelete($hForm1_1)
                Return ;
            Case "SKIPEXIT"
            Case $hB_ASTCC
                GUICtrlSetState($hB_ASTCC, $GUI_DISABLE)
                GUICtrlSetState($hB_ISTCC, $GUI_DISABLE)
                $hForm1_2 = GUICreate("Active Pos", 0, 0, -1, -1, $WS_OVERLAPPEDWINDOW)
                $aPos = GetRectFromString(GUICtrlRead($hI_ACORD))
                If IsArray($aPos) Then WinMove($hForm1_2, "", $aPos[0], $aPos[1], $aPos[2], $aPos[3])
                $hB_ACORD = GUICtrlCreateButton("Set", 0, 0, 50, 17)
                GUISetState(@SW_SHOW, $hForm1_2)
                ;GUICtrlSetData ( controlID, data [, default] )
            Case $hB_ACORD
                GUICtrlSetState($hB_ASTCC, $GUI_ENABLE)
                GUICtrlSetState($hB_ISTCC, $GUI_ENABLE)
                $aPos = WinGetPos($hForm1_2)
                GUICtrlSetData($hI_ACORD, ArrayToStr($aPos))
                $hB_ACORD = $hDummy
                GUIDelete($hForm1_2)
                $hForm1_2 = $hDummy
            Case $hB_ISTCC
                GUICtrlSetState($hB_ASTCC, $GUI_DISABLE)
                GUICtrlSetState($hB_ISTCC, $GUI_DISABLE)
                $hForm1_2 = GUICreate("Inactive Pos", 0, 0, -1, -1, $WS_OVERLAPPEDWINDOW)
                $aPos = GetRectFromString(GUICtrlRead($hI_ICORD))
                If IsArray($aPos) Then WinMove($hForm1_2, "", $aPos[0], $aPos[1], $aPos[2], $aPos[3])
                $hB_ICORD = GUICtrlCreateButton("Set", 0, 0, 50, 17)
                GUISetState(@SW_SHOW, $hForm1_2)
                ;GUICtrlSetData ( controlID, data [, default] )
            Case $hB_ICORD
                GUICtrlSetState($hB_ASTCC, $GUI_ENABLE)
                GUICtrlSetState($hB_ISTCC, $GUI_ENABLE)
                $aPos = WinGetPos($hForm1_2)
                GUICtrlSetData($hI_ICORD, ArrayToStr($aPos))
                $hB_ICORD = $hDummy
                GUIDelete($hForm1_2)
                $hForm1_2 = $hDummy
            Case $hB_Save
                $g_sExec = GUICtrlRead($hI_EXEC)
                $g_sMatchWin_FbTxt = GUICtrlRead($hI_FBT)
                $g_bMaxonAct = (BitAND(GUICtrlRead($hC_AMAXM), $GUI_CHECKED) = $GUI_CHECKED) ? 1 : 0
                $g_sKeysSend_Act = GUICtrlRead($hI_ASK)
                $g_sKeysSend_Inact = GUICtrlRead($hI_ISK)
                $g_sFileTypes = GUICtrlRead($hI_FEXT)
                $gaWinPosInact = GetRectFromString(GUICtrlRead($hI_ICORD))
                $gaWinPosAct = GetRectFromString(GUICtrlRead($hI_ACORD))
                Settings_Save()
                Return ;
        EndSwitch
    WEnd

EndFunc   ;==>Settings

Func Settings_Save()
    If Not _IsCompiled() Then Return
    IniWrite($gsINI_PATH, $gsCFG, $gaSettings[$geCfg_Exec], $g_sExec)
    IniWrite($gsINI_PATH, $gsCFG, $gaSettings[$geCfg_Close], $g_bClose ? 1 : 0)
    IniWrite($gsINI_PATH, $gsCFG, $gaSettings[$geCfg_Max], $g_bMaxonAct ? 1 : 0)
    IniWrite($gsINI_PATH, $gsCFG, $gaSettings[$geCfg_Sz], $g_iMinSz) ;Mb
    IniWrite($gsINI_PATH, $gsCFG, $gaSettings[$geCfg_Delay], $g_iKeyDelay)
    IniWrite($gsINI_PATH, $gsCFG, $gaSettings[$geCfg_DnDelay], $g_iKeyDnDelay)

    IniWrite($gsINI_PATH, $gsCFG, $gaSettings[$geCfg_KeysAct], $g_sKeysSend_Act)
    IniWrite($gsINI_PATH, $gsCFG, $gaSettings[$geCfg_KeysInA], $g_sKeysSend_Inact)
    IniWrite($gsINI_PATH, $gsCFG, $gaSettings[$geCfg_FileT], $g_sFileTypes)
    IniWrite($gsINI_PATH, $gsCFG, $gaSettings[$geCfg_WName], $g_sMatchWin_Name)
    IniWrite($gsINI_PATH, $gsCFG, $gaSettings[$geCfg_WTxt], $g_sMatchWin_FbTxt)

    IniWrite($gsINI_PATH, $gsCFG, $gaSettings[$geCfg_InACd], ArrayToStr($gaWinPosInact))
    IniWrite($gsINI_PATH, $gsCFG, $gaSettings[$geCfg_ActCd], ArrayToStr($gaWinPosAct))
EndFunc   ;==>Settings_Save

Func WinAPI_PostMessage($hWnd, $iMsg, $wParam, $lParam)
    Local $aResult = DllCall("user32.dll", "bool", "PostMessage", "hwnd", $hWnd, "uint", $iMsg, "wparam", $wParam, "lparam", $lParam)
    If @error Then Return SetError(@error, @extended, False)
    Return $aResult[0]
EndFunc   ;==>WinAPI_PostMessage

Func WinAPI_RegisterWindowMessage($sMessage)
    Local $aResult = DllCall("user32.dll", "uint", "RegisterWindowMessageW", "wstr", $sMessage)
    If @error Then Return SetError(@error, @extended, 0)
    Return $aResult[0]
EndFunc   ;==>WinAPI_RegisterWindowMessage

Func WaitActiveVLC_Win($aRect, $sKeys)
    ; Loops waiting for a trigger from vlc window either filename(s)
    ; in the title or window name and text
    ; if PID is defined and doesn't exist closes script
    ; Returns window handle
    Local $hWin = 0
    Local $bIsAct
    Do
        WinActivate($gsMatchVLC_Win, "")
        $hWin = WinWaitActive($gsMatchVLC_Win, "", $giACTWAIT) ; Wait for active window for number of seconds
        $bIsAct = ($hWin = 0 ? False : True)

        If Not $bIsAct Then ;Fallback
            WinActivate($gsMatchVLC_Win_Fb, $g_sMatchWin_FbTxt)
            $hWin = WinWaitActive($gsMatchVLC_Win_Fb, $g_sMatchWin_FbTxt, $giACTWAIT)

            $bIsAct = ($hWin = 0 ? False : True)
            If $bIsAct Then ExitLoop
            If $gPID And Not ProcessExists($gPID) And Not WinExists($gsMatchVLC_Win) Then Exit
            Sleep(1000)
        EndIf

        ;ConsoleWrite("VLC is " & ($bIsAct ? "" : "not ") & "active" & @CRLF)
    Until ($bIsAct)

    WinMoveArray($hWin, $aRect)

    If $sKeys <> "" Then ControlSend($hWin, "", 0, $sKeys) ;Send($sKeys)
    Sleep(100)

    If $g_bMaxonAct Then
        WinSetState($hWin, "", @SW_MAXIMIZE)
    EndIf

    Return $hWin
EndFunc   ;==>WaitActiveVLC_Win

Func WaitNotExists_Win($hWin, $aRect, $sKeys)
    ;Returns False if Title Does Not exist but $hWin DOES exist
    ;Returns True if $hWin + $title DOES NOT exist
    Do
        $gbActivated = False
        WinWaitClose(WinGetTitle($ghVlc))
    Until (Not $gbActivated)

    If WinExists($hWin) Then
        If $sKeys <> "" Then ControlSend($hWin, "", 0, $sKeys) ;Send($sKeys)
        Sleep(100)
        If $g_bMaxonAct Then WinSetState($hWin, "", @SW_RESTORE)

        WinMoveArray($hWin, $aRect)
        Return False
    EndIf
    Return True
EndFunc   ;==>WaitNotExists_Win

Func WinMoveArray($hWin, $aC)
    ;Moves $hWin to coords specified by array
    If IsArray($aC) And UBound($aC) == 4 Then
        ;_ArrayDisplay($aC, "Win Move")
        WinMove($hWin, "", $aC[0], $aC[1], $aC[2], $aC[3])
    EndIf
EndFunc   ;==>WinMoveArray

 

 

I haven't done a whole lot of testing of it and there are a few options you still need to edit from the ini file but it should make the worst / most used ones easy to set

Fixed a few bugs in the position helper windows they would set each others position depending on which was closed first

 

Edited by Bilgus
Old Code

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

×