Jump to content

Window Binding


Recommended Posts

Is there a dll or such that I can use to "bind"/"attach" a window to another.

Example: Exe is launched with GUI code in it, so we've got a window open now. A button in that "parent" window is clicked - boom - the "child" window is launched via a ShellExecute (which currently passes many params to the new window). How do I attach/bind the new window to the previous window as a "child."

I can explain more if need be, but this might convey all that is needed.

A decision is a powerful thing
Link to comment
Share on other sites

#include 

$parent = GUICreate("Hello World", 400, 400)
GUISetState()
GUICtrlCreateLabel("Hello world! How are you?", 30, 10)
$okbutton = GUICtrlCreateButton("OK", 70, 50, 60)

$child = GUICreate("Dummy window for testing ", 200, 100)
GUISetState()
GUISwitch($child)


While 1
  $msg = GUIGetMsg(1)

  Select
    Case $msg[0] = $okbutton
      MsgBox(0, "GUI Event", "You pressed OK!")

    Case $msg[0] = $GUI_EVENT_CLOSE And $msg[1] = $parent
      MsgBox(0, "GUI Event", "You clicked CLOSE on the parent window! Exiting...")
      ExitLoop
    
    Case $msg[0] = $GUI_EVENT_CLOSE And $msg[1] = $child
      MsgBox(0, "GUI Event", "You clicked CLOSE on the child window! Exiting...")
      ExitLoop
  EndSelect
WEnd

Link to comment
Share on other sites

Scripts & functions Organize Includes Let Scite organize the include files

Yahtzee The game "Yahtzee" (Kniffel, DiceLion)

LoginWrapper Secure scripts by adding a query (authentication)

_RunOnlyOnThis UDF Make sure that a script can only be executed on ... (Windows / HD / ...)

Internet-Café Server/Client Application Open CD, Start Browser, Lock remote client, etc.

MultipleFuncsWithOneHotkey Start different funcs by hitting one hotkey different times

Link to comment
Share on other sites

Mega, first thanks for that link. I like how he set that up as a udf. While that is close to what I want, that's not quiet it. I've been working with SetParent and on MSDN this morning trying to figure this out. The problem with SetParent is that it moves the child window :) I just want to attach the child window not move it or anything else. Maybe I should do some process threading of sorts.

A decision is a powerful thing
Link to comment
Share on other sites

It would be very difficult to share data between 2 running apps.

Well, I got that going on through a COM-of-sorts ($WM_COPYDATA). I can post that if it helps. However, I don't think so. Mainly I just want to have the window close when the parent window closes. I have the COM setup sending the window title of the new window to the "parent" window. The parent window has the title, but WinClose, doesn't close the child window. They aren't really parents or children in that scenario, so my way of doing it with COM is in sufficient.

A decision is a powerful thing
Link to comment
Share on other sites

Are you really using ShellExecute for the child?

Why not use Run() to get the PID of your child and close that process if it exists when your Parent GUI loop gets a close request????

#include 

GUICreate("My GUI")  ; will create a dialog box that when displayed is centered
GUISetState (@SW_SHOW)       ; will display an empty dialog box

$process = Run("notepad.exe")

; Run the GUI until the dialog is closed
While 1
    Switch GUIGetMsg()
        Case $GUI_EVENT_CLOSE
            If ProcessExists($process) Then
                ProcessClose ($process)
            EndIf
            ExitLoop
    EndSwitch
Wend
Link to comment
Share on other sites

Are you really using ShellExecute for the child?

Why not use Run() to get the PID of your child and close that process if it exists when your Parent GUI loop gets a close request????

Good idea about the PID! As for the really using ShellExecute :) yeah I am. I can send params to the "child" using ShellExecute. Maybe I can do that with run(), but I've just been using ShellExecute for that. I need to send about five to six params to the "child" on it's opening.

A decision is a powerful thing
Link to comment
Share on other sites

ok, so SetParent moves the window inside the "parent window." Well, that's no good for me. I want to bind the windows. So if the parent moves, so does the child move. I've got the closing method down (well, one that works anyway - it's not truly bound in that way nor are the processes treed). However, I'm still working on this moving issue. I can do WinGetPos, but that seems like a lot of code for something that seemingly could be done through dlls.

A decision is a powerful thing
Link to comment
Share on other sites

Doing this looks really bad if the user has "show content while dragging" and seems to suck up processor power

_KeepWindowsDocked is in the while loop

$childWinsArray is built through Data Interchanging between the AU3 exes.

Func _KeepWindowsDocked()
    $p_win1 = WinGetPos($ParentWin)
    For $kwd_Counter = 1 to UBound($childWinsArray)-1
        ;Assign('c_win'&$kwd_Counter,WinGetPos($childWinsArray[$kwd_Counter][0]))
        Local $c_winPosArray = WinGetPos($childWinsArray[$kwd_Counter][0])
        Local $moveX = $p_win1[0]+$p_win1[2]
        Local $moveY = $p_win1[1]
        WinMove($childWinsArray[$kwd_Counter][0],'',$moveX,$moveY)
    Next    
EndFunc  ;==>_KeepWindowsDocked
Edited by JohnBailey
A decision is a powerful thing
Link to comment
Share on other sites

Here, I did what you want. Not very clear on what you wanted so..

Thanks to gaFROST, MS Creator for the function.

Rest was created by me.

#include <GUIConstants.au3>

;Globals
Global $View = 0

;GUI SETUP
$hGUI = GUICreate("Parent", 620, 500, -1, -1)          ;- Main GUI Window
$okbutton = GUICtrlCreateButton("OK", 500, 450, 75)
$POS = WinGetPos($hGUI)

$Child  = GUICreate("Child", 425, 440, 0, 30, "", -1, $hGUI)

GUISetState(@SW_SHOW, $hGUI)
DllCall("user32.dll", "int", "SetParent", "hwnd", $Child, "hwnd", $hGUI)
GUISetState(@SW_HIDE, $Child)




;;Main loop
While 1
    $Msg = GUIGetMsg()
    Switch $Msg
  
    Case $okbutton
        Child()
    
Case $GUI_EVENT_CLOSE
            If WinActive($Child) Then
                GUISetState(@SW_HIDE, $Child)
            $View = 0
            Else
                Exit
            EndIf
 
    EndSwitch  
WEnd

;;Child funtion
Func Child()
If $View = 0 Then
WinSetState($Child, "", @SW_SHOW)
GUISwitch($Child)
GUISetState()
$View = 1
Else
$View = 0           
WinSetState($Child, "", @SW_HIDE)
GUISwitch($hGUI)
EndIf
EndFunc
Edited by Sardith

[font="Verdana"]Valik:Get it straight - I'm not here to say please, I'm here to help - if my help's not appreciated then lotsa luck, gentlemen.[/font]

Link to comment
Share on other sites

Here, I did what you want. Not very clear on what you wanted so..

This may just be an issue with my machine, but... When using SetParent, the child window is moved from it's original position and placed inside of the parent window.

Furthermore, I'm launching a separate process not a gui scripted into the original script. Imagine the parent script gui launches a secondary script with gui (eg. notepad). That secondary gui is needed to be attached to the side of the original/parent gui and move with it.

A decision is a powerful thing
Link to comment
Share on other sites

Here's a very crud example.

*NOTICE: the child window must be compiled and the location of the child window must be set in the parent script.

Parent

#include <GUIConstants.au3>

Global $ScriptLocation = '"I:\SAI\Auto-It files\Experiments"'

;GUI SETUP
Global $ParentWin_Title = "Parent"
$hGUI = GUICreate($ParentWin_Title, 620, 500, -1, -1)       ;- Main GUI Window
$okbutton = GUICtrlCreateButton("Launch Child", 500, 450, 75)
GUISetState(@SW_SHOW, $hGUI)

;;Main loop
While 1
    $Msg = GUIGetMsg()
    Switch $Msg
 
        Case $okbutton
        ;Run($ScriptLocation&"'\Win Binding Ex - Child.exe'",$ScriptLocation)
            $ParentWinPosArray = WinGetPos($ParentWin_Title);  $array[0] = X position, $array[1] = Y position, $array[2] = Width , $array[3] = Height 
            $thisParentTitletoSend = StringReplace($ParentWin_Title,' ','_')
            ShellExecute('"I:\SAI\Auto-It files\Experiments\Win Binding Ex - Child.exe"','Launched_from_Parent '&$thisParentTitletoSend &' '&$ParentWinPosArray[0]+$ParentWinPosArray[2]&' '&$ParentWinPosArray[1],$ScriptLocation)
        Case $GUI_EVENT_CLOSE
            Exit
    EndSwitch 
WEnd

Child

#include <GUIConstants.au3>

Global $ScriptLocation = '"I:\SAI\Auto-It files\Experiments\"'
Global $ParentWin_Title = 'Child'
;GUI SETUP
If $CmdLine[0] <> 0 Then
    If StringInStr($CmdLine[1],'Launched_from_Parent') > 0 Then
        Global $hGUI = GUICreate($ParentWin_Title, 605, 771, $CmdLine[3], $CmdLine[4])
        $ParentWin_Title_Real = StringReplace($CmdLine[2],'_',' ')
        $WinOpenAnimation = 1
        $OpenFromParent = 1
    ;#NoTrayIcon
    Else
        MsgBox(0,'Error',$CmdLine[1])
    EndIf
Else 
    $hGUI = GUICreate("Child", 620, 500, -1, -1)        ;- Main GUI Window
EndIf
GUISetState(@SW_SHOW, $hGUI)
WinMove($ParentWin_Title,'',0,0)
_SetParent($ParentWin_Title, $ParentWin_Title_Real)
GUISetState(@SW_SHOW, $hGUI)
WinSetState($hGUI, "", @SW_SHOW)


;;Main loop
While 1
    $Msg = GUIGetMsg()
    Switch $Msg
        Case $GUI_EVENT_CLOSE
            Exit
    EndSwitch 
WEnd

#cs ----------------------------------------------------------------------------
   
    AutoIt Version: 3.2.4.9
    Author:      Senton-Bomb, (adjusted by John Bailey)
   
        $TitleP - string, The title of the parent window
        $TitleC - string, The title of the child window
        $returnArray - Boolean, if true returns an array with the hwnds of the parent and child (default = false)
       
        If a window doesn't exist, It returns -1, otherwise it returns 1
   
    Script Function:
    Wrapper for the "SetParent" dllcall + Example.
    
    Example:    $p = _SetParent($ParentWin_Title, $ParentWin_Title_Real)

                If $p = -1 Then
                    MsgBox(0, "", "One or more windows don't exist")
                EndIf
   
#ce ----------------------------------------------------------------------------

; Script Stizzle - Add your codeizzle

Func _SetParent($TitleP, $TitleC, $sp_ArrayReturn=false)
    If WinExists($TitleP) Then
        If WinExists($TitleC) Then
            $HwndP = WinGetHandle($TitleP)
            $HwndC = WinGetHandle($TitleC)
            $user32 = DllOpen("user32.dll")
            DllCall($user32, "str", "SetParent", "HWnd", $HwndP, "HWnd", $HwndC)
            If $sp_ArrayReturn Then
                Local $sp_ArraytoReturn[2]
                $sp_ArraytoReturn[0] = $HwndP
                $sp_ArraytoReturn[1] = $HwndC
                GUISetState(@SW_SHOW, $HwndC)
                Return $sp_ArraytoReturn
            Else
                Return 1
            EndIf
        Else
            Return -1
        EndIf
    Else
        Return -1
    EndIf
EndFunc  ;==>_SetParent


#cs ----------------------------------------------------------------------------
;
; Parameters:   $hwnd - ref, the reference of the gui
;               $style - string, see example
;               $exstyle - string, see example
;      
; Author:      ResNullius (http://www.autoitscript.com/forum/index.php?showtopic=45906&view=findpost&p=365672)
;   
; Example:      $guiStyle = BitOR($WS_BORDER, $WS_CAPTION, $WS_CLIPCHILDREN, $WS_CLIPSIBLINGS, $WS_DLGFRAME, $WS_GROUP, $WS_MAXIMIZE, $WS_MAXIMIZEBOX, $WS_MINIMIZEBOX, $WS_SYSMENU, $WS_TABSTOP, $WS_THICKFRAME, $WS_VISIBLE); 0x17CF0100
;               $guiStyleEx = $WS_EX_WINDOWEDGE; 0x00000100
;
;               _SetStyle($Win,$guiStyle,$guiStyleEx)
;
;  
#ce ----------------------------------------------------------------------------

Func _SetStyle($hwnd,$style,$exstyle)
    DllCall("user32.dll", "long", "SetWindowLong", "hwnd", $hwnd, "int", -16, "long", $style)
    DllCall("user32.dll", "long", "SetWindowLong", "hwnd", $hwnd, "int", -20, "long", $exstyle)
EndFunc
A decision is a powerful thing
Link to comment
Share on other sites

So i've tested it. What else are you looking for? I'd be more the happy to help, just not sure what your trying to change or add on to the parent/child.

[font="Verdana"]Valik:Get it straight - I'm not here to say please, I'm here to help - if my help's not appreciated then lotsa luck, gentlemen.[/font]

Link to comment
Share on other sites

So i've tested it. What else are you looking for? I'd be more the happy to help, just not sure what your trying to change or add on to the parent/child.

What I'm saying is SetParent through the user32.dll places the child window inside the parent window. The child window's coordinates are moved in relation to the parent window, instead of the child window's position remaining where it was. Moreover, since the child window is inside the parent window, the child window cannot be dragged outside the parent window. I'm wanting to bind the child window to the parent window, but not like this. I want to be able to move the parent window and the child window moves along with it, but staying outside the parent window.

If that doesn't make sense I'll show you an example of how I'm currently doing it.

A decision is a powerful thing
Link to comment
Share on other sites

Sigh, I had a example like that. Then Deleted it. I'll work on something similar to what you want.

[font="Verdana"]Valik:Get it straight - I'm not here to say please, I'm here to help - if my help's not appreciated then lotsa luck, gentlemen.[/font]

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