Jump to content

Restore GUI if instance is running


Go to solution Solved by Zmylna,

Recommended Posts

Hi All.

I searched the forum but could not find a solution so I am writing a new thread.
I came across such a problem.

I have an application window where when I click a button the application window is hidden.
I wanted to achieve the effect that if the application is running and the window is hidden, and someone starts the application again then that it restores the main window.

It seemingly works but not quite.
The window is restored but the controls do not work.

#include <StaticConstants.au3>
#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
#Include <GuiButton.au3>
#include <Misc.au3>
#include <Array.au3>

check_instance_running()

$gui = GUICreate("gui V1.1.1",445,262,-1,-1,-1,-1)
$button = GUICtrlCreateButton("Button",60,20,100,30,-1,-1)
$bHide = GUICtrlCreateButton("Hide",60,60,100,30,-1,-1)
$label = GUICtrlCreateLabel("My Text",80,100,50,15,-1,-1)

GUISetState(@SW_SHOW,$gui)

$counter = 0

While 1
    $nMsg = GUIGetMsg()
    Switch $nMsg
        Case $GUI_EVENT_CLOSE
            Exit

        case $button
            $counter +=1
            guictrlsetdata($label, $counter)

        case $bHide
            GUISetState(@SW_HIDE,$gui)
    EndSwitch
WEnd

Func check_instance_running()
    
    Local $aWindows = ""
    Local $aWin = ""
    Local $hWin = ""

    If _Singleton("hide_win.exe", 1) = 0 Then
        $aWindows = WinList()

        $aWin = _ArraySearch($aWindows, "gui V1.1.1", 0, 0, 0, 1)

        If $aWin > 0 Then ; Mamy okno
            $hWin = $aWindows[$aWin][1]

            WinSetState($hWin, "", @SW_SHOW)
            WinActivate($hWin)

        EndIf

        Exit
    EndIf
EndFunc   ;==>check_instance_running

My guess is that the problem is that the window is hidden from within the application using GUISetState(@SW_HIDE,$gui) and restored from outside using WinSetState($hWin, "", @SW_SHOW). It seems that the main program does not know that the window is active again.

Can anyone suggest how to get around this ?

 

---edit---

ok, I solved this problem :)
This way works fine provided that the GUI is first shown (initialized) with GUISetState(@SW_SHOW, $GUI).

Func _api_win_show($hWnd, $state)
    If $state = 0 Then ; Hide Windows
        DllCall("user32.dll", "int", "ShowWindow", "hwnd", $hWnd, "int", @SW_HIDE)
    Else ; Show Window
        DllCall("user32.dll", "int", "ShowWindow", "hwnd", $hWnd, "int", @SW_SHOW)
    EndIf
EndFunc   ;==>_api_win_show

 

#include <StaticConstants.au3>
#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
#include <GuiButton.au3>
#include <Misc.au3>
#include <Array.au3>
#include <WinAPI.au3>

check_instance_running()

$gui = GUICreate("gui V1.1.1", 445, 262, -1, -1, -1, -1)
$button = GUICtrlCreateButton("Button", 60, 20, 100, 30, -1, -1)
$bHide = GUICtrlCreateButton("Hide", 60, 60, 100, 30, -1, -1)
$label = GUICtrlCreateLabel("My Text", 80, 100, 50, 15, -1, -1)

GUISetState(@SW_SHOW, $gui)

$counter = 0

While 1
    $nMsg = GUIGetMsg()
    Switch $nMsg
        Case $GUI_EVENT_CLOSE
            Exit

        Case $button
            $counter += 1
            GUICtrlSetData($label, $counter)

        Case $bHide
            ;GUISetState(@SW_HIDE,$gui)
            _api_win_show($gui,0)
    EndSwitch
WEnd

Func check_instance_running()
    ; ================================================================================================= Sprawdzenie czy program nie jest juz uruchomiony
    Local $aWindows = ""
    Local $aWin = ""
    Local $hWin = ""

    If _Singleton("hide_win.exe", 1) = 0 Then
        $aWindows = WinList()

        $aWin = _ArraySearch($aWindows, "gui V1.1.1", 0, 0, 0, 1)

        If $aWin > 0 Then ; Mamy okno
            $hWin = $aWindows[$aWin][1]

            ;WinSetState($hWin, "", @SW_SHOW)
            _api_win_show($hWin, 1)
            ;WinActivate($hWin)

        EndIf

        Exit
    EndIf
EndFunc   ;==>check_instance_running

Func _api_win_show($hWnd, $state)
    If $state = 0 Then ; Hide Windows
        DllCall("user32.dll", "int", "ShowWindow", "hwnd", $hWnd, "int", @SW_HIDE)
    Else ; Show Window
        DllCall("user32.dll", "int", "ShowWindow", "hwnd", $hWnd, "int", @SW_SHOW)
    EndIf
EndFunc   ;==>_api_win_show

 

Edited by Zmylna
Link to comment
Share on other sites

Try this :

#include <GUIConstantsEx.au3>
#include <Misc.au3>

If Not _Singleton("MyGui", 1) Then Exit WinSetState("gui V1.1.1", "", @SW_SHOW)

$gui = GUICreate("gui V1.1.1",445,262,-1,-1,-1,-1)
$button = GUICtrlCreateButton("Button",60,20,100,30,-1,-1)
$bHide = GUICtrlCreateButton("Hide",60,60,100,30,-1,-1)
$label = GUICtrlCreateLabel("My Text",80,100,50,15,-1,-1)

GUISetState()

$counter = 0

While 1
    $nMsg = GUIGetMsg()
    Switch $nMsg
        Case $GUI_EVENT_CLOSE
            Exit

      case $button
            $counter +=1
            guictrlsetdata($label, $counter)

        case $bHide
            WinSetState($gui, "", @SW_HIDE)
    EndSwitch
WEnd

 

Edited by Nine
Link to comment
Share on other sites

  • Solution
Posted (edited)
22 hours ago, Nine said:

Try this :

#include <GUIConstantsEx.au3>
#include <Misc.au3>

If Not _Singleton("MyGui", 1) Then Exit WinSetState("gui V1.1.1", "", @SW_SHOW)

$gui = GUICreate("gui V1.1.1",445,262,-1,-1,-1,-1)
$button = GUICtrlCreateButton("Button",60,20,100,30,-1,-1)
$bHide = GUICtrlCreateButton("Hide",60,60,100,30,-1,-1)
$label = GUICtrlCreateLabel("My Text",80,100,50,15,-1,-1)

GUISetState()

$counter = 0

While 1
    $nMsg = GUIGetMsg()
    Switch $nMsg
        Case $GUI_EVENT_CLOSE
            Exit

      case $button
            $counter +=1
            guictrlsetdata($label, $counter)

        case $bHide
            WinSetState($gui, "", @SW_HIDE)
    EndSwitch
WEnd

 

Simple and effective.
Thank you so much Nine :)

Edited by Zmylna
Link to comment
Share on other sites

  • Zmylna changed the title to Restore GUI if instance is running (SOLVED)
Posted (edited)

Nine, there is a small problem ;)

I forgot an important thing.
The application is supposed to run as a hide.
The window is to restore either a keyboard shortcut or by running again the exe.

And in that case the button no longer works :(

 

To summarize.
If the application is launched normally (the window is immediately visible) then everything is ok.

If the application is launched as hidden. Restarting the exe restores the window but the button no longer works.

 

In this configuration app does not work:

#include <GUIConstantsEx.au3>
#include <Misc.au3>

If Not _Singleton("MyGui", 1) Then Exit WinSetState("gui V1.1.1", "", @SW_SHOW)

$gui = GUICreate("gui V1.1.1",445,262,-1,-1,-1,-1)
$button = GUICtrlCreateButton("Button",60,20,100,30,-1,-1)
$bHide = GUICtrlCreateButton("Hide",60,60,100,30,-1,-1)
$label = GUICtrlCreateLabel("My Text",80,100,50,15,-1,-1)

;GUISetState()

$counter = 0

While 1
    $nMsg = GUIGetMsg()
    Switch $nMsg
        Case $GUI_EVENT_CLOSE
            Exit

      case $button
            $counter +=1
            guictrlsetdata($label, $counter)

        case $bHide
            WinSetState($gui, "", @SW_HIDE)
    EndSwitch
WEnd

---edit---

It seems that GUISetState() does more than just show the window so it must be at the beginning of the script.

So I came up with a kind of workaround:

WinSetTrans($gui, "", 0)
GUISetState()
WinSetState($gui, "", @SW_HIDE)
WinSetTrans($gui, "", 255)

Not very pretty but it works.

Edited by Zmylna
Link to comment
Share on other sites

  • Zmylna changed the title to Restore GUI if instance is running

It's the same problem, GUISetState won't work correctly with WinSetState.  If you just remove the GUISetState(), it is like doing a GUISetState(@SW_HIDE).  Then it will not work afterward.  Use that instead :

GUISetState()
WinSetState($gui, "", @SW_HIDE)

 

Link to comment
Share on other sites

8 hours ago, Nine said:

It's the same problem, GUISetState won't work correctly with WinSetState.  If you just remove the GUISetState(), it is like doing a GUISetState(@SW_HIDE).  Then it will not work afterward.  Use that instead :

GUISetState()
WinSetState($gui, "", @SW_HIDE)

 

Thank you for your reply.
I'm just not sure we understand each other.
Use the code below and see if the button works for you after you run the exe a second time.

The conditions that must be met are that the window after the startup must be hidden. The window is to appear only after the second launch of the exe.

 

#include <GUIConstantsEx.au3>
#include <Misc.au3>

If Not _Singleton("MyGui", 1) Then Exit WinSetState("gui V1.1.1", "", @SW_SHOW)

$gui = GUICreate("gui V1.1.1",445,262,-1,-1,-1,-1)
$button = GUICtrlCreateButton("Button",60,20,100,30,-1,-1)
$bHide = GUICtrlCreateButton("Hide",60,60,100,30,-1,-1)
$label = GUICtrlCreateLabel("My Text",80,100,50,15,-1,-1)


$counter = 0

While 1
    $nMsg = GUIGetMsg()
    Switch $nMsg
        Case $GUI_EVENT_CLOSE
            Exit

      case $button
            $counter +=1
            guictrlsetdata($label, $counter)

        case $bHide
            WinSetState($gui, "", @SW_HIDE)
    EndSwitch
WEnd

 

Link to comment
Share on other sites

1 hour ago, Zmylna said:

The window is to appear only after the second launch of the exe.

'cause you forgot to add GUISetState() ; display the GUI
No big deal :) 

#include <GUIConstantsEx.au3>
#include <Misc.au3>

If Not _Singleton("MyGui", 1) Then
    WinSetState("gui V1.1.1", "", @SW_SHOW)
    WinActivate("gui V1.1.1") ; easier to see when you "click click" the script
    Exit 5
EndIf


$gui = GUICreate("gui V1.1.1",445,262,-1,-1,-1,-1)
$button = GUICtrlCreateButton("Button",60,20,100,30,-1,-1)
$bHide = GUICtrlCreateButton("Hide",60,60,100,30,-1,-1)
$label = GUICtrlCreateLabel("My Text",80,100,50,15,-1,-1)
GUISetState() ; display the GUI

$counter = 0

While 1
    $nMsg = GUIGetMsg()
    Switch $nMsg
        Case $GUI_EVENT_CLOSE
            GUIDelete() ; this should be here too
            Exit

      case $button
            $counter +=1
            guictrlsetdata($label, $counter)

        case $bHide
            WinSetState($gui, "", @SW_HIDE)
    EndSwitch
WEnd

Edit: ..read the whole post and still believe that this code should have no problem.

Edit 2: I see that you marked yourself as solving the problem. Genieal ? :lol:

Edited by argumentum
like and subscribe 👍

Follow the link to my code contribution ( and other things too ).
FAQ - Please Read Before Posting.
autoit_scripter_blue_userbar.png

Link to comment
Share on other sites

Posted (edited)
49 minutes ago, argumentum said:

'cause you forgot to add GUISetState() ; display the GUI
No big deal :) 

#include <GUIConstantsEx.au3>
#include <Misc.au3>

If Not _Singleton("MyGui", 1) Then
    WinSetState("gui V1.1.1", "", @SW_SHOW)
    WinActivate("gui V1.1.1") ; easier to see when you "click click" the script
    Exit 5
EndIf


$gui = GUICreate("gui V1.1.1",445,262,-1,-1,-1,-1)
$button = GUICtrlCreateButton("Button",60,20,100,30,-1,-1)
$bHide = GUICtrlCreateButton("Hide",60,60,100,30,-1,-1)
$label = GUICtrlCreateLabel("My Text",80,100,50,15,-1,-1)
GUISetState() ; display the GUI

$counter = 0

While 1
    $nMsg = GUIGetMsg()
    Switch $nMsg
        Case $GUI_EVENT_CLOSE
            GUIDelete() ; this should be here too
            Exit

      case $button
            $counter +=1
            guictrlsetdata($label, $counter)

        case $bHide
            WinSetState($gui, "", @SW_HIDE)
    EndSwitch
WEnd

Edit: ..read the whole post and still believe that this code should have no problem.

Edit 2: I see that you marked yourself as solving the problem. Genieal ? :lol:

Hi Argumentum :)

No, I didn't forget to add GUISetState() 
By design, the script is not supposed to show the window on startup.
The window is supposed to show only after starting again the exe.

The application will be started automatically at Windows startup and will be hidden. The application is an address book.
The application is to have an option to be invoked (show main window) in three ways:
1. keyboard shortcut
3. clicking on the systray icon
4. running a shortcut on the desktop

 

Yes, at first I thought that Nine's solution would be ok but unfortunately not in the case when we do not want to show the window at the start of the script.

Edited by Zmylna
Link to comment
Share on other sites

45 minutes ago, Zmylna said:

not in the case when we do not want to show the window at the start of the script

#include <GUIConstantsEx.au3>
#include <Misc.au3>

If Not _Singleton("MyGui", 1) Then
    WinSetState("gui V1.1.1", "", @SW_SHOW)
    WinActivate("gui V1.1.1") ; easier to see when you "click click" the script
    Exit 5
EndIf


Global $gui = GUICreate("gui V1.1.1",445,262,-1,-1,-1,-1)
Global $button = GUICtrlCreateButton("Button",60,20,100,30,-1,-1)
Global $bHide = GUICtrlCreateButton("Hide",60,60,100,30,-1,-1)
Global $label = GUICtrlCreateLabel("My Text",80,100,50,15,-1,-1)

WinSetTrans($gui, "", 0) ; fake not there
GUISetState(@SW_SHOW) ; display the GUI
WinSetState($gui, "", @SW_HIDE) ; hide
WinSetTrans($gui, "", 255) ; restore tranparency back to solid

$counter = 0

While 1
    $nMsg = GUIGetMsg()
    Switch $nMsg
        Case $GUI_EVENT_CLOSE
            GUIDelete() ; this should be here too
            Exit

      case $button
            $counter +=1
            guictrlsetdata($label, $counter)

        case $bHide
            ConsoleWrite('case $bHide' & @CRLF)
            WinSetState($gui, "", @SW_HIDE)
    EndSwitch
WEnd

.. is a bit hacky but, if that does what you describe, then you are good.
The GUIGetMsg() not working is either a bug or a caveat of win32.

Edited by argumentum
like and subscribe 👍

Follow the link to my code contribution ( and other things too ).
FAQ - Please Read Before Posting.
autoit_scripter_blue_userbar.png

Link to comment
Share on other sites

6 minutes ago, argumentum said:
#include <GUIConstantsEx.au3>
#include <Misc.au3>

If Not _Singleton("MyGui", 1) Then
    WinSetState("gui V1.1.1", "", @SW_SHOW)
    WinActivate("gui V1.1.1") ; easier to see when you "click click" the script
    Exit 5
EndIf


Global $gui = GUICreate("gui V1.1.1",445,262,-1,-1,-1,-1)
Global $button = GUICtrlCreateButton("Button",60,20,100,30,-1,-1)
Global $bHide = GUICtrlCreateButton("Hide",60,60,100,30,-1,-1)
Global $label = GUICtrlCreateLabel("My Text",80,100,50,15,-1,-1)

WinSetTrans($gui, "", 0) ; fake not there
GUISetState(@SW_SHOW) ; display the GUI
WinSetState($gui, "", @SW_HIDE) ; hide
WinSetTrans($gui, "", 255) ; restore tranparency back to solid

$counter = 0

While 1
    $nMsg = GUIGetMsg()
    Switch $nMsg
        Case $GUI_EVENT_CLOSE
            GUIDelete() ; this should be here too
            Exit

      case $button
            $counter +=1
            guictrlsetdata($label, $counter)

        case $bHide
            ConsoleWrite('case $bHide' & @CRLF)
            WinSetState($gui, "", @SW_HIDE)
    EndSwitch
WEnd

.. is a bit hacky but it that does what you describe then you are good.
The GUIGetMsg() not working is either a bug or a caveat of win32.

Yes, I came up with this idea earlier. Look a few posts above ;)

It seems that there is no other way to do it.
But thank you for your help :)

Link to comment
Share on other sites

 

#include <GUIConstantsEx.au3>
#include <Misc.au3>

If WinExists("[TITLE:gui V1.1.1; CLASS:AutoIt v3 GUI]") Then
    WinActivate("[TITLE:gui V1.1.1; CLASS:AutoIt v3 GUI]")
    Send("+^h")
    Exit
EndIf

$beHide = False
HotKeySet("+^h", "GuiHider")

$gui = GUICreate("gui V1.1.1", 445, 262, -1, -1, -1, -1)
$button = GUICtrlCreateButton("Button", 60, 20, 100, 30, -1, -1)
$bHide = GUICtrlCreateButton("Hide", 60, 60, 100, 30, -1, -1)
$label = GUICtrlCreateLabel("My Text", 80, 100, 50, 15, -1, -1)
GUISetState(@SW_HIDE)

$counter = 0

While 1
    $nMsg = GUIGetMsg()
    Switch $nMsg
        Case $GUI_EVENT_CLOSE
            GUIDelete() ; this should be here too
            Exit
        Case $button
            $counter += 1
            GUICtrlSetData($label, $counter)
        Case $bHide
            GuiHider()
    EndSwitch
WEnd

Func GuiHider()
    ConsoleWrite("$beHide=" & $beHide & @CRLF)
    If $beHide = True Then
        GUISetState(@SW_HIDE)
        $beHide = False
    Else
        GUISetState(@SW_SHOW)
        $beHide = True
    EndIf
EndFunc   ;==>GuiHider

 

Edited by ioa747
UpDate

I know that I know nothing

Link to comment
Share on other sites

16 minutes ago, ioa747 said:

 

#include <GUIConstantsEx.au3>
#include <Misc.au3>

If WinExists("[TITLE:gui V1.1.1; CLASS:AutoIt v3 GUI]") Then
    WinActivate("[TITLE:gui V1.1.1; CLASS:AutoIt v3 GUI]")
    Send("^s")
    Exit
EndIf

$gui = GUICreate("gui V1.1.1", 445, 262, -1, -1, -1, -1)
$button = GUICtrlCreateButton("Button", 60, 20, 100, 30, -1, -1)
$bHide = GUICtrlCreateButton("Hide", 60, 60, 100, 30, -1, -1)
$dUnHide = GUICtrlCreateDummy()
$label = GUICtrlCreateLabel("My Text", 80, 100, 50, 15, -1, -1)

; Set GUIAccelerators for hide=Ctrl+h ; show=Ctrl+s
Local $aAccelKeys[2][2] = [["^h", $bHide], ["^s", $dUnHide]]
GUISetAccelerators($aAccelKeys)
GUISetState(@SW_HIDE)
$counter = 0
While 1
    $nMsg = GUIGetMsg()
    Switch $nMsg
        Case $GUI_EVENT_CLOSE
            GUIDelete() ; this should be here too
            Exit

        Case $button
            $counter += 1
            GUICtrlSetData($label, $counter)

        Case $bHide
            WinSetState($gui, "", @SW_HIDE)

        Case $dUnHide
            WinSetState($gui, "", @SW_SHOW)

    EndSwitch
WEnd

 

Interesting idea, thank you ioa747 :)

Link to comment
Share on other sites

Another way less hacky maybe :

#include <GUIConstantsEx.au3>
#include <Misc.au3>

If Not _Singleton("MyGui", 1) Then Exit WinSetState("gui V1.1.1", "", @SW_SHOW) + WinSetState("gui V1.1.1", "", @SW_RESTORE)

$gui = GUICreate("gui V1.1.1", 445, 262, -1, -1, -1, -1)
$button = GUICtrlCreateButton("Button", 60, 20, 100, 30, -1, -1)
$bHide = GUICtrlCreateButton("Hide", 60, 60, 100, 30, -1, -1)
$label = GUICtrlCreateLabel("My Text", 80, 100, 50, 15, -1, -1)
$label2 = GUICtrlCreateLabel("My Text", 80, 130, 50, 15, -1, -1)

GUISetState(@SW_SHOWMINIMIZED)
WinSetState($gui, "", @SW_HIDE)

$counter = 0

While 1
  $nMsg = GUIGetMsg()
  Switch $nMsg
    Case $GUI_EVENT_CLOSE
      Exit

    Case $button
      $counter += 1
      GUICtrlSetData($label, $counter)

    Case $bHide
      WinSetState($gui, "", @SW_HIDE)
  EndSwitch
WEnd

 

4 hours ago, argumentum said:

I see that you marked yourself as solving the problem. Genieal ? :lol:

Yes, it made me laugh too...

Edited by Nine
Link to comment
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
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...