Jump to content

Attaching a GUI to Another Window


Affe
 Share

Recommended Posts

I'm looking for a way to attach a GUI to another non-autoit window in a way that when I move the non-autoit window, the GUI moves with it, when I minimize the non-autoit window, the GUI minimizes with it, etc., as if it were built into the window itself.

I'm currently using a function through AdLibRegister to move, hide, and show the window, but it is slow to hide/show and the window movement can be choppy and slow.

Is there any way to do this that would make for a more "natural" display?

This is what I'm currently using:

Func WatchWindow()
    If WinActive($NONAutoItTitle) Then
        WinSetState($GUITitle, "", @SW_SHOW)
        Sleep(10)
    ElseIf WinExists($NONAutoItTitle) = 0 Then
        MsgBox(4096, "Window Closed", "The Parent window has closed and the application will exit", 60)
        Exit 1
    Else
        If WinActive($GUITitle) Then Return
        WinSetState($GUITitle, "", @SW_HIDE)
    EndIf

    $pos = WinGetPos($NONAutoItTitle)
    WinMove($GUITitle, "", $pos[0] + $Triangle[0] - 5, $pos[1] + $Triangle[1] + 130)
EndFunc   ;==>WatchWindow
Edited by Affe

[center][/center]

Link to comment
Share on other sites

  • Moderators

Affe,

Looks pretty close to what I use: ;)

Func _GUI_Match()

    ; If NonAutoItApp minimised, then hide GUI and do nothing
    If BitAND(WinGetState($hNonAutoItApp_Wnd), 16) = 16 Then
        GUISetState(@SW_HIDE, $hGUI)
        $fGUI_Vis = False
    ; If NonAutoItApp not minimised
    Else
        ; Hide GUI when NonAutoItApp not active
        If BitAND(WinGetState($hNonAutoItApp_Wnd), 8) <> 8 And $fGUI_Vis = True Then
            GUISetState(@SW_HIDE, $hGUI)
            $fGUI_Vis = False
        ; Show GUI when it is
        ElseIf BitAND(WinGetState($hNonAutoItApp_Wnd), 8) = 8 And $fGUI_Vis = False Then
            GUISetState(@SW_SHOWNOACTIVATE, $hGUI)
            $fGUI_Vis = True
        EndIf
        ; If visible check GUI position
        If $fGUI_Vis = True Then
            ; Move if required
            Local $aNonAutoItApp_Pos = WinGetPos($hNonAutoItApp_Wnd)
            If $aNonAutoItApp_Pos[0] <> $iLast_X Or $aNonAutoItApp_Pos[1] <> $iLast_Y Then
                $iLast_X = $aNonAutoItApp_Pos[0]
                $iLast_Y = $aNonAutoItApp_Pos[1]
                Local $aNonAutoItApp_Client_Size = WinGetClientSize($hNonAutoItApp_Wnd)
                WinMove($hGUI, '', $aNonAutoItApp_Pos[0] + 360, $aNonAutoItApp_Pos[1] + ($aNonAutoItApp_Pos[3] - $aNonAutoItApp_Client_Size[1]) - 5, $iGUI_Width, 18)
            EndIf           
        EndIf
    EndIf

EndFunc      ;==>_GUI_Match

But then I do not move the app I have attached to very much, so the "choppiness" is not that much of a problem.

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

Another way of attaching an autoit window to a non-autoit window, at least for minimize/restore would be to make the GUI a child window of the window you want to attach to using something like this:

$Form1 = GUICreate("Attached window!", 629, 437, 314, 132, default,default, WinGetHandle("AutoIt Help"))

I used the AutoIt help window in this example but it should work for any window. You will still have to use M23's code to move it with the attached window, but this way eliminates checking the state of the window. Seeing as how you can't move a window when it's minimized it should eliminate a bit of code checking.

If I posted any code, assume that code was written using the latest release version unless stated otherwise. Also, if it doesn't work on XP I can't help with that because I don't have access to XP, and I'm not going to.
Give a programmer the correct code and he can do his work for a day. Teach a programmer to debug and he can do his work for a lifetime - by Chirag Gude
How to ask questions the smart way!

I hereby grant any person the right to use any code I post, that I am the original author of, on the autoitscript.com forums, unless I've specifically stated otherwise in the code or the thread post. If you do use my code all I ask, as a courtesy, is to make note of where you got it from.

Back up and restore Windows user files _Array.au3 - Modified array functions that include support for 2D arrays.  -  ColorChooser - An add-on for SciTE that pops up a color dialog so you can select and paste a color code into a script.  -  Customizable Splashscreen GUI w/Progress Bar - Create a custom "splash screen" GUI with a progress bar and custom label.  -  _FileGetProperty - Retrieve the properties of a file  -  SciTE Toolbar - A toolbar demo for use with the SciTE editor  -  GUIRegisterMsg demo - Demo script to show how to use the Windows messages to interact with controls and your GUI.  -   Latin Square password generator

Link to comment
Share on other sites

I use something like this in one of my programs:

Global Const $WM_MOVING = 0x0216
Global Const $WM_EXITSIZEMOVE = 0x0232
GUIRegisterMsg($WM_MOVING, 'On_WM_MOVING')
GUIRegisterMsg($WM_EXITSIZEMOVE, "On_WM_EXITSIZEMOVE")

Func On_WM_MOVING($hWnd, $Msg, $wParam, $lParam)
    If $hWnd = $gui_main Then _Move_attached_GUIs()
    Return $GUI_RUNDEFMSG
EndFunc   ;==>On_WM_MOVING

Func On_WM_EXITSIZEMOVE($hWnd, $Msg, $wParam, $lParam)
    If $hWnd <> $gui_main Then _Move_attached_GUIs()
    Return $GUI_RUNDEFMSG
EndFunc   ;==>On_WM_EXITSIZEMOVE
Link to comment
Share on other sites

BrewManNH brought up a nice idea...

$Form1 = GUICreate("Attached window!", 629, 437, 314, 132, default,default, WinGetHandle("AutoIt Help"))

But what I wonder... imagine two separate programs, one helper-program monitoring the other. If the main app crashes, it is restarted by the helper. If I now link them with this window parent<>child relationship, wouldn't a crash of the main program not also stall the child (same winproc)?

Link to comment
Share on other sites

Thanks for the replies ;)

@Melba, am I correct to assume that $fGUI_Vis is a global variable?

@BrewManNH, awesome, thanks for that!

@KaFu, do you happen to have the code for your _Move_attached_GUIs() function? I'm just curious if it would be smoother than a WinMove()

[center][/center]

Link to comment
Share on other sites

But what I wonder... imagine two separate programs, one helper-program monitoring the other. If the main app crashes, it is restarted by the helper. If I now link them with this window parent<>child relationship, wouldn't a crash of the main program not also stall the child (same winproc)?

If you use the child window to restart the Parent window, you can always use the same script to restart the child window GUI and reattach it. Put the child window GUI into a function, and just exit the function, do the restart of the Parent application, and then call the Child window function again. You can always use a GUIDelete on the previous child window prior to exiting its function.

====EDIT=====

I don't know if it's different for a crash as it is for just closing a window, but closing the help file window when the gui was attached to it didn't cause any problems for the child window application that I tried it with.

Edited by BrewManNH

If I posted any code, assume that code was written using the latest release version unless stated otherwise. Also, if it doesn't work on XP I can't help with that because I don't have access to XP, and I'm not going to.
Give a programmer the correct code and he can do his work for a day. Teach a programmer to debug and he can do his work for a lifetime - by Chirag Gude
How to ask questions the smart way!

I hereby grant any person the right to use any code I post, that I am the original author of, on the autoitscript.com forums, unless I've specifically stated otherwise in the code or the thread post. If you do use my code all I ask, as a courtesy, is to make note of where you got it from.

Back up and restore Windows user files _Array.au3 - Modified array functions that include support for 2D arrays.  -  ColorChooser - An add-on for SciTE that pops up a color dialog so you can select and paste a color code into a script.  -  Customizable Splashscreen GUI w/Progress Bar - Create a custom "splash screen" GUI with a progress bar and custom label.  -  _FileGetProperty - Retrieve the properties of a file  -  SciTE Toolbar - A toolbar demo for use with the SciTE editor  -  GUIRegisterMsg demo - Demo script to show how to use the Windows messages to interact with controls and your GUI.  -   Latin Square password generator

Link to comment
Share on other sites

Link to comment
Share on other sites

Not child window and Parent window, but child application and parent application, two separate exes, one monitoring the other for crashs. I fear attaching the child (monitor) window to the main app window will crash that too if the main crashs.

Link to comment
Share on other sites

If the 2 applications are running in separate executables, the parent<->child relationship shouldn't affect the other window unless one or the other will only operate if they are both running and can't restart the other program or itself. If I start ApplicationA and that starts ApplicationB, if the 2 programs are written correctly, then A or B crashing shouldn't cause the other to crash.

If I posted any code, assume that code was written using the latest release version unless stated otherwise. Also, if it doesn't work on XP I can't help with that because I don't have access to XP, and I'm not going to.
Give a programmer the correct code and he can do his work for a day. Teach a programmer to debug and he can do his work for a lifetime - by Chirag Gude
How to ask questions the smart way!

I hereby grant any person the right to use any code I post, that I am the original author of, on the autoitscript.com forums, unless I've specifically stated otherwise in the code or the thread post. If you do use my code all I ask, as a courtesy, is to make note of where you got it from.

Back up and restore Windows user files _Array.au3 - Modified array functions that include support for 2D arrays.  -  ColorChooser - An add-on for SciTE that pops up a color dialog so you can select and paste a color code into a script.  -  Customizable Splashscreen GUI w/Progress Bar - Create a custom "splash screen" GUI with a progress bar and custom label.  -  _FileGetProperty - Retrieve the properties of a file  -  SciTE Toolbar - A toolbar demo for use with the SciTE editor  -  GUIRegisterMsg demo - Demo script to show how to use the Windows messages to interact with controls and your GUI.  -   Latin Square password generator

Link to comment
Share on other sites

  • Moderators

Affe,

am I correct to assume that $fGUI_Vis is a global variable?

It must be so that it is always a the correct value when the function is called. You could use a STATIC variable here (a perfect opprtunity!) but as that is still experimental, I would stick with GLOBAL. :)

But wait a moment...

BrewManNH,

Nice thought about the parent parameter. ;)

I wrote that code a long time ago and I have spent the past half hour playing with your idea. I have also been looking into using the z-order to keep the AutoIt GUI visible at all times rather than hiding/showing it as the NonAutoIt GUI gains/loses focus. I originally had the AutoIt app with the TOPMOST style set to keep it on top of the NonAutoIt app (it is a additional toolbar) and needed the hide/show code to prevent it from overlaying other apps on screen when the NonAutoit was not activated. This is what I have come up with so far:

; Creation
$hToolBar = GUICreate("ToolBar", 400, 18, 360, 5, $WS_POPUP, $WS_EX_TOOLWINDOW, $hNonAutoIt_Wnd)

; Control creation code

GUISetState(@SW_SHOWNOACTIVATE, $hToolBar)

; This is the _WinAPI_SetWindowPos function to put the toolbar just above the NonAutoIt app in the z-order
DllCall("user32.dll", "bool", "SetWindowPos", "hwnd", $hToolBar, "hwnd", $hNonAutoIt_Wnd, "int", 10, "int", 10, "int", $iToolbar_Width, "int", 18, "uint", 0x0010) ; $SWP_NOACTIVATE

That removes any need for the complicated "minimized/active" code, all that remains is the "; Move if required" section.

Kafu,

I like the idea of the message handler to look for the NonAutoIt app moving - looks like I have another little project for this evening! ;)

All,

I do enjoy the free exchange of ideas around here - such a pleasure to learn new things every day! :shocked:

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

the parent<->child relationship shouldn't affect the other window unless one

And thats what I'm not sure about. Doesn't setting the relationship connect both windows message queue? So that if one crashes, the other one will idle out because it does not receive WMs anymore? Hmmmm, I guess I have to create a crashing program to test that out ;)...

I like the idea of the message handler to look for the NonAutoIt app moving - looks like I have another little project for this evening! ;)

Above code only works for the scripts own windows, don't know if you could hook into NonAutoIt apps, but might work with hook.dll... see your own example on wm_command :)...
Link to comment
Share on other sites

Hmmmm, I guess I have to create a crashing program to test that out :)...

I have a ton of those ;)

If I posted any code, assume that code was written using the latest release version unless stated otherwise. Also, if it doesn't work on XP I can't help with that because I don't have access to XP, and I'm not going to.
Give a programmer the correct code and he can do his work for a day. Teach a programmer to debug and he can do his work for a lifetime - by Chirag Gude
How to ask questions the smart way!

I hereby grant any person the right to use any code I post, that I am the original author of, on the autoitscript.com forums, unless I've specifically stated otherwise in the code or the thread post. If you do use my code all I ask, as a courtesy, is to make note of where you got it from.

Back up and restore Windows user files _Array.au3 - Modified array functions that include support for 2D arrays.  -  ColorChooser - An add-on for SciTE that pops up a color dialog so you can select and paste a color code into a script.  -  Customizable Splashscreen GUI w/Progress Bar - Create a custom "splash screen" GUI with a progress bar and custom label.  -  _FileGetProperty - Retrieve the properties of a file  -  SciTE Toolbar - A toolbar demo for use with the SciTE editor  -  GUIRegisterMsg demo - Demo script to show how to use the Windows messages to interact with controls and your GUI.  -   Latin Square password generator

Link to comment
Share on other sites

Decided to remove the entire thing as an AdLibRegister since it was slowing down the program.

Instead, I made a separate peripheral program to do this for me. Dramatically boosts performance of the main program and improves the performance of the window mover itself.

Now I call it from the main program with:

;Run the window watching program
Global $watchprog = Run(@ScriptDir & "\Tools\Watch.exe " & $GUITitle & " " & $win & " " & WinGetProcess($GUITitle) & " " & $Triangle[0] & " " & $Triangle[1])
;Let's keep this here in case some idiot deletes the watcher file
If $watchprog = 0 Then AdlibRegister("WatchWindow", 750)

And here is the code for Watch.exe:

Opt("WinTitleMatchMode", 3)
Opt("TrayIconHide", 1)

If $CmdLine[0] <= 0 Then Exit

Global $GUITitle = $CmdLine[1]
Global $ParentTitle = $CmdLine[2]
Global $process = $CmdLine[3]
Global $T1 = $CmdLine[4] ;this is a x offset
Global $T2 = $CmdLine[5] ;this is a y offset
Global $ParentHandle

GetWindow()

While 1
    WatchWindow()
    Sleep(50)
WEnd

Func GetWindow()
    $winlist = WinList($ParentTitle)
    If $winlist[0] > 0 Then
        For $x = 0 to UBound($winlist) - 1
            If StringLen($winlist[$x]) = 3 Then
                $ParentHandle = WinGetHandle($winlist[$x])
                ExitLoop
            EndIf
        Next
        Exit 1
    Exit
EndFunc

Func WatchWindow()
    $pos = WinGetPos($ParentHandle)

    If WinActive($ParentHandle) Then
;~      If WinGetState($GUITitle) >= 0 Then WinSetState($GUITitle, "", @SW_SHOW)
        Sleep(10)
    ElseIf WinExists($ParentHandle) = 0 Then
        MsgBox(4096, "Closed", "Parent window has closed and will now quit.", 60)
        ProcessClose($process)
        Exit 1
    Else
        If WinActive($GUITitle) Then Return
;~      If WinGetState($ParentTitle) > 2 Then WinSetState($GUITitle, "", @SW_HIDE)
    EndIf

    ;Set Z Order
    ; This is the _WinAPI_SetWindowPos function to put the toolbar just above the NonAutoIt app in the z-order
    DllCall("user32.dll", "bool", "SetWindowPos", "hwnd", $GUITitle, "hwnd", $ParentHandle, "int", $pos[0] + $T1 - 5, "int", $pos[1] + $T2 + 130, "int", 200, "int", 200, "uint", 0x0010) ; $SWP_NOACTIVATE
;~  Sleep(10)
    WinMove($GUITitle, "", $pos[0] + $T1 - 5, $pos[1] + $T2 + 130)

EndFunc   ;==>WatchWindow

On a side note, the option WinTitleMatchMode doesn't seem to work with the option 3 (exact match). It will return partial matches (example, I have a window open named Watch, and a window opened named Watcher. WinList("Watch") will return both Watch and Watcher, and WinGetPos("Watch") also has a chance of falsely returning Watcher's position)

Edited by Affe

[center][/center]

Link to comment
Share on other sites

  • Moderators

Affe,

I am not sure you need the API call each time you move the window. I use it just the once after creating the AutoIt GUI to get it into the correct place in the z-order. From then on I use a simple WinMove to keep it in the same place. You should only ever need to reuse the API call if some other app completely changes the existing z-order - most of the apps that do anything to it just push themselves to the top of the list leaving the underneath GUIs in the same order. ;)

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

  • Moderators

I haven't seen code from the op that suggests this one way or the other, so I thought I'd ask.

Are you trying to embed the autoit gui into the non-window gui? If so, you may want to look at _WinAPI_GetWindowLong/_WinAPI_SetWindowLong

Common sense plays a role in the basics of understanding AutoIt... If you're lacking in that, do us all a favor, and step away from the computer.

Link to comment
Share on other sites

@Melba, I'll change it so that it doesn't get called all the time. I was unaware ;) Thanks!

I haven't seen code from the op that suggests this one way or the other, so I thought I'd ask.

Are you trying to embed the autoit gui into the non-window gui? If so, you may want to look at _WinAPI_GetWindowLong/_WinAPI_SetWindowLong

Yes, that's what I'm trying to do, so that it shows up in a way that it looks layered on top of the other window. The Parent/Child method worked great for the minimize/maximize, but currently the WinMove() works, but doesn't look "professional". I'm not sure if that makes any sense, so I hope you're able to make something of it :)

Do you happen to have a link or something to help me understand the method you are referring to? If not, I'll google, but hoping you can save me the time of wading through the junk if you have a link handy ;)

[center][/center]

Link to comment
Share on other sites

  • Moderators

@Melba, I'll change it so that it doesn't get called all the time. I was unaware ;) Thanks!

Yes, that's what I'm trying to do, so that it shows up in a way that it looks layered on top of the other window. The Parent/Child method worked great for the minimize/maximize, but currently the WinMove() works, but doesn't look "professional". I'm not sure if that makes any sense, so I hope you're able to make something of it :)

Do you happen to have a link or something to help me understand the method you are referring to? If not, I'll google, but hoping you can save me the time of wading through the junk if you have a link handy ;)

I have code somewhere that provides an example. If I find the link I'll post in this post.

Edit:

I couldn't find the code I used, but I remembered something called "AnyGUI" from years ago.

Anyway, I don't know if it still works, but if you look at the AnyGUI.au3, worse case, you can see how to handle it.

This way you won't need to worry about moving the gui/control, it will be embedded in the window itself.

http://www.autoitscript.com/forum/index.php?showtopic=9517&view=findpost&p=638738

Edit 2:

After looking at it, it certainly could be written much better, but I think it will serve the needs you are wanting as it is.

Edited by SmOke_N

Common sense plays a role in the basics of understanding AutoIt... If you're lacking in that, do us all a favor, and step away from the computer.

Link to comment
Share on other sites

I have code somewhere that provides an example. If I find the link I'll post in this post.

Edit:

I couldn't find the code I used, but I remembered something called "AnyGUI" from years ago.

Anyway, I don't know if it still works, but if you look at the AnyGUI.au3, worse case, you can see how to handle it.

This way you won't need to worry about moving the gui/control, it will be embedded in the window itself.

http://www.autoitscript.com/forum/index.php?showtopic=9517&view=findpost&p=638738

Edit 2:

After looking at it, it certainly could be written much better, but I think it will serve the needs you are wanting as it is.

Thanks, that does certainly shed some light, however, it doesn't seem to work with the application I'm attaching to. I can see the GUI try to show up when I mouse over the area it should be (I have some dll function calls to highlight any text in the edit boxes for faster changes, and when that is called it tries to draw the GUI but is quickly erased by the application redrawing the window). I'm sure I can use this for something in the future though!

[center][/center]

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