Jump to content

Maintain Focus on Parent GUI


 Share

Recommended Posts

I've looked around, but can't find what I'm looking for.  I'm creating a main parent GUI window, with 3 embedded child GUI windows, similar to the following code:

 

; Include files
#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>

; Autoit Options
Opt ("GUIOnEventMode", 1)

; GUI variables
$mainGUI = Null
$topGUI = Null
$rightGUI = Null
$leftGUI = Null

; Initialize GUI
guiInit ()

While 1
   Sleep (10)
WEnd

Func guiInit ()
   ; Create Main GUI
   $mainGUI = GUICreate ("Main Window", 600, 600)

   ; Child GUI for top row
   $topGUI = GUICreate ("", 600, 50, 0, 0, $WS_POPUP, $WS_EX_MDICHILD, $mainGUI)
   GUISetBkColor (0x0000FF, $topGUI)

   ; Child GUI for left side
   ;    contains row labels and fields
   $leftGUI = GUICreate ("", 300, 550, 0, 50, $WS_POPUP, $WS_EX_MDICHILD, $mainGUI)
   GUISetBkColor (0x00FF00, $leftGUI)

   ; Child GUI for right side
   $rightGUI = GUICreate ("", 300, 550, 300, 50, $WS_POPUP, $WS_EX_MDICHILD, $mainGUI)
   GUISetBkColor (0xFF0000, $rightGUI)

   ; Main GUI events
   GUISetOnEvent ($GUI_EVENT_CLOSE, "close", $mainGUI)
   GUISetOnEvent ($GUI_EVENT_CLOSE, "close", $topGUI)
   GUISetOnEvent ($GUI_EVENT_CLOSE, "close", $leftGUI)
   GUISetOnEvent ($GUI_EVENT_CLOSE, "close", $rightGUI)

   ; Show GUIs
   GUISetState (@SW_SHOW, $topGUI)
   GUISetState (@SW_SHOW, $leftGUI)
   GUISetState (@SW_SHOW, $rightGUI)
   GUISetState (@SW_SHOW, $mainGUI)

   ;GUISetState (@SW_DISABLE, $topGUI)
   ;GUISetState (@SW_DISABLE, $leftGUI)
   ;GUISetState (@SW_DISABLE, $rightGUI)
EndFunc

Func close ()
   Exit
EndFunc

 

The problem is the focus.  If I click on any of the child windows, the main window loses focus and the title bar is greyed out.  Maybe I'm a bit picky, but I don't like this behavior.

One way around this has been to disable the child GUIs (which is fine since I don't need to access them directly) then the main GUI will never lose focus.  The problem with this solution is that if the window itself loses focus (like clicking on another window), the only way to regain focus (with the mouse) is to click on the title bar.  Clicking on any of the child GUI windows will do nothing.

Any ideas?

D1Spartan

Edited by D1Spartan
Link to comment
Share on other sites

  • Moderators

D1Spartan,

Add this in your idle loop:

Switch _WinAPI_GetFocus()
    Case $topGUI, $rightGUI, $leftGUI
        WinActivate($mainGUI)
EndSwitch

You will also need #include <WinAPI.au3> at the top of the script. Now whenever one of the child GUIs gets focus, is it automatically transferred to the main GUI.

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

If it's something to do with forms then there's probably a window message for it :)

; Include files
#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>

; Autoit Options
Opt ("GUIOnEventMode", 1)

; GUI variables
$mainGUI = Null
$topGUI = Null
$rightGUI = Null
$leftGUI = Null

; Initialize GUI
guiInit ()

While 1
   Sleep (10)
WEnd

Func guiInit ()
   ; Create Main GUI
   $mainGUI = GUICreate ("Main Window", 600, 600)

   ; Child GUI for top row
   $topGUI = GUICreate ("Top GUI", 600, 50, 0, 0, $WS_POPUP, $WS_EX_MDICHILD, $mainGUI)
   GUISetBkColor (0x0000FF, $topGUI)

   ; Child GUI for left side
   ;    contains row labels and fields
   $leftGUI = GUICreate ("Left GUI", 300, 550, 0, 50, $WS_POPUP, $WS_EX_MDICHILD, $mainGUI)
   GUISetBkColor (0x00FF00, $leftGUI)

   ; Child GUI for right side
   $rightGUI = GUICreate ("Right GUI", 300, 550, 300, 50, $WS_POPUP, $WS_EX_MDICHILD, $mainGUI)
   GUISetBkColor (0xFF0000, $rightGUI)

   ; Main GUI events
   GUISetOnEvent ($GUI_EVENT_CLOSE, "close", $mainGUI)
   GUISetOnEvent ($GUI_EVENT_CLOSE, "close", $topGUI)
   GUISetOnEvent ($GUI_EVENT_CLOSE, "close", $leftGUI)
   GUISetOnEvent ($GUI_EVENT_CLOSE, "close", $rightGUI)

   ; Show GUIs
   GUISetState (@SW_SHOW, $topGUI)
   GUISetState (@SW_SHOW, $leftGUI)
   GUISetState (@SW_SHOW, $rightGUI)
   GUISetState (@SW_SHOW, $mainGUI)
   GUIRegisterMsg($WM_SETFOCUS, WM_SETFOCUS)

   ;GUISetState (@SW_DISABLE, $topGUI)
   ;GUISetState (@SW_DISABLE, $leftGUI)
   ;GUISetState (@SW_DISABLE, $rightGUI)
EndFunc

Func close ()
   Exit
EndFunc

Func WM_SETFOCUS($hWnd, $iMsg, $wParam, $lParam)
    If ($hWnd <> $mainGUI) Then
        ConsoleWrite("Window " & WinGetTitle($hWnd) & " was activated. Activating main" & @CRLF)
        WinActivate($mainGUI)
    EndIf
    Return $GUI_RUNDEFMSG
EndFunc

Also look into _WinApi_SetParent for your child windows. This will force windows OS to draw the childs inside the parent and get rid of the effect where all the windows minimize/restore separately.

Edited by InunoTaishou
Link to comment
Share on other sites

19 minutes ago, Valuater said:

Maybe...

 

While 1
   Sleep (10)
   WinActivate($mainGUI)
WEnd

8)

Won't work, since it will always activate the window, even if I switch to another window (that's even more annoying).

 

11 minutes ago, Melba23 said:

D1Spartan,

Add this in your idle loop:

Switch _WinAPI_GetFocus()
    Case $topGUI, $rightGUI, $leftGUI
        WinActivate($mainGUI)
EndSwitch

You will also need #include <WinAPI.au3> at the top of the script. Now whenever one of the child GUIs gets focus, is it automatically transferred to the main GUI.

M23

This seems at first glance to be the best option for my problem.  However, as soon as you add a control to one of the child GUIs, it no longer works.  Added a control and some debugging output to the console:

; Include files
#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
#include <WinAPI.au3>

; Autoit Options
Opt ("GUIOnEventMode", 1)

; GUI variables
$mainGUI = Null
$topGUI = Null
$rightGUI = Null
$leftGUI = Null

; Initialize GUI
$l = 0
guiInit ()

While 1
   Sleep (10)
   Switch _WinAPI_GetFocus ()
      Case $topGUI, $rightGUI, $leftGUI
         $l += 1
         ConsoleWrite ("Lost focus: " & $l & @CRLF)
         WinActivate($mainGUI)
   EndSwitch
WEnd

Func guiInit ()
   ; Create Main GUI
   $mainGUI = GUICreate ("Main Window", 600, 600)

   ; Child GUI for top row
   $topGUI = GUICreate ("", 600, 50, 0, 0, $WS_POPUP, $WS_EX_MDICHILD, $mainGUI)
   GUISetBkColor (0x0000FF, $topGUI)

   ; Child GUI for left side
   ;    contains row labels and fields
   $leftGUI = GUICreate ("", 300, 550, 0, 50, $WS_POPUP, $WS_EX_MDICHILD, $mainGUI)
   GUISetBkColor (0x00FF00, $leftGUI)

   ; Adding control to left side
   GUICtrlCreateButton ("Test", 10, 10)

   ; Child GUI for right side
   $rightGUI = GUICreate ("", 300, 550, 300, 50, $WS_POPUP, $WS_EX_MDICHILD, $mainGUI)
   GUISetBkColor (0xFF0000, $rightGUI)

   ; Main GUI events
   GUISetOnEvent ($GUI_EVENT_CLOSE, "close", $mainGUI)
   GUISetOnEvent ($GUI_EVENT_CLOSE, "close", $topGUI)
   GUISetOnEvent ($GUI_EVENT_CLOSE, "close", $leftGUI)
   GUISetOnEvent ($GUI_EVENT_CLOSE, "close", $rightGUI)

   ; Show GUIs
   GUISetState (@SW_SHOW, $topGUI)
   GUISetState (@SW_SHOW, $leftGUI)
   GUISetState (@SW_SHOW, $rightGUI)
   GUISetState (@SW_SHOW, $mainGUI)

   ;GUISetState (@SW_DISABLE, $topGUI)
   ;GUISetState (@SW_DISABLE, $leftGUI)
   ;GUISetState (@SW_DISABLE, $rightGUI)
EndFunc

Func close ()
   Exit
EndFunc

 

 

13 minutes ago, InunoTaishou said:

If it's something to do with forms then there's probably a window message for it :)

; Include files
#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>

; Autoit Options
Opt ("GUIOnEventMode", 1)

; GUI variables
$mainGUI = Null
$topGUI = Null
$rightGUI = Null
$leftGUI = Null

; Initialize GUI
guiInit ()

While 1
   Sleep (10)
WEnd

Func guiInit ()
   ; Create Main GUI
   $mainGUI = GUICreate ("Main Window", 600, 600)

   ; Child GUI for top row
   $topGUI = GUICreate ("Top GUI", 600, 50, 0, 0, $WS_POPUP, $WS_EX_MDICHILD, $mainGUI)
   GUISetBkColor (0x0000FF, $topGUI)

   ; Child GUI for left side
   ;    contains row labels and fields
   $leftGUI = GUICreate ("Left GUI", 300, 550, 0, 50, $WS_POPUP, $WS_EX_MDICHILD, $mainGUI)
   GUISetBkColor (0x00FF00, $leftGUI)

   ; Child GUI for right side
   $rightGUI = GUICreate ("Right GUI", 300, 550, 300, 50, $WS_POPUP, $WS_EX_MDICHILD, $mainGUI)
   GUISetBkColor (0xFF0000, $rightGUI)

   ; Main GUI events
   GUISetOnEvent ($GUI_EVENT_CLOSE, "close", $mainGUI)
   GUISetOnEvent ($GUI_EVENT_CLOSE, "close", $topGUI)
   GUISetOnEvent ($GUI_EVENT_CLOSE, "close", $leftGUI)
   GUISetOnEvent ($GUI_EVENT_CLOSE, "close", $rightGUI)

   ; Show GUIs
   GUISetState (@SW_SHOW, $topGUI)
   GUISetState (@SW_SHOW, $leftGUI)
   GUISetState (@SW_SHOW, $rightGUI)
   GUISetState (@SW_SHOW, $mainGUI)
   GUIRegisterMsg($WM_SETFOCUS, WM_SETFOCUS)

   ;GUISetState (@SW_DISABLE, $topGUI)
   ;GUISetState (@SW_DISABLE, $leftGUI)
   ;GUISetState (@SW_DISABLE, $rightGUI)
EndFunc

Func close ()
   Exit
EndFunc

Func WM_SETFOCUS($hWnd, $iMsg, $wParam, $lParam)
    If ($hWnd <> $mainGUI) Then
        ConsoleWrite("Window " & WinGetTitle($hWnd) & " was activated. Activating main" & @CRLF)
        WinActivate($mainGUI)
    EndIf
    Return $GUI_RUNDEFMSG
EndFunc

Also look into _WinApi_SetParent for your child windows. This will force windows OS to draw the childs inside the parent and get rid of the effect where all the windows minimize/restore separately.

Trying this as-is produces a weird slow-load of the child GUIs.  Not sure why, but doesn't seem to be affected by removing the ConsoleWrite functions.  I do like the suggestion about  _WinApi_SetParent though, I'll look into that.

 

Thank you all for your suggestions, I'll see what I can find.

Link to comment
Share on other sites

20 minutes ago, mikell said:

Also...

GUISetOnEvent ($GUI_EVENT_PRIMARYDOWN, "_focus", $topGUI)
GUISetOnEvent ($GUI_EVENT_PRIMARYDOWN, "_focus", $leftGUI)
GUISetOnEvent ($GUI_EVENT_PRIMARYDOWN, "_focus", $rightGUI)

Func _focus()
   WinActivate($mainGUI)
EndFunc

 

I tried that as well, but it creates a weird "flash" of the title bar occasionally.  It's funny, but my code was identical except the function was "focus".

Link to comment
Share on other sites

  • Moderators

D1Spartan,

I know I had seen this solved somewhere:

; Include files
#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
#include <MsgBoxConstants.au3>

; Autoit Options
Opt("GUIOnEventMode", 1)

; GUI variables
$mainGUI = Null
$topGUI = Null
$rightGUI = Null
$leftGUI = Null

; Initialize GUI
guiInit()

While 1
    Sleep(10)
WEnd

Func guiInit()
    ; Create Main GUI
    $mainGUI = GUICreate("Main Window", 600, 600)

    ; Child GUI for top row
    $topGUI = GUICreate("", 600, 50, 0, 0, $WS_POPUP, $WS_EX_MDICHILD, $mainGUI)
    GUISetBkColor(0x0000FF, $topGUI)

    ; Child GUI for left side
    ;    contains row labels and fields
    $leftGUI = GUICreate("", 300, 550, 0, 50, $WS_POPUP, $WS_EX_MDICHILD, $mainGUI)

    $cButton = GUICtrlCreateButton("Test", 50, 50, 80, 30)
    GUICtrlSetOnEvent($cButton, "_Test")

    GUISetBkColor(0x00FF00, $leftGUI)

    ; Child GUI for right side
    $rightGUI = GUICreate("", 300, 550, 300, 50, $WS_POPUP, $WS_EX_MDICHILD, $mainGUI)
    GUISetBkColor(0xFF0000, $rightGUI)

    ; Main GUI events
    GUISetOnEvent($GUI_EVENT_CLOSE, "close", $mainGUI)
    GUISetOnEvent($GUI_EVENT_CLOSE, "close", $topGUI)
    GUISetOnEvent($GUI_EVENT_CLOSE, "close", $leftGUI)
    GUISetOnEvent($GUI_EVENT_CLOSE, "close", $rightGUI)

    ; Show GUIs
    GUISetState(@SW_SHOW, $topGUI)
    GUISetState(@SW_SHOW, $leftGUI)
    GUISetState(@SW_SHOW, $rightGUI)
    GUISetState(@SW_SHOW, $mainGUI)

    GUIRegisterMsg( $WM_NCACTIVATE, "_WM_NCACTIVATE")

EndFunc   ;==>guiInit

Func _Test()
    MsgBox($MB_SYSTEMMODAL, "Hi", "Pressed")
EndFunc   ;==>_Test

Func close()
    Exit
EndFunc   ;==>close

Func _WM_NCACTIVATE( $hWnd, $iMsg, $wParam, $lParam)
  If $hWnd = $mainGUI Then
    If Not $wParam Then Return 1
  EndIf
  Return $GUI_RUNDEFMSG
EndFunc

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

13 minutes ago, Melba23 said:

D1Spartan,

I know I had seen this solved somewhere:

; Include files
#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
#include <MsgBoxConstants.au3>

; Autoit Options
Opt("GUIOnEventMode", 1)

; GUI variables
$mainGUI = Null
$topGUI = Null
$rightGUI = Null
$leftGUI = Null

; Initialize GUI
guiInit()

While 1
    Sleep(10)
WEnd

Func guiInit()
    ; Create Main GUI
    $mainGUI = GUICreate("Main Window", 600, 600)

    ; Child GUI for top row
    $topGUI = GUICreate("", 600, 50, 0, 0, $WS_POPUP, $WS_EX_MDICHILD, $mainGUI)
    GUISetBkColor(0x0000FF, $topGUI)

    ; Child GUI for left side
    ;    contains row labels and fields
    $leftGUI = GUICreate("", 300, 550, 0, 50, $WS_POPUP, $WS_EX_MDICHILD, $mainGUI)

    $cButton = GUICtrlCreateButton("Test", 50, 50, 80, 30)
    GUICtrlSetOnEvent($cButton, "_Test")

    GUISetBkColor(0x00FF00, $leftGUI)

    ; Child GUI for right side
    $rightGUI = GUICreate("", 300, 550, 300, 50, $WS_POPUP, $WS_EX_MDICHILD, $mainGUI)
    GUISetBkColor(0xFF0000, $rightGUI)

    ; Main GUI events
    GUISetOnEvent($GUI_EVENT_CLOSE, "close", $mainGUI)
    GUISetOnEvent($GUI_EVENT_CLOSE, "close", $topGUI)
    GUISetOnEvent($GUI_EVENT_CLOSE, "close", $leftGUI)
    GUISetOnEvent($GUI_EVENT_CLOSE, "close", $rightGUI)

    ; Show GUIs
    GUISetState(@SW_SHOW, $topGUI)
    GUISetState(@SW_SHOW, $leftGUI)
    GUISetState(@SW_SHOW, $rightGUI)
    GUISetState(@SW_SHOW, $mainGUI)

    GUIRegisterMsg( $WM_NCACTIVATE, "_WM_NCACTIVATE")

EndFunc   ;==>guiInit

Func _Test()
    MsgBox($MB_SYSTEMMODAL, "Hi", "Pressed")
EndFunc   ;==>_Test

Func close()
    Exit
EndFunc   ;==>close

Func _WM_NCACTIVATE( $hWnd, $iMsg, $wParam, $lParam)
  If $hWnd = $mainGUI Then
    If Not $wParam Then Return 1
  EndIf
  Return $GUI_RUNDEFMSG
EndFunc

M23

So close to being the perfect solution.  When you navigate to another window, the title bar stays "active".  However, I'll take it.  This works for me.  Thanks Melba, and everyone who gave me their ideas.

Link to comment
Share on other sites

  • Moderators

D1Spartan,

Quote

So close to being the perfect solution

Talk about fussy......

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

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...