Jump to content
Sign in to follow this  
tito

Why does _WinAPI_SetParent hide the new child?

Recommended Posts

tito

Hi,

I'm trying to hide programs (fe notepad) from the taskbar, without hiding/minimising the programs.

I've read that this could be achieved by making the 3rth party app a child of a new app.

 

Problem I've encountered now is that upon calling _WinAPI_SetParent(), the program becomes hidden.

Is it possible to make a 3rth party program a child of a new autoit program, wihtout hiding it ?

Final goal : moving 3rth party programs to the systemtray, removing their startbar/taskbar button, but -without- hiding or minimising the 3rt party program.

Below the code I'm curently using (found most of it on this forum)

To test : try opening a notepad.exe and hiding+showing it (though shouldn't actually hide but is does)

#include <Array.au3>
#include <Constants.au3>
#include <WinAPI.au3>
#include <guiconstants.au3>
#include <windowsconstants.au3>

;Opt("TrayIconHide", 1)

Global $hGui1 = GUICreate('Parent');this is the 'holder' for hidden apps
GUISetState();hide the parent from task bar as well or remove comment to show it
MsgBox(262144, 'Hide and Seek', 'To Hide the active window press F8' & @CRLF & 'To bring back the last hidden window press F9' & _
        @CRLF & 'To restore all and quit press F10')
Dim $origparent[20][2], $index = 0


Global $avChildren

HotKeySet("{F8}", "Hide")
HotKeySet("{F9}", "Show")
HotKeySet("{F10}", "Leave")
While 1
;next line not needed, it's just to stop anyone seeing your app is running
    ;If WinExists("Windows Task Manager") Then WinClose("Windows Task Manager")
    Sleep(100)

WEnd

Func Hide()
    If $origparent[$index][0] <> 0 Then Return
    $title = WinGetTitle("")
    
    ConsoleWrite($title & @CRLF)

    If $title = 'Program Manager' Then;caution - this is language dependent I assume
        MsgBox(0, "ERROR", "Can't hide Program Manager")
        Return
    EndIf

    $origparent[$index][1] = WinGetHandle($title)
    ;$origparent[$index][0] = DllCall("user32.dll", "int", "SetParent", "hwnd", $origparent[$index][1], "hwnd", $hGui1)
    $origparent[$index][0] = _WinAPI_SetParent($origparent[$index][1], $hGui1)




    ConsoleWrite("$origparent[$index][1] "&$origparent[$index][1] & @CRLF)
    ConsoleWrite("$origparent[$index][0] "&$origparent[$index][0] & @CRLF)

    #cs
    _WinAPI_RedrawWindow($hGui1)
    _WinAPI_RedrawWindow($origparent[$index][1])
    
    $WinSetState = WinSetState( $origparent[$index][1], "", @SW_SHOW )
    ConsoleWrite("WinSetState "& $WinSetState & @CRLF)
    
    $GUISetState = GUISetState( $origparent[$index][1], @SW_SHOW )
    ConsoleWrite("GUISetState "& $GUISetState & @CRLF)
    
    $winactivate = WinActivate($origparent[$index][1])
    ConsoleWrite("winactivate "&$winactivate & @CRLF)
    
    $SW_SHOWNORMAL = _WinAPI_ShowWindow($origparent[$index][1], @SW_SHOWNORMAL)
    ConsoleWrite("SW_SHOWNORMAL "&$SW_SHOWNORMAL & @CRLF)
    
    $SW_SHOW = _WinAPI_ShowWindow($origparent[$index][1], @SW_SHOW)
    ConsoleWrite("SW_SHOW "&$SW_SHOW & @CRLF)
    #ce
    
    $index += 1

    If UBound($origparent) < $index + 2 Then ReDim $origparent[$index + 5][2]

    $avChildren = ""
    WinListChildren($hGui1, $avChildren)
    
EndFunc ;==>Hide

Func Show()
    $shouldReturn = False
    
    If Not $shouldReturn Then
        If $index = 0 Then $shouldReturn = True
    EndIf

    If Not $shouldReturn Then
        If $origparent[$index - 1][0] = 0 Then $shouldReturn = True
    EndIf
    
    If Not $shouldReturn Then
        ;$detachparentresult = DllCall("user32.dll", "int", "SetParent", "hwnd", $origparent[$index - 1][1], "hwnd", $origparent[$index - 1][0])
        $detachparentresult = _WinAPI_SetParent($origparent[$index - 1][1], $origparent[$index - 1][0])
        ConsoleWrite("detachparentresult "&$detachparentresult & @CRLF)
        
        WinActivate($origparent[$index - 1][1])
        $origparent[$index - 1][0] = 0
        $index -= 1
    EndIf
    
    $avChildren = ""
    WinListChildren($hGui1, $avChildren)
    ;_ArrayDisplay($avChildren)

EndFunc ;==>Show

Func Leave()
    
    While $index > 0
        Show()
    WEnd
    Exit
EndFunc ;==>Leave

Func OnAutoItExit()
    Leave()
EndFunc ;==>OnAutoItExit

Func WinListChildren($hWnd, ByRef $avArr)
    If UBound($avArr, 0) <> 2 Then
        Local $avTmp[10][2] = [[0]]
        $avArr = $avTmp
    EndIf
    
    Local $hChild = _WinAPI_GetWindow($hWnd, $GW_CHILD)
    
    While $hChild
        If $avArr[0][0]+1 > UBound($avArr, 1)-1 Then ReDim $avArr[$avArr[0][0]+10][2]
        $avArr[$avArr[0][0]+1][0] = $hChild
        $avArr[$avArr[0][0]+1][1] = _WinAPI_GetWindowText($hChild)
        $avArr[0][0] += 1
        ;WinListChildren($hChild, $avArr)
        $hChild = _WinAPI_GetWindow($hChild, $GW_HWNDNEXT)
    WEnd
    
    ReDim $avArr[$avArr[0][0]+1][2]

    If UBound($avArr) > 1 Then
        ConsoleWrite("UBound($avChildren) "&UBound($avArr) & @CRLF)
        For $avChildren_i = 1 To UBound($avArr) - 1
            ConsoleWrite("child["&$avChildren_i&"]" & " --> " & $avArr[$avChildren_i][0] & " | " & $avArr[$avChildren_i][1] & @CRLF)
        Next
    Else
        ConsoleWrite("No children" & @CRLF)
    EndIf

EndFunc
Edited by tito

Share this post


Link to post
Share on other sites
martin

Hello tito,

I see that by coincidence you are using some code I wrote a few years ago.

Notepad moves correctly to the parent window for me when I try your code. When a child is given a new parent window it will take the same position as it did on the desktop, so maybe your notepad is just out of sight and if you made your parent like this

Global $hGui1 = GUICreate('Parent', 800, 600, 100, 100,$WS_SIZEBOX)

you might be able to see it.

I don't think there is any difference btween these 2 lines BTW.

;$origparent[$index][0] = DllCall("user32.dll", "int", "SetParent", "hwnd", $origparent[$index][1], "hwnd", $hGui1)
    $origparent[$index][0] = _WinAPI_SetParent($origparent[$index][1],$hGui1)

 

If you replace the parent $hGui parameter with wingethandle("Program Manager") then you might get what you want except that the window will be stuck at the back of any other windows.


Serial port communications UDF Includes functions for binary transmission and reception.printing UDF Useful for graphs, forms, labels, reports etc.Add User Call Tips to SciTE for functions in UDFs not included with AutoIt and for your own scripts.Functions with parameters in OnEvent mode and for Hot Keys One function replaces GuiSetOnEvent, GuiCtrlSetOnEvent and HotKeySet.UDF IsConnected2 for notification of status of connected state of many urls or IPs, without slowing the script.

Share this post


Link to post
Share on other sites
tito

Hi Martin,

Indeed I used your code from

Changing the gui parent creation to:

Global $hGui1 = GUICreate('Parent', 800, 600, 100, 100,$WS_SIZEBOX)

did not solve it , notepad still becomes hidden.

I also tried your suggestion to set notepad's parent to 'Project Manager' :

Then notepad is then not hidden , though the taskbar buttons statys (it's dissapears for 1ms and then reappears...)

Do you or anyone else have any other suggestions to achieve 'hiding the taskbar button of a 3rth party app, without hiding the app ?'

Or : show a hidden child from a (new) parent?

Edited by tito

Share this post


Link to post
Share on other sites
martin

What Windows version are you suing?


Serial port communications UDF Includes functions for binary transmission and reception.printing UDF Useful for graphs, forms, labels, reports etc.Add User Call Tips to SciTE for functions in UDFs not included with AutoIt and for your own scripts.Functions with parameters in OnEvent mode and for Hot Keys One function replaces GuiSetOnEvent, GuiCtrlSetOnEvent and HotKeySet.UDF IsConnected2 for notification of status of connected state of many urls or IPs, without slowing the script.

Share this post


Link to post
Share on other sites
tito

Thx for your help Martin!

I'm on : Win7 + SP1 - 64bit

btw: I've set the option 'group taskbar buttons' to 'never'

 

I've also noticed that when using the Autoit 'Window Info' tool:

Selecting the SysTray (Shell_TrayWnd - ToolbarWindow32) does show icons/programs listed in the 'Window Info' -> 'ToolBar' tab

But selecting the TaskBar (Shell_TrayWnd - MSTaskListWClass) does not show any programs listed in the 'Window Info' -> 'ToolBar' tab

 

Regarding:

 

I don't think there is any difference btween these 2 lines BTW.

;$origparent[$index][0] = DllCall("user32.dll", "int", "SetParent", "hwnd", $origparent[$index][1], "hwnd", $hGui1)
    $origparent[$index][0] = _WinAPI_SetParent($origparent[$index][1],$hGui1)

 

-> Indeed, this is from WinAPI.AU3 :

Func _WinAPI_SetParent($hWndChild, $hWndParent)
Local $aResult = DllCall("user32.dll", "hwnd", "SetParent", "hwnd", $hWndChild, "hwnd", $hWndParent)
If @error Then Return SetError(@error, @extended, 0)
Return $aResult[0]
EndFunc   ;==>_WinAPI_SetParent
Edited by tito

Share this post


Link to post
Share on other sites
trancexx

There is an example of what you want to do in the help file of AutoIt language for function ObjCreateInterface. Possibly.


♡♡♡

.

eMyvnE

Share this post


Link to post
Share on other sites
martin

Ooh, so there is. Works for me.


Serial port communications UDF Includes functions for binary transmission and reception.printing UDF Useful for graphs, forms, labels, reports etc.Add User Call Tips to SciTE for functions in UDFs not included with AutoIt and for your own scripts.Functions with parameters in OnEvent mode and for Hot Keys One function replaces GuiSetOnEvent, GuiCtrlSetOnEvent and HotKeySet.UDF IsConnected2 for notification of status of connected state of many urls or IPs, without slowing the script.

Share this post


Link to post
Share on other sites
tito

Thx!

The example works fine, will ellaborate on that.

$oTaskbarList.AddTab(handle) works great too

 

ps 1: I rreeaaalllyyy did check the help file and forum, though missed it ....

ps 2: I'll ignore the warning in the help file for now ;) "Warning: This feature is experimental. It may not work, may contain bugs or may be changed or removed without notice. DO NOT REPORT BUGS OR REQUEST NEW FEATURES FOR THIS FEATURE. USE AT YOUR OWN RISK."

Share this post


Link to post
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
Sign in to follow this  

×