Incorporate WinSet into Run function Topic is solved

Get help with using AutoHotkey (v1.1 and older) and its commands and hotkeys
Ecimeric
Posts: 130
Joined: 11 Jan 2017, 02:23

Incorporate WinSet into Run function

Post by Ecimeric » 21 Jan 2022, 02:55

Code: Select all

Func("Run").Bind("explorer C:", , "AlwaysOnTop")

Run(Target, WorkingDir := "", Options := "") {
    Run, % Target, % WorkingDir, % Options
    return
}
How might I incorporate WinSet, AlwaysOnTop as an option in my Run function?

amateur+
Posts: 655
Joined: 09 Oct 2021, 15:43

Re: Incorporate WinSet into Run function

Post by amateur+ » 21 Jan 2022, 03:37

Code: Select all

runExplorerAlwaysOnTop := Func("Run").Bind("explorer C:","" ,"", "On")

Run(Target, WorkingDir := "", Options := "", AlwaysOnTop := "") {
    Run, % Target, % WorkingDir, % Options, PID
	If AlwaysOnTop in On,Off,Toggle
 		WinSet, AlwaysOnTop, % AlwaysOnTop, ahk_pid %PID%
    return
}
Have found any drawback in my code or approach? Please, point it out. /The moderator ordered to remove the rest of the signature, I had obeyed.
And I really apologize for our russian president. Being a citizen of an aggressor country is very shameful. Personally I tried to avoid this trying to defend elections from fraud being a member of the election commission of one of the precincts but only was subjected to a hooligan attack and right before the vote count was illegally escorted from the polling station and spent the night behind bars (in jail) in a result of illegal actions of corrupt policemen.

User avatar
boiler
Posts: 16768
Joined: 21 Dec 2014, 02:44

Re: Incorporate WinSet into Run function

Post by boiler » 21 Jan 2022, 03:52

Here’s an approach allowing AlwaysOnTop to be included in the Options parameter. Also waits for the window to exist before executing the WinSet command, which is likely necessary.

Code: Select all

RunFunc := Func("Run").Bind("explorer C:", , "AlwaysOnTop")

Run(Target, WorkingDir := "", Options := "") {
    Options := StrReplace(Options, "AlwaysOnTop",, Count)
    Run, % Target, % WorkingDir, % Options, PID
    if Count {
        WinWait, ahk_pid %PID%
        WinSet, AlwaysOnTop, On, ahk_pid %PID%
    }
}

Btw, a return with no return expression right before the close parenthesis of a function is superfluous.

amateur+
Posts: 655
Joined: 09 Oct 2021, 15:43

Re: Incorporate WinSet into Run function

Post by amateur+ » 21 Jan 2022, 04:21

Boiler is right. WinWait is necessary and we don't need return here.
We can handle also AlwaysOnTopOff and AlwaysOnTopToggle variants if in the future we'll meet a window that has undesirable AlwaysOnTop On option on its startup.
Have found any drawback in my code or approach? Please, point it out. /The moderator ordered to remove the rest of the signature, I had obeyed.
And I really apologize for our russian president. Being a citizen of an aggressor country is very shameful. Personally I tried to avoid this trying to defend elections from fraud being a member of the election commission of one of the precincts but only was subjected to a hooligan attack and right before the vote count was illegally escorted from the polling station and spent the night behind bars (in jail) in a result of illegal actions of corrupt policemen.

Ecimeric
Posts: 130
Joined: 11 Jan 2017, 02:23

Re: Incorporate WinSet into Run function

Post by Ecimeric » 21 Jan 2022, 16:29

boiler wrote:
21 Jan 2022, 03:52

Code: Select all

RunFunc := Func("Run").Bind("explorer C:", , "AlwaysOnTop")
Menu, MyMenu, Add, RunFunc, % RunFunc
Menu, MyMenu, Show

Run(Target, WorkingDir := "", Options := "") {
    Options := StrReplace(Options, "AlwaysOnTop",, Count)
    Run, % Target, % WorkingDir, % Options, PID
    if Count {
        WinWait, ahk_pid %PID%
        WinSet, AlwaysOnTop, On, ahk_pid %PID%
    }
}
Thank you, both; however, Explorer does not open on top for me, and the script keeps running.

User avatar
boiler
Posts: 16768
Joined: 21 Dec 2014, 02:44

Re: Incorporate WinSet into Run function  Topic is solved

Post by boiler » 21 Jan 2022, 18:11

It does open up for me after I select it from the menu you added. Yours doesn't even do that?

However, mine didn't make it AlwaysOnTop, and I see that's because when you get the PID from the Run command when running a File Explorer window, it doesn't actually use the PID that is obtained. For now I tested it by just adding Sleep like below, and it works as expected:

Code: Select all

RunFunc := Func("Run").Bind("explorer C:", , "AlwaysOnTop")
Menu, MyMenu, Add, RunFunc, % RunFunc
Menu, MyMenu, Show

Run(Target, WorkingDir := "", Options := "") {
    Options := StrReplace(Options, "AlwaysOnTop",, Count)
    Run, % Target, % WorkingDir, % Options
    if Count {
		Sleep, 2000
        WinSet, AlwaysOnTop, On, A
    }
}

Something else could be done to make a more positive identification about the new window opening, but I won't bother implementing that until you at least get it to open a File Explorer window. Does the following single-line script not open a File Explorer window for you?

Code: Select all

Run, % "explorer C:"

Ecimeric
Posts: 130
Joined: 11 Jan 2017, 02:23

Re: Incorporate WinSet into Run function

Post by Ecimeric » 21 Jan 2022, 18:26

boiler wrote:
21 Jan 2022, 18:11
It does open up for me after I select it from the menu you added. Yours doesn't even do that?
It was opening, just not on top; it is working now, thank you :D

amateur+
Posts: 655
Joined: 09 Oct 2021, 15:43

Re: Incorporate WinSet into Run function

Post by amateur+ » 21 Jan 2022, 18:37

sleep 2000 is too long imho. You can open and set it on top faster. Here are two solutions. The first one:

Code: Select all

RunFunc := Func("Run").Bind("explorer C:", , "AlwaysOnTop")  ;
Menu, MyMenu, Add, RunFunc, % RunFunc
Menu, MyMenu, Show
return

Run(Target, WorkingDir := "", Options := "") {
    Options := StrReplace(Options, "AlwaysOnTop",, Count)
	oldActive := WinExist("A")
    Run, % Target, % WorkingDir, % Options
    if Count {
		while !(newActive := WinExist("A")) || (newActive = oldActive)
			Sleep 20
        WinSet, AlwaysOnTop, On
    }
}

And here is the second one:

Code: Select all

RunFunc := Func("Run").Bind("explorer C:", , "AlwaysOnTop")  ;
Menu, MyMenu, Add, RunFunc, % RunFunc
Menu, MyMenu, Show
return

Run(Target, WorkingDir := "", Options := "") {
    Options := StrReplace(Options, "AlwaysOnTop",, Count)
	oldActive := WinExist("A")
    Run, % Target, % WorkingDir, % Options
    if Count {
		WinWaitCreated("ahk_class CabinetWClass")
        WinSet, AlwaysOnTop, On, A
    }
}

; https://www.autohotkey.com/boards/viewtopic.php?f=6&t=1274
;~ https://www.autohotkey.com/board/topic/80644-how-to-hook-on-to-shell-to-receive-its-messages/
/*
  Wait for a window to be created, returns 0 on timeout and ahk_id otherwise
  Parameter are the same as WinWait, see http://ahkscript.org/docs/commands/WinWait.htm
  Forum: http://ahkscript.org/boards/viewtopic.php?f=6&t=1274&p=8517#p8517
*/
WinWaitCreated( WinTitle:="", WinText:="", Seconds:=0, ExcludeTitle:="", ExcludeText:="" ) {
    ; HotKeyIt - http://ahkscript.org/boards/viewtopic.php?t=1274
    static Found := 0, _WinTitle, _WinText, _ExcludeTitle, _ExcludeText 
        , init := DllCall( "RegisterShellHookWindow", "UInt",A_ScriptHwnd )
        , MsgNum := DllCall( "RegisterWindowMessage", "Str","SHELLHOOK" )
        , cleanup:={base:{__Delete:"WinWaitCreated"}}
    If IsObject(WinTitle)   ; cleanup
        return DllCall("DeregisterShellHookWindow","PTR",A_ScriptHwnd)
    else if (Seconds <> MsgNum) { ; User called the function
        Start := A_TickCount, _WinTitle := WinTitle, _WinText := WinText
        ,_ExcludeTitle := ExcludeTitle, _ExcludeText := ExcludeText
        ,OnMessage( MsgNum, A_ThisFunc ),  Found := 0
        While ( !Found && ( !Seconds || Seconds * 1000 < A_TickCount - Start ) ) 
            Sleep 16                                                         
        Return Found,OnMessage( MsgNum, "" )
    }
    If (WinTitle = 1   ; window created, check if it is our window
    && ExcludeTitle = A_ScriptHwnd
    && WinExist( _WinTitle " ahk_id " WinText,_WinText,_ExcludeTitle,_ExcludeText))
        WinWait % "ahk_id " Found := WinText ; wait for window to be shown
}
Have found any drawback in my code or approach? Please, point it out. /The moderator ordered to remove the rest of the signature, I had obeyed.
And I really apologize for our russian president. Being a citizen of an aggressor country is very shameful. Personally I tried to avoid this trying to defend elections from fraud being a member of the election commission of one of the precincts but only was subjected to a hooligan attack and right before the vote count was illegally escorted from the polling station and spent the night behind bars (in jail) in a result of illegal actions of corrupt policemen.

Ecimeric
Posts: 130
Joined: 11 Jan 2017, 02:23

Re: Incorporate WinSet into Run function

Post by Ecimeric » 22 Jan 2022, 00:45

amateur+ wrote:
21 Jan 2022, 18:37
sleep 2000 is too long imho. You can open and set it on top faster. Here are two solutions. The first one:
Thank you; I went with your first solution.

Post Reply

Return to “Ask for Help (v1)”