Jump to content

Keep focus at current window when clicking button GUI


Go to solution Solved by Melba23,

Recommended Posts

I created a GUI with a few buttons to move the current active window to a part of the screen:

(Left, Right, center, LeftTop, LeftBottom, RightTop, RightBottom)

 

When I click on a GUI button I lose the focus of my active window (the window to move).

How can I keep the focus on that window while clicking on a GUI button?

 

WinList() can give a list of active, enabled, minimized windows (and more) but there is no time indication.

What I want is to go back to the last active window (before using the GUI) or better never losing the focus of that window when I click on a GUI button.

 

Is that possible in autoit?

 

UPDATE:

 

The function below creates a GUI with buttons to move an application.

Example what I want to do with it:

I use notepad          --> activate GUI                      -->  click on button to move notepad

click on browser      --> click on button (in same already open Gui) to move browser

click on email client --> click on button (in same already open Gui) to move email client

 

This is my function:

#include <GUIConstantsEx.au3>
#include <MsgBoxConstants.au3>

HotKeySet("^3",  "MoveMenu")

While 1
    Sleep(10000)
WEnd

Func MoveMenu()
  If WinExists("Move Menu") Then
    GUIDelete("Move Menu")
  EndIf

$gActiveWin = PREVIOUS ACTIVE ??
  $Form1=GUICreate("Move Menu", 120, 220, 265, 142)
  $bLeft =        GUICtrlCreateButton("Left",          16,  50, 89, 25)
  $bRight =       GUICtrlCreateButton("Right",         16,  75, 89, 25)
  $bLeftTop =     GUICtrlCreateButton("LeftTop",       16, 100, 89, 25)
  $bLeftBottom =  GUICtrlCreateButton("LeftBottom",    16, 125, 89, 25)
  $bRightTop =    GUICtrlCreateButton("RightTop",      16, 150, 89, 25)
  $bRightBottom = GUICtrlCreateButton("RightBottom",   16, 175, 89, 25)
   GUISetState(@SW_SHOW, $Form1) While 1 $nMsg = GUIGetMsg() 

  While 1
   $nMsg = GUIGetMsg()
   Switch $nMsg
    Case $GUI_EVENT_CLOSE
        GUIDelete($Form1)

     Case $bLeft
        WinMove($gActiveWin, "",0,0,@DesktopWidth/2,@DesktopHeight-41)
     Case $bRight
        WinMove($gActiveWin, "",@DesktopWidth/2,0,@DesktopWidth/2,@DesktopHeight-41)
     Case $bLeftTop
        WinMove($gActiveWin, "",0,0,@DesktopWidth*0.5,@DesktopHeight*0.5-21)
     Case $bLeftBottom
        WinMove($gActiveWin, "",0,@DesktopHeight*0.5-21,@DesktopWidth*0.5,@DesktopHeight*0.5-21)
     Case $bRightTop
        WinMove($gActiveWin, "",@DesktopWidth*0.5,0,@DesktopWidth*0.5,@DesktopHeight*0.5-21)
     Case $bRightBottom
        WinMove($gActiveWin, "",@DesktopWidth*0.5,@DesktopHeight*0.5-21,@DesktopWidth*0.5,@DesktopHeight*0.5-21)

   EndSwitch
  WEnd
EndFunc ;==>MoveMenu
Edited by remin
Link to comment
Share on other sites

  • Moderators

remin,

You can do it this way:

#include <GUIConstantsEx.au3>
#include <MsgBoxConstants.au3>

AdlibRegister("_GetActive")
Global $hActive

$hGUI = GUICreate("Test", 500, 500)

$cButton = GUICtrlCreateButton("Test", 10, 10, 80, 30)

GUISetState()

While 1

    Switch GUIGetMsg()
        Case $GUI_EVENT_CLOSE
            Exit
        Case $cButton
            ConsoleWrite("Button pressed" & @CRLF)
            ; Reactivate last known active window
            WinActivate($hActive)
    EndSwitch

WEnd

Func _GetActive()
    $hCurrent = WinGetHandle("[ACTIVE]")
    If $hCurrent <> $hGUI Then
        $hActive = $hCurrent
    EndIf
EndFunc
Any use? :)

M23

Edited by Melba23
Added missing lines

Public_Domain.png.2d871819fcb9957cf44f4514551a2935.png Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind

Open spoiler to see my UDFs:

Spoiler

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

 

Link to comment
Share on other sites

easiest way, is to loop, and grab the handle of the active window to a variable, and when your window is active, DON'T overwrite the variable.

Else, you can get tricky, and look into _WinApi_GetWindow...the first param will be your window handle, the second $GW_HWNDNEXT.  This will grab the last active window, relative to YOUR window...you need to add logic to skip over some background threads...example, of two notepads open:

#include <WinAPI.au3>
#include <constants.au3>

sleep (5000)

$h = _WinAPI_GetWindow(HWnd("0x0000000000611E6E"),$GW_HWNDNEXT)
Do
    $h = _WinAPI_GetWindow($h,$GW_HWNDNEXT)
Until _WinAPI_GetClassName($h)<>"IME" And _WinAPI_GetClassName($h)<>"MSCTFIME UI" And _WinAPI_GetClassName($h)<>"tooltips_class32" And _
    _WinAPI_GetClassName($h)<>"AutoIt v3"
;~  _WinAPI_GetClassName($h)<>"WindowsForms10.tooltips_class32.app.0.1de93af" And _
ConsoleWrite($h & " " & WinGetTitle($h) & " " & _WinAPI_GetClassName($h) & @CRLF)

Better example...will grab the hwnd of the notepad, despite the gui created being active:

#include <WinAPI.au3>
#include <constants.au3>

$pid1 = Run("notepad.exe")
Sleep(1000)
$hMyGui = GUICreate("My GUI")
GUISetState(@SW_SHOW)

Sleep(1000)
Local $currentpid, $lastpid
$h = _WinAPI_GetWindow($hMyGui,$GW_HWNDNEXT)
_WinAPI_GetWindowThreadProcessId($h, $lastpid)
Do
    $h = _WinAPI_GetWindow($h,$GW_HWNDNEXT)
    _WinAPI_GetWindowThreadProcessId($h, $currentpid)
    If $currentpid = $lastpid Then
        ConsoleWrite("Same" & @CRLF)
        ContinueLoop
    Else
        $lastpid = $currentpid
    EndIf
Until _WinAPI_GetClassName($h)<>"IME" And _WinAPI_GetClassName($h)<>"MSCTFIME UI"
ConsoleWrite($h & " " & WinGetTitle($h) & " " & _WinAPI_GetClassName($h) & @CRLF)
WinActivate($h)



Edited by jdelaney
IEbyXPATH-Grab IE DOM objects by XPATH IEscriptRecord-Makings of an IE script recorder ExcelFromXML-Create Excel docs without excel installed GetAllWindowControls-Output all control data on a given window.
Link to comment
Share on other sites

Hello Melba,

Thank you for replying :)

I tried your code but nothing happens.

Are you sure nothing is missing?

Ah consolewrite() is a SciTe function isn't it?

Tried it in SciTe:

Line 25 Func _GetActive()

error: syntax error

error: Statement cannot be just an expression

---------

@jdelaney, 

Difficult to understand your solution.

I updated my question to give you a bit more info about my function.

Edited by remin
Link to comment
Share on other sites

  • Moderators

remin,

Sorry - the poor internet connection I was using mid-Channel ate the rest of the script! Try now. :)

M23

Public_Domain.png.2d871819fcb9957cf44f4514551a2935.png Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind

Open spoiler to see my UDFs:

Spoiler

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

 

Link to comment
Share on other sites

remin,

Sorry - the poor internet connection I was using mid-Channel ate the rest of the script! Try now. :)

M23

 

No problem. Thank you very much for your help Melba :)

Yes it seems to give focus to the previous window but I noted that it does not change focus if the previous window changes.

p.e if I use the browser and then click on the test button in the GUI it does not activate the browser it activates the window before I started the GUI.

Please see my question, I wrote this morning a bit more info in it.

Link to comment
Share on other sites

  • Moderators

remin,

 

if I use the browser and then click on the test button in the GUI it does not activate the browser it activates the window before I started the GUI

Then something very strange is happening - as for me it reactivates the window that was active immediately before button press, even when it has changed since the example began. :wacko:

M23

Edit: You do have the AdlibRegister("_GetActive") line in there? :huh:

Edited by Melba23

Public_Domain.png.2d871819fcb9957cf44f4514551a2935.png Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind

Open spoiler to see my UDFs:

Spoiler

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

 

Link to comment
Share on other sites

What if you had a gui that was always on top of the other windows and would list all the open windows in one column and you could select one and then choose the button for the screen position. You could move or minimize the GUI if you wanted to. Would this work for your purposes or are you trying to automate something?

Get Scite to add a popup when you use a 3rd party UDF -> http://www.autoitscript.com/autoit3/scite/docs/SciTE4AutoIt3/user-calltip-manager.html

Link to comment
Share on other sites

Oh yes.. I removed the `AdlibRegister("_GetActive")` and added it in the while 1 loop. I thought that it was needed there.

I removed and added it again at the start of the function and it works as you've indicated.  :thumbsup:

Just noted a few things:

- it does not work always, sometimes I have to click 2 or more times in the last window to make it recognize as the active window.

- it works also on the GUI self --> sometimes when I click on a GUI button it moves the GUI and not the previous active window.

- last question: I have more functions which I want to use AdlibRegister("_GetActive"). Is it possible to send the GUI name to `_GetActive`?

  Something like this (but this doesn't work): AdlibRegister("_GetActive($form1)")

This is my function now:

#include <GUIConstantsEx.au3>
#include <MsgBoxConstants.au3>
#include <WinAPI.au3>
#include <constants.au3>

HotKeySet("^3",  "MoveMenu")

Global $Form1
Global $hActive

While 1
    Sleep(10000)
WEnd

Func MoveMenu()
  If WinExists("Move Menu") Then
    GUIDelete("Move Menu")
  EndIf

AdlibRegister("_GetActive")


  $Form1=GUICreate("Move Menu", 120, 220, 265, 142)
  $bLeft =        GUICtrlCreateButton("Left",          16,  50, 89, 25)
  $bRight =       GUICtrlCreateButton("Right",         16,  75, 89, 25)
  $bLeftTop =     GUICtrlCreateButton("LeftTop",       16, 100, 89, 25)
  $bLeftBottom =  GUICtrlCreateButton("LeftBottom",    16, 125, 89, 25)
  $bRightTop =    GUICtrlCreateButton("RightTop",      16, 150, 89, 25)
  $bRightBottom = GUICtrlCreateButton("RightBottom",   16, 175, 89, 25)
  GUISetState(@SW_SHOW, $Form1)

  While 1
   $nMsg = GUIGetMsg()
   Switch $nMsg
    Case $GUI_EVENT_CLOSE
       GUIDelete($Form1)

     Case $bLeft
        WinMove($hActive, "",0,0,@DesktopWidth/2,@DesktopHeight-41)
     Case $bRight
        WinMove($hActive, "",@DesktopWidth/2,0,@DesktopWidth/2,@DesktopHeight-41)
     Case $bLeftTop
        WinMove($hActive, "",0,0,@DesktopWidth*0.5,@DesktopHeight*0.5-21)
     Case $bLeftBottom
        WinMove($hActive, "",0,@DesktopHeight*0.5-21,@DesktopWidth*0.5,@DesktopHeight*0.5-21)
     Case $bRightTop
        WinMove($hActive, "",@DesktopWidth*0.5,0,@DesktopWidth*0.5,@DesktopHeight*0.5-21)
     Case $bRightBottom
        WinMove($hActive, "",@DesktopWidth*0.5,@DesktopHeight*0.5-21,@DesktopWidth*0.5,@DesktopHeight*0.5-21)

   EndSwitch
  WEnd
EndFunc ;==>MoveMenu

Func _GetActive()
    $hCurrent = WinGetHandle("[ACTIVE]")
    ;ConsoleWrite(WinGetTitle($hActive) & ' ' & $hCurrent & ' - ' & $gFormNR & ' - ' & $Form1 & @CRLF)
    If $hCurrent <> $Form1 Then
        $hActive  = $hCurrent
    EndIf
EndFunc
Edited by remin
Link to comment
Share on other sites

  • Moderators

remin,

You are now only setting the Adlib as you enter the HotKey function - so it will not run before the GUI is created and so you only store the values of GUIs activate after you create your own GUI, which is not what you want and which ex-plains your puzzling symptoms. ;)

You should add a call to the function before setting its Adlib call:

_GetActive()
AdlibRegister("_GetActive")
Now you will set the active window to the GUI that is active just before you create your own GUI - the Adlib calls will keep the handle updated if other GUIs are activated later. :)

And I suggest you deregister the Adlib call as you exit your GUI - no point in it running when no longer required. ;)

M23

Public_Domain.png.2d871819fcb9957cf44f4514551a2935.png Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind

Open spoiler to see my UDFs:

Spoiler

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

 

Link to comment
Share on other sites

Thank you Melba. :)

I resolved my question.

This is what I've done (see $gFormNR and Adlib/AddlibUn)

Hope it is correct :)

Global $gFormNr

Function...
  _GetActive()
  AdlibRegister("_GetActive")


  $Form1=GUICreate("Move Menu", 120, 250, 265, 142, _
             BitOr($WS_BORDER, $WS_EX_TOOLWINDOW), BitOR($WS_EX_TOPMOST, $WS_EX_TOOLWINDOW))
  $gFormNr = $Form1
  etc

  While 1
   .....
  WEnd
  AdlibUnRegister("_GetActive")
EndFunc


Func _GetActive()
    $hCurrent = WinGetHandle("[ACTIVE]")
    If $hCurrent <> $gFormNr Then
        $hActive  = $hCurrent
    EndIf
EndFunc

What I don't understand is why this doesn't work:

(see _GetActive / Adlib / AdlibUn)

_GetActive()

Function...
  $Form1=GUICreate("Move Menu", 120, 250, 265, 142, _
             BitOr($WS_BORDER, $WS_EX_TOOLWINDOW), BitOR($WS_EX_TOPMOST, $WS_EX_TOOLWINDOW))
  $gFormNr = $Form1

  While 1
    Switch GUIGetMsg()
      Case $GUI_EVENT_CLOSE
         GUIDelete($Form1)


      Case $bLeft to $bRight
        Switch GUIGetMsg()
         AdlibRegister("_GetActive")
         AdlibUnRegister("_GetActive")

  
        Case $bLeft
             WinMove($hActive, "",0,0,@DesktopWidth/2,@DesktopHeight-41)
        Case $bRight          
             etc
      EndSwitch
    EndSwitch
  WEnd
EndFunc


Func _GetActive()
    $hCurrent = WinGetHandle("[ACTIVE]")
    If $hCurrent <> $gFormNr Then
        $hActive  = $hCurrent
    EndIf
EndFunc

Remin

Edited by remin
Link to comment
Share on other sites

  • Moderators

remin,

It does not work because there are several mistakes in that snippet: ;)

Function...

    _GetActive()                ; Get the active GUI BEFORE your GUI is created
    AdlibRegister("_GetActive") ; Check for changes to the active GUI WHILE your GUI is active

    $Form1 = GUICreate("Move Menu", 120, 250, 265, 142, _
            $WS_BORDER, BitOR($WS_EX_TOPMOST, $WS_EX_TOOLWINDOW)) ; No need to use the _EX_TOOLWINDOW style twice!
    $gFormNR = $Form1

    While 1
        $iMsg = GUIGetMsg() ; You want to use this value twice, so save the value
        Switch $iMsg
            Case $GUI_EVENT_CLOSE
                GUIDelete($Form1)
                AdlibUnRegister("_GetActive") ; No point in checking any longer

            Case $bLeft, $bRight ; But why bother with this double Switch at all?  Why not just have 4 separate cases?
                Switch $iMsg ; Now you are checking the SAME message - calling GUIGetMsg again as you did before was looking at the NEXT one in the queue
                    Case $bLeft
                        ;
                    Case $bRight
                        ;
                EndSwitch
        EndSwitch
    WEnd
EndFunc
Does that make it clearer? :)

M23

Public_Domain.png.2d871819fcb9957cf44f4514551a2935.png Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind

Open spoiler to see my UDFs:

Spoiler

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

 

Link to comment
Share on other sites

Melba, 

Still something doesn't work.

p.e. considering these functions with `AdlibRegister("_GetActive")`

 
HotKeySet("^3",  "MoveMenu")
HotKeySet("^7",  "ConvertCase")

Func MoveMenu() 

  _GetActive() 
  AdlibRegister("_GetActive") 

  $Form1=GUICreate("Move",60,370,IniRead($gMyINI,"POS_MoveMenu","x",0),IniRead($gMyINI,"POS_MoveMenu","y",0), _ 
  $WS_BORDER, BitOR($WS_EX_TOPMOST, $WS_EX_TOOLWINDOW)) 
  $gFormNr = $Form1 
    $bLeft = GUICtrlCreateButton("1", $horiz, $vertic, 20, 40) 
    $bRight = etc 
  GUISetState(@SW_SHOW, $Form1)

  While 1 
    $nMsg = GUIGetMsg() 
      Switch $nMsg 
        Case $GUI_EVENT_CLOSE 
          AdlibUnRegister("_GetActive")
          SUB_Write2ini("Move", "POS_MoveMenu","","","") 
        Case $bLeft 
          WinMove($gActiveWin, "",0,0,@DesktopWidth/2,@DesktopHeight-41) 
        Case ... etc 
      EndSwitch 
  WEnd 
EndFunc 


Func ConvertCase() 
  _GetActive() 
  AdlibRegister("_GetActive") 

  local $Result2 

  $Form2=GUICreate("Case", 90, 190,IniRead($gMyINI,"POS_ConvertCase","x",0),IniRead($gMyINI,"POS_ConvertCase","y",0), _ 
  $WS_BORDER, BitOR($WS_EX_TOPMOST, $WS_EX_TOOLWINDOW)) 
  gFormNR = $Form2 
    $bUpper = GUICtrlCreateButton("Upper", 10, 20, 70, 20) 
    $bLower ....etc 
  GUISetState(@SW_SHOW, $Form2) 

  While 1 
    $nMsg = GUIGetMsg() 
    Switch $nMsg 
     Case $GUI_EVENT_CLOSE 
      AdlibUnRegister("_GetActive") 
      SUB_Write2ini("Case", "POS_ConvertCase","","","") 
     
     Case $bUpper,$bLower, .... etc
      WinActivate($gActiveWin) 

        Switch $nMsg 
          Case $bUpper 
             $Result2 = StringUpper(ClipGet()) 
        Case $bLower .... 
    EndSwitch 
   EndSwitch 
  WEnd 
EndFunc 


Func _GetActive() 
  $hCurrent = WinGetHandle("[ACTIVE]") 
  If $hCurrent <> $gFormNr Then 
   $gActiveWin = $hCurrent 
  EndIf 
EndFunc 


Func SUB_Write2ini($FormName, $POS_Cat, $Focus_Cat, $CheckBox_Cat, $Focus) 
  MsgBox(0,"",$POS_Cat) 
  Local $Handle = WinGetHandle($FormName, "") 
  $RFScreenPos = WinGetPos($Handle, "") 

  IniWrite($gMyINI, $POS_Cat, "x", $RFScreenPos[0]) 
  IniWrite($gMyINI, $POS_Cat, "y", $RFScreenPos[1])

  GUIDelete($FormName) 
EndFunc

When I activate both functions (using the hotkey) and close one of them, the other is not recognized anymore.

p.e. when I close the function `ConvertCase` using ESC,

SUB_Write2ini writes the positions in the ini file as I wanted.

But the other GUI `Move` doesn't work anymore.

It is not recognized anymore.

Is it because of `AdlibUnRegister("_GetActive")` that this GUI is not active anymore?

Not easy autoit :)

Edited by remin
Link to comment
Share on other sites

  • Moderators

remin,

The problem arises because you are creating 2 While...WEnd loops when you run both functions via the HotKeys - plus you are overwriting the $gFormNr variable with the last created dialog. :(

I suggest you deactivate bothHotKeys when you enter one of the dialogs and only reactivate them when you exit - the conflicts will then not occur. :)

M23

Public_Domain.png.2d871819fcb9957cf44f4514551a2935.png Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind

Open spoiler to see my UDFs:

Spoiler

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

 

Link to comment
Share on other sites

Thank you Melba. :)

Using both functions would not be possible in that case?

Maybe I haven't fully understand what you mean with you answer.

Deactivating both hotkeys, if I do this, how can I activate the functions?

(btw I have more functions with while loops in this .au3 file)

Link to comment
Share on other sites

  • Moderators

remin,

 

Using both functions would not be possible in that case?

Not at the same time - you would have to close one dialog before you could activate it again (this is considered good coding practice in any case) or fire the other HotKey. :)

 

Deactivating both hotkeys, if I do this, how can I activate the functions?

Read what I said: " reactivate them when you exit" - when you have finished with one of the dialogs, you reactivate the HotKeys ready for the next time you need them. ;)

AutoIt does not like multiple While...WEnd loops - it tends to get stuck in them unless you are very careful. And if you are in such a loop within a function, you risk everything else becoming unresponsive. Perhaps if you posted the entire script with some explanation of what you are trying to do I might be able to offer some more focused advice - send it to me via PM if you want to keep it private. :)

M23

Public_Domain.png.2d871819fcb9957cf44f4514551a2935.png Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind

Open spoiler to see my UDFs:

Spoiler

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

 

Link to comment
Share on other sites

  • 4 weeks later...
  • Moderators
  • Solution

Hi,

After a protracted development period (we were both away for periods) I have managed to produce something which meets remin's many and complex requirements - so I thought I would post a boilerplate version here in case anyone looking was interested and wanted to modify it for their own needs. :)

First off, you will need a v3.3.13.# Beta version to run the code as it uses maps. ;)

A few words of explanation. remin wanted to wrap a lot of small scripts he had developed into one large package with each actioned by a HotKey. But he was having problems integrating them all as some of the scripts used small dialogs and he could not get them to work nicely together. As I explained earlier in the thread, this is because each of the scripts when called interrupted the current one and AutoIt was getting confused. The solution I adopted was to break each of the existing scripts into 3 parts: creation, action, deletion. Then the wrapper script calls these sections when required, using maps to determine whether a dialog is active, has been actioned, or should be deleted. There was also a requirement to reactivate the previously active window when the dialogs were action, to store the positions of the dialogs on exit or when moved, and to allow {ESC} to close them. :sweating:

Here is what I finally came up with - I have commented liberally so I hope you can follow what is going on:

#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>

#NoTrayIcon

Global $mDialog[]               ; Map to hold open dialog handles

; Functions which have a GUI
HotKeySet("^6", "_Script_6")    ; Hotkey to activate dialog
Global $mScript_6[]             ; Map to hold dialog handle and ControlIDs
HotKeySet("^7", "_Script_7")
Global $mScript_7[]
HotKeySet("^8", "_Script_8")
Global $mScript_8[]

; Functions which do not have a GUI
HotKeySet("^1", "Script_1") ; HotKey to action function
HotKeySet("^2", "Script_2")

Global $gLastDialog = 0         ; Last active dialog
Global $gMyINI = "Dialog.ini"   ; Ini file
Global $gActiveWin = 0          ; Handle of active window other than dialogs

HotKeySet("!^{ESC}", "_Exit")       ; HotKey to exit script
HotKeySet("{ESC}", "_CloseLast")    ; HotKey to exit last active dialog

Opt("GUIEventOptions", 1)       ; Prevent autoclosing of dialogs

; Register message to detect when dialogs moved
GUIRegisterMsg($WM_EXITSIZEMOVE, "_Dialog_Moved")

; Start timer
$nBegin = TimerInit()

While 1

    $aMsg = GUIGetMsg(1)
    Switch $aMsg[1]
        Case $mScript_6["Dialog"]
            ; Onlt check the dialog for events if it has been activated
            _Check_Script_6($aMsg[0])
        Case $mScript_8["Dialog"]
            _Check_Script_8($aMsg[0])
        Case $mScript_7["Dialog"]
            _Check_Script_7($aMsg[0])
    EndSwitch

    ; Check for current active window other than dialogs
    If TimerDiff($nBegin) > 250 Then
        _GetActive()
        ; Reset timer
        $nBegin = TimerInit()
    EndIf


WEnd

Func _Script_6() ; Called when HotKey is pressed

    If Not MapExists($mScript_6, "Dialog") Then
        ; Create the dialog if it does not exist
        _Create_Script_6()
    EndIf

EndFunc   ;==>Script_6

Func _Create_Script_6()

    ; Get the current active window - just in case
    _GetActive()

    ; Determine the coordinates to use
    Local $iX = IniRead($gMyINI, "POS_Script_6", "x", 100)
    Local $iY = IniRead($gMyINI, "POS_Script_6", "y", 100)

    ; Create the dialog
    $hDialog = GUICreate("Script_6", 200, 200, $iX, $iY, Default, BitOR($WS_EX_TOPMOST, $WS_EX_TOOLWINDOW))

    ; Save the dialog handle
    $mScript_6["Dialog"] = $hDialog
    $mDialog["Script_6"] = $hDialog
    $gLastDialog = $hDialog

    ; Add controls ad store the ControlIDs
    $mScript_6["One"] = GUICtrlCreateButton("Script_6 1", 10, 10, 80, 30)
    $mScript_6["Two"] = GUICtrlCreateButton("Script_6 2", 10, 50, 80, 30)

    GUISetState(@SW_SHOWNOACTIVATE, $hDialog)

    ; Reactivate the current window - just in case
    WinActivate($gActiveWin)

EndFunc   ;==>_Create_Script_6

Func _Check_Script_6($iMsg)

    Switch $iMsg
        Case $GUI_EVENT_CLOSE
            _Delete_Script_6()
        Case $mScript_6["One"] To $mScript_6["Two"]
            ; Reactivate the previously active window
            WinActivate($gActiveWin)
            $gLastDialog = $mScript_6["Dialog"]
            Switch $iMsg
                Case $mScript_6["One"]
                    ; Add required code here
                    ConsoleWrite("Script_6 Button 1 pressed" & @CRLF)
                Case $mScript_6["Two"]
                    ConsoleWrite("Script_6 Button 2 pressed" & @CRLF)
            EndSwitch
    EndSwitch

EndFunc   ;==>_Check_Script_6

Func _Delete_Script_6()

    ; Save current dialog position
    IniWrite($gMyINI, "POS_Script_6", "x", WinGetPos($mScript_6["Dialog"])[0])
    IniWrite($gMyINI, "POS_Script_6", "y", WinGetPos($mScript_6["Dialog"])[1])
    ; Delete dialog
    GUIDelete($mScript_6["Dialog"])
    ; Remove from maps
    MapRemove($mScript_6, "Dialog") ; Now the dialog will be recreated when the HotKey is nexxt pressed
    MapRemove($mDialog, "Script_6") ; Now the _Check_ function will not be run

EndFunc

Func _Script_7() ; Called when HotKey is pressed

    If Not MapExists($mScript_7, "Dialog") Then
        _Create_Script_7()
    EndIf

EndFunc   ;==>Script_6

Func _Create_Script_7()

    _GetActive()

    Local $iX = IniRead($gMyINI, "POS_Script_7", "x", 300)
    Local $iY = IniRead($gMyINI, "POS_Script_7", "y", 300)
    $hDialog = GUICreate("Script_7", 200, 200, $iX, $iY, Default, BitOR($WS_EX_TOPMOST, $WS_EX_TOOLWINDOW))

    $mScript_7["Dialog"] = $hDialog
    $mDialog["Script_7"] = $hDialog
    $gLastDialog = $hDialog

    $mScript_7["One"] = GUICtrlCreateButton("Script_7 1", 10, 10, 80, 30)
    $mScript_7["Two"] = GUICtrlCreateButton("Script_7 2", 10, 50, 80, 30)

    GUISetState(@SW_SHOWNOACTIVATE, $hDialog)

    WinActivate($gActiveWin)

EndFunc   ;==>_Create_Script_7

Func _Check_Script_7($iMsg)

    Switch $iMsg
        Case $GUI_EVENT_CLOSE
            _Delete_Script_7()
        Case $mScript_7["One"] To $mScript_7["Two"]
            WinActivate($gActiveWin)
            $gLastDialog = $mScript_7["Dialog"]
            Switch $iMsg
                Case $mScript_7["One"]
                    ConsoleWrite("Script_7 Button 1 pressed" & @CRLF)
                Case $mScript_7["Two"]
                    ConsoleWrite("Script_7 Button 2 pressed" & @CRLF)
            EndSwitch
    EndSwitch

EndFunc   ;==>_Check_Script_7

Func _Delete_Script_7()

    IniWrite($gMyINI, "POS_Script_7", "x", WinGetPos($mScript_7["Dialog"])[0])
    IniWrite($gMyINI, "POS_Script_7", "y", WinGetPos($mScript_7["Dialog"])[1])
    GUIDelete($mScript_7["Dialog"])
    MapRemove($mScript_7, "Dialog")
    MapRemove($mDialog, "Script_7")

EndFunc

Func _Script_8() ; Called when HotKey is pressed

    If Not MapExists($mScript_8, "Dialog") Then
        _Create_Script_8()
    EndIf

EndFunc   ;==>Script_8

Func _Create_Script_8()

    _GetActive()

    Local $iX = IniRead($gMyINI, "POS_Script_8", "x", 500)
    Local $iY = IniRead($gMyINI, "POS_Script_8", "y", 500)
    $hDialog = GUICreate("Script_8", 200, 200, $iX, $iY, Default, BitOR($WS_EX_TOPMOST, $WS_EX_TOOLWINDOW))

    $mScript_8["Dialog"] = $hDialog
    $mDialog["Script_8"] = $hDialog
    $gLastDialog = $hDialog

    $mScript_8["One"] = GUICtrlCreateButton("Script_8 1", 10, 10, 80, 30)
    $mScript_8["Two"] = GUICtrlCreateButton("Script_8 2", 10, 50, 80, 30)

    GUISetState(@SW_SHOWNOACTIVATE, $hDialog)

    WinActivate($gActiveWin)

EndFunc   ;==>_Create_Script_8

Func _Check_Script_8($iMsg)

    Switch $iMsg
        Case $GUI_EVENT_CLOSE
            _Delete_Script_8()
        Case $mScript_8["One"] To $mScript_8["Two"]
            WinActivate($gActiveWin)
            $gLastDialog = $mScript_8["Dialog"]
            Switch $iMsg
                Case $mScript_8["One"]
                    ConsoleWrite("Script_8 Button 1 pressed" & @CRLF)
                Case $mScript_8["Two"]
                    ConsoleWrite("Script_8 Button 2 pressed" & @CRLF)
            EndSwitch
    EndSwitch

EndFunc   ;==>_Check_Script_8

Func _Delete_Script_8()

    IniWrite($gMyINI, "POS_Script_8", "x", WinGetPos($mScript_8["Dialog"])[0])
    IniWrite($gMyINI, "POS_Script_8", "y", WinGetPos($mScript_8["Dialog"])[1])
    GUIDelete($mScript_8["Dialog"])
    MapRemove($mScript_8, "Dialog")
    MapRemove($mDialog, "Script_8")

EndFunc

Func Script_1()
    ; There is no dialog so just run the required code here
    ConsoleWrite("Script_1 running" & @CRLF)
EndFunc   ;==>Script_1

Func Script_2()
    ConsoleWrite("Script_2 running" & @CRLF)
EndFunc   ;==>Script_2

Func _GetActive()
    $hCurrent = WinGetHandle("[ACTIVE]")
    ; Are there are dialogs to check?
    If UBound($mDialog) Then
        For $vKey In MapKeys($mDialog)
            If $hCurrent <> $mDialog[$vKey] Then
                $gActiveWin = $hCurrent
            EndIf
        Next
    Else
        ; If not then change current
        $gActiveWin = $hCurrent
    EndIf

EndFunc   ;==>_GetActive

Func _Dialog_Moved($hWnd, $iMsg, $wParam, $lParam)

    ; Reactivate the current window
    WinActivate($gActiveWin)

EndFunc   ;==>_Dialog_Moved

Func _CloseLast()

    ; If no dialog has been activated since the last deletion
    If $gLastDialog = 0 Then
        ; Set a dialog by default
        Local $aKeys = MapKeys($mDialog)
        If UBound($aKeys) Then
            $gLastDialog = $mDialog[$aKeys[0]]
        EndIf
    EndIf
    ; Delete the last active dialog
    Switch WinGetTitle($gLastDialog)
        Case "Script_6"
            _Delete_Script_6()
            $gLastDialog = 0
        Case "Script_7"
            _Delete_Script_7()
            $gLastDialog = 0
        Case "Script_8"
            _Delete_Script_8()
            $gLastDialog = 0
    EndSwitch

EndFunc

Func _Exit()

    If MapExists($mScript_6, "Dialog") Then
        IniWrite($gMyINI, "POS_Script_6", "x", WinGetPos($mScript_6["Dialog"])[0])
        IniWrite($gMyINI, "POS_Script_6", "y", WinGetPos($mScript_6["Dialog"])[1])
    EndIf
    If MapExists($mScript_8, "Dialog") Then
        IniWrite($gMyINI, "POS_Script_8", "x", WinGetPos($mScript_8["Dialog"])[0])
        IniWrite($gMyINI, "POS_Script_8", "y", WinGetPos($mScript_8["Dialog"])[1])
    EndIf
    If MapExists($mScript_7, "Dialog") Then
        IniWrite($gMyINI, "POS_Script_7", "x", WinGetPos($mScript_7["Dialog"])[0])
        IniWrite($gMyINI, "POS_Script_7", "y", WinGetPos($mScript_7["Dialog"])[1])
    EndIf
    Exit
EndFunc   ;==>_Exit
I am not interested in developing the script further, so please do not ask for any further functionality - and if you want to produce another way of skinning this particular cat, please open another thread to do so. ;)

M23

Public_Domain.png.2d871819fcb9957cf44f4514551a2935.png Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind

Open spoiler to see my UDFs:

Spoiler

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

 

Link to comment
Share on other sites

  • 2 months later...

Return to previous active window?

Keep it simple:

; Activate previous window
Send("!{ESC}") ; back to previous window.
Sleep(1000)
Send("!{ESC}") ; back to pre-previous window.
Sleep(1000)
Send("!+{ESC}") ; forward to previous window.
Sleep(1000)
Send("!+{ESC}") ; forward to "current" window.

Alt+ESC shows previous window in Z-order.

Shift+Alt+ESC shows next window in Z-order.

App: Au3toCmd              UDF: _SingleScript()                             

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

×
×
  • Create New...