alternative ways to showwindow?

Get help with using AutoHotkey (v1.1 and older) and its commands and hotkeys
User avatar
KuroiLight
Posts: 327
Joined: 12 Apr 2015, 20:24
Contact:

alternative ways to showwindow?

08 Feb 2018, 19:16

I'm using ControlClick to interact with Spotify (automatically), however the window ofc. needs to be visible for this to work, trying to get it to show it [the window when its behind another or minimized] without activating it is somewhat a struggle though;

I've tried changing Z-Order with DllCall("SetWindowPos", UInt, hwnd, UInt, 1, Int, 0, Int, 0, Int, 0, Int, 0, UInt, (SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE | SWP_SHOWWINDOW)), but it does nothing.
using showwindow DllCall("ShowWindow", UInt, hwnd, Int, SW_SHOWNOACTIVATE), but it does nothing.
SetForegroundWindow/SwitchToThisWindow works but ofcourse it activates the window, BringWindowToTop does nothing.
All return success [with no A_LastError] and running the script as admin doesn't change the results.

The only other working method is setting AlwaysOnTop but this isn't ideal.

Any other methods I've missed, before resorting to AlwaysOnTop?

*EDIT*
Just for confirmation heres what the I get back from each call:

Code: Select all

A_IsAdmin: 0
WindowHwnd: 0x1e60586

BringWindowToTop: 1
ErrorLevel: 0
A_LastError: 0

ShowWindow: 24
ErrorLevel: 0
A_LastError: 0

SetForegroundWindow: 1
ErrorLevel: 0
A_LastError: 0

BringWindowToTop: 1
ErrorLevel: 0
A_LastError: 0

--------------
A_IsAdmin: 1
WindowHwnd: 0x1e60586

BringWindowToTop: 1
ErrorLevel: 0
A_LastError: 0

ShowWindow: 24
ErrorLevel: 0
A_LastError: 0

SetForegroundWindow: 1
ErrorLevel: 0
A_LastError: 0

BringWindowToTop: 1
ErrorLevel: 0
A_LastError: 0
Last edited by KuroiLight on 08 Feb 2018, 19:38, edited 1 time in total.
Windows 10, Ryzen 1600, 16GB G.Skill DDR4, 8GB RX 480 | [MyScripts][MySublimeSettings] [Unlicense][MIT License]
01/24/18
[/color]
User avatar
Exaskryz
Posts: 2882
Joined: 17 Oct 2015, 20:28

Re: alternative ways to showwindow?

08 Feb 2018, 19:38

If ControlClick is working, and it is not activating the window, try just moving the window off screen. I have used WinMove, Title,, 0, 1100, 1000, 1000 (changing the 1000s to whatever size the window natively is; can be obtained with Window Spy or using WinGetPos) / WinMove, 0, 1100 when it was active to move the window to below the rendered area of my screen (which is 1920x1080) and been able to interact with it. In my case, I actually used normal Click and Send because the Control varieties weren't working.

It's a workaround, so I'd hope someone can supply a better answer.
User avatar
KuroiLight
Posts: 327
Joined: 12 Apr 2015, 20:24
Contact:

Re: alternative ways to showwindow?

08 Feb 2018, 19:44

ControlClick works and doesn't activate the window and I want to keep it that way; but the window has to be visibly on top
There is no WinSetPos so I tried
[code]
ShowNoActivateViaMove(hwnd) {
WinGetPos, x, y, w, h, ahk_id %hwnd%
WinSet, Region, %x%-%y%, ahk_id %hwnd%
}
[/code]
But it doesn't bring it forward.

*edit* guess you fixed winsetpos beofre I replied :P
changed it to:
[code]
ShowNoActivateViaMove(hwnd) {
WinGetPos, x, y, w, h, ahk_id %hwnd%
WinMove, ahk_id %hwnd%,, %x%, %y%, %w%, %h%
}
[/code]
still nope.

Nvm I misunderstood what you meant, I will try that.
Windows 10, Ryzen 1600, 16GB G.Skill DDR4, 8GB RX 480 | [MyScripts][MySublimeSettings] [Unlicense][MIT License]
01/24/18
[/color]
User avatar
KuroiLight
Posts: 327
Joined: 12 Apr 2015, 20:24
Contact:

Re: alternative ways to showwindow?

08 Feb 2018, 20:14

trying to see if it will work and... running into the multi-timer lockup bug again....
Don't understand why in some cases running 2 timers kills one of them.

Code: Select all

;Spotify Media Shorcuts
;Version: 1.0
;Author: KuroiLight/klomb
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

global script_conditional_param := "ahk_class SpotifyMainWindow"
#Include %A_ScriptDIr%\includes\CommonCode.ahk
;#NoTrayIcon
#UseHook, On

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

global DebugMode := 0, AdList := {}
global SearchArea_X, SearchArea_Y, SearchArea_W, SearchArea_H, sX, sY, sW, sH, PPBtn, VolBtn

Initialize()
Return

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
!\::PushButton(PPBtn)
!]::SendSpotify("^{Right}")
![::SendSpotify("^{Left}")
!'::SendSpotify("^{Up}")
!`;::SendSpotify("^{Down}")
!.::
    DebugMode += 1
    DebugMode := (DebugMode >= 3 ? 0 : DebugMode)
    Loop 19
        ToolTip,,,, %A_Index%
return
!/::
    cTitle := GetTitle()
    if(!AdList[cTitle]) {
        AdList[cTitle] := true
    } else {
        AdList.Delete(cTitle)
    }
    UpdateBlackList()
    UpdatePositions()
    if(isAd(cTitle) != isSpotifyMuted()) 
        PushButton(VolBtn)
return
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

Initialize() {
    MoveOffScreen()

    if(FileExist(".\SpotifyAdList.dat")) {
        Loop, Read, % ".\SpotifyAdList.dat"
        {
            AdList[A_LoopReadLine] := true
        }
    }

    SetTimer, AutoMove, -1500
    SetTimer, MainLoop, 1000
}

UpdateBlackList() {
    FileDelete, ".\SpotifyAdList.dat"
    for adName, _ in AdList
        FileAppend, %adName%`n, ".\SpotifyAdList.dat"
}

AutoMove() {
    Loop {
        WinWaitActive, %script_conditional_param%
        MoveOnScreen()
        WinWaitNotActive, %script_conditional_param%
        MoveOffScreen()
        Sleep, 100
    }
}

MainLoop() {
    static pTitle, cMuted
    CoordMode, Pixel, Screen

    if((cTitle := GetTitle()) != pTitle or isAd(cTitle) != cMuted) {
        Notify("[Spotify]`n" . cTitle)
        UpdatePositions()
        pTitle := cTitle

        if(isAd(cTitle) != (cMuted := isSpotifyMuted())) 
            PushButton(VolBtn)
    }

    if(DebugMode) {
        WinGetTitle, SpotifyTitle, %script_conditional_param%
        ToolTip, % "isAd=" . isAd(cTitle) . "`ncMuted=" . cMuted . "`ncSong=" . SpotifyTitle, 1, 1, 11
    }
}

GetTitle() {
    WinGetTitle, SpotifyTitle, %script_conditional_param%
    return SpotifyTitle
}

isAd(title) {
    return (AdList[title] ? true : false)
}

PushButton(Btn) {
    BtnX := (Btn.x + 10) - sX, BtnY := (Btn.y + 10) - sY
    if(DebugMode == 1)
        ToolTip, PushButton, % BtnX + sX, % BtnY + sY, 6
    ControlClick, x%BtnX% y%BtnY%, %script_conditional_param%
}

isSpotifyMuted() {
    PixelGetColor, cColor, % (VolBtn.x + 27), % (VolBtn.y + 7), RGB
    if(DebugMode == 1)
        ToolTip, %cColor%, % (VolBtn.x + 27) + 3, % (VolBtn.y + 7) + 3, 2
    return (!(cColor == 0xB3B3B3 or cColor == 0x1DB954 or cColor == 0xFFFFFF) ? true : false)
}

UpdatePositions() {
    static pX, pY, pW, pH
    WinGetPos, sX, sY, sW, sH, %script_conditional_param%

    if(sX != pX or sY != pY or sW != pW or sH != pH) {
        pX := sX, pY := sY, pW := sW, pH := sH
        SearchArea_X := sX
        SearchArea_Y := sY + sH - 75
        SearchArea_W := sX + sW
        SearchArea_H := sY + sH
        UpdateImgOffsets()
        if(DebugMode == 1) {
            ToolTip, SearchArea_XY, %SearchArea_X%, %SearchArea_Y%, 7
            ToolTip, SearchArea_WH, %SearchArea_W%, %SearchArea_H%, 3
        }
    }
}

UpdateImgOffsets() {
    static img_volbtn := ".\data\spotify\volBtn.png"
    static img_play := ".\data\spotify\play.png"
    static img_pause := ".\data\spotify\pause.png"

    While(!(VolBtn := ImageSearch(img_volbtn))) {
        Sleep, 25
    }
    PPBtn := ((PPBtn := ImageSearch(img_pause)) ? PPBtn : ImageSearch(img_play))

    if(DebugMode == 1) {
        ToolTip, VolBtn, % VolBtn.x, % VolBtn.y, 4
        ToolTip, PPBtn, % PPBtn.x, % PPBtn.y, 5
    }
}

ImageSearch(imgfile) {
    ImageSearch, fX, fY, %SearchArea_X%, %SearchArea_Y%, %SearchArea_W%, %SearchArea_H%, *100 *Trans0xEC0BE4 %imgfile%
    return (ErrorLevel == 0 ? {"x":fX, "y":fY} : false)
}

; ShowWindow() {
;     WinGet, sHwnd, ID, %script_conditional_param%
;     WinGet, mm, MinMax, %script_conditional_param%

;     a := WinActive(script_conditional_param)
;     WinGet, aot, Cmd, WinTitle, WinText, ExcludeTitle, ExcludeText]

;     if(WinActive(script_conditional_param))
;         return 1
;     DllCall("User32\ShowWindow", UInt, sHwnd, Int, 4, Int)
;     WinSet, AlwaysOnTop, On, %script_conditional_param%
;     WinSet, Redraw,, %script_conditional_param%
;     Sleep, 25
;     if(mm == -1) { ;minimized
;         Sleep, 250
;         return -1
;     }
;     return 0
; }

; HideWindow(pMM) {
;     if(pMM == 1)
;         return
;     WinSet, AlwaysOnTop, Off, %script_conditional_param%
;     WinSet, Bottom,, %script_conditional_param%

;     if(pMM == -1)
;         WinMinimize, %script_conditional_param%
; }

SendSpotify(key) {
    if(WinActive("ahk_class SpotifyMainWindow"))
        Send, %key%
    else
        ControlSend, ahk_parent, %key%, %script_conditional_param%
}

MoveOffScreen() {
    SysGet, Primary, MonitorPrimary
    SysGet, M, Monitor, %Primary%

    WinGetPos, x, y, w, h, %script_conditional_param%
    WinMove, %script_conditional_param%,, % (0 - w), % (MBottom + 1)
}

MoveOnScreen() {
    SysGet, Primary, MonitorPrimary
    SysGet, M, Monitor, %Primary%

    WinGetPos, x, y, w, h, %script_conditional_param%
    WinMove, %script_conditional_param%,, % (MRight / 2) - (w / 2), % (MBottom / 2) - (h / 2)
}
*EDIT*
I have my doubts that this method will work, I don't think ImageSearch works on offscreen objects and I still need to restore w/ no activate when I accidently hit minimize on spotify.
I'm open to other suggestions though.
*EDIT2*
Just confirmed ImageSearch doesn't work offscreen.
The funny thing is I'm working on this script despite the fact that Ill be re-subbing to spotify in a week or 2... lol
Windows 10, Ryzen 1600, 16GB G.Skill DDR4, 8GB RX 480 | [MyScripts][MySublimeSettings] [Unlicense][MIT License]
01/24/18
[/color]
User avatar
Exaskryz
Posts: 2882
Joined: 17 Oct 2015, 20:28

Re: alternative ways to showwindow?

08 Feb 2018, 23:49

Without any familiarity with Spotify or the images in your ImageSearch, I do wonder if they are strictly necessary though. I also see PixelGetColor strung throughout, so, that would probably need to be on screen unfortunately. I think if images/pixel colors are necessary, you may need to turn to GDI+, but I also have no familiarity with that.

You can handle the accidental minimize with a separate timer that checks every 200-300 ms for the state of Spotify with WinGet and the MinMax subcommand. Then make it WinRestore if it's the Minimized position (-1), but that would reactivate it... So you might need to capture the active window and WinActivate that active window immediately after restoring Spotify, maybe. Clunky, but could work...

This kind of alludes to the issue of multi-timer lock up. I see in some places you're using a Loop for WinWait[Not]Active -- in the AutoMove(), which might be a problem? If you have two loops like that, one thread is going to be interrupted by a never ending thread -- so the first thread isn't going to resume. I didn't spot the second potential offending loop that could be in a timer, but something to look for. That's why I suggested you keep repeating the WinGet for the MinMax; to avoid one of them getting permanently interrupted.
User avatar
KuroiLight
Posts: 327
Joined: 12 Apr 2015, 20:24
Contact:

Re: alternative ways to showwindow?

09 Feb 2018, 17:32

imagesearch/pixelgetcolor are needed because the entire spotify window just shows up as a Chrome_RenderWidgetHostHWND1, with no discernible controls.
Yea, you are likely right about WinWait commands, I had assumed they would automatically yield to other running timers between internal checks but I guess this wasn't considered when they were written.

*edit*
Just testing what causes the timer lockup and its easily reproduced, despite me thinking it should work.

Code: Select all

SetTimer, timer1, -60
;sleep, 1000
SetTimer, timer2, -50
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
return

timer1() {
    c1 := 0
    Loop {
        ToolTip, %c1%, 1, 1, 1
        c1++
        Sleep, 500
        Sleep, -1 ;yield
    }
}
timer2() {
    c2 := 0
    Loop {
        ToolTip, %c2%, 1, 40, 2
        c2++
        Sleep, 500
        Sleep, -1 ;yield
    }
}
^This timer1 function never completes a loop, but timer2 does. but adding a sleep between timer calls will stop timer2 from ever running.

but doing it this way, succeeds, I think some mention of this should be included in the docs. something like: "Using a negative value will cause the timer thread to return only when its completed." or "Using a negative value will stall the current thread until the timer finishes."

Code: Select all

SetTimer, timer1, 500
SetTimer, timer2, 500
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
return

timer1() {
    static c1 := 0
    c1++
    ToolTip, %c1%, 1, 1, 1
}
timer2() {
    static c2 := 0
    c2++
    ToolTip, %c2%, 1, 40, 2
}
Windows 10, Ryzen 1600, 16GB G.Skill DDR4, 8GB RX 480 | [MyScripts][MySublimeSettings] [Unlicense][MIT License]
01/24/18
[/color]
User avatar
jeeswg
Posts: 6902
Joined: 19 Dec 2016, 01:58
Location: UK

Re: alternative ways to showwindow?

09 Feb 2018, 19:19

- Did you try AccViewer, to investigate controls/GUI elements?
Acc library (MSAA) and AccViewer download links - AutoHotkey Community
https://autohotkey.com/boards/viewtopic.php?f=6&t=26201
- I searched threads featuring me for Spotify, and found these, in case they're useful:
Spotify - Adding a song to a specific playlist - AutoHotkey Community
https://autohotkey.com/boards/viewtopic.php?f=5&t=42651
Spotify Hotkeys (again) - AutoHotkey Community
https://autohotkey.com/boards/viewtopic.php?f=5&t=41636
Spotify PostMessage Library - AutoHotkey Community
https://autohotkey.com/boards/viewtopic.php?f=6&t=39465
Adding a song to a specific playlist in Spotify - AutoHotkey Community
https://autohotkey.com/boards/viewtopic.php?f=5&t=24771
homepage | tutorials | wish list | fun threads | donate
WARNING: copy your posts/messages before hitting Submit as you may lose them due to CAPTCHA

Return to “Ask for Help (v1)”

Who is online

Users browsing this forum: doodles333, exodus_cl, Google [Bot], ratyrat, Sniperman and 350 guests