Jump to content

Recommended Posts

Posted

Hello,

I've stumbled upon an issue trying to change how one of my child windows behaves and looked through the forum for an answer however the closest I got to was this post: https://www.autoitscript.com/forum/topic/201385-solved-gui-design-layering-transparency-_winapi_setparent-with-guictrlcreatepic-doesnt-work/

So for the sake of simplicity I'll be borrowing the original code with a couple of changes.

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

Local $hMainGUI = GUICreate("Main Background - Example 4", 500, 500, 0, 0, -1)
GUISetBkColor(0x000000)
GUISetState()

Local $hGUIOverlay = GUICreate("Test 4", 500, 500, 0, 0, -1, $WS_EX_LAYERED)
GUISetBkColor(0x0000F4)
Local $idButton = GUICtrlCreateButton("C:\Program Files (x86)\AutoIt3\Examples\GUI\mslogo.jpg", 50, 50, 255, 40)
GUICtrlCreatePic("C:\Program Files (x86)\AutoIt3\Examples\GUI\mslogo.jpg", 50, 100, 255, 40)

_WinAPI_SetLayeredWindowAttributes($hGUIOverlay, 0x0000F4)
GUISetState()

_WinAPI_SetParent($hGUIOverlay, $hMainGUI)
_WinAPI_MoveWindow($hGUIOverlay, 0, 0, 500, 500)

ConsoleWrite(WinGetHandle($hMainGUI) & @CRLF)

Local $Check


While 1
    $Msg = GUIGetMsg()
    Select
        Case $Msg = $idButton
            If $Check = True Then
                Local $hWndHandle = _WinAPI_SetParent($hGUIOverlay, $hMainGUI)
                ConsoleWrite($hWndHandle)
;~              $Pos = WinGetPos($hMainGUI)
;~              _WinAPI_MoveWindow($hGUIOverlay, 0, 0, 500, 500)
                $Check = False
            Else
                _WinAPI_SetParent($hGUIOverlay, 0)
                _WinAPI_MoveWindow($hGUIOverlay, 0, 0, 500, 500)
                $Check = True
            EndIf
        Case $Msg = $GUI_EVENT_CLOSE
            GUIDelete($hGUIOverlay)
            GUIDelete($hMainGUI)
            Exit
    EndSelect
WEnd

 

My problem is trying to attach the child window back to the main AFTER it was detached. Currently the way I'm overcoming this problem is by deleting and re-creating the child window with all its controls with the proper parent handle (example from my own script):

...BitOR($WS_EX_LAYERED, $WS_EX_TOOLWINDOW), $hMainGUI...

To be honest, not sure if this is even possible.

Posted

That is somewhat interesting.  I tested your code under Win7 and Win10.

Nothing works correctly in Win7.  However it is kind of working in Win10 as described in your post.

I just think you found a breach in Windows as it should not work like with Win7.

As you can see in help file :

Quote

$WS_EX_LAYERED          Creates a layered window. Note that this cannot be used for child windows. 

So if you remove the layered style from your child, all works as expected...

Posted

@Ninecan it be related to this, as found in msdn documentation (several topics)

Beginning with Windows 8, WS_EX_LAYERED can be used with child windows and top-level windows. Previous Windows versions support WS_EX_LAYERED only for top-level windows.
Posted
16 minutes ago, Nine said:

That is somewhat interesting.  I tested your code under Win7 and Win10.

Nothing works correctly in Win7.  However it is kind of working in Win10 as described in your post.

I just think you found a breach in Windows as it should not work like with Win7.

As you can see in help file :

So if you remove the layered style from your child, all works as expected...

You are correct when it comes to W10. Removing the extended style does work however I require it.

To elaborate on my problem a little bit more. I have a child window that by default is attached to the main window and is completely transparent with a *.png over it and a couple of labels on top acting as invisible buttons. I draw and update the image (yes it changes) with _WinAPI_UpdateLayeredWindow(). And if I want to detach it I simply delete the previous GUI and recreate a new one (...BitOR($WS_EX_LAYERED, $WS_EX_TOOLWINDOW)...) with all the labels.

So removing the extended style would be quite troublesome. I did try looking into _WinAPI_SetWindowLong() as one of its parameters is $GWL_HWNDPARENT however that seems to do nothing. MSDN page on SetWindowLongA (from the page: "You must not call SetWindowLong with the GWL_HWNDPARENT index to change the parent of a child window. Instead, use the SetParent function.")

Example is from my script simply to show what I meant above.

$GUI_MainImage = GUICreate($PROGRAMNAME, 232, 232, $TempPos[0], $TempPos[1] + $TempPos[3] - 250, -1, BitOR($WS_EX_LAYERED, $WS_EX_TOOLWINDOW), $GUI_MainWindow)
$GUI_MainImageTouch0 = GUICtrlCreateLabel('', 0, 0, 0, 0) ;Inactive
$GUI_MainImageTouch1 = GUICtrlCreateLabel('', 70, 0, 120, 100)
$GUI_MainImageTouch2 = GUICtrlCreateLabel('', 60, 150, 50, 40)
$GUI_MainImageTouch3 = GUICtrlCreateLabel('', 80, 100, 40, 40)
GUISetState(@SW_SHOWNOACTIVATE, $GUI_MainImage)

 

Posted

Thanks @pixelsearch.  Learning is an every day experience  But obviously, Windows seems to have done a lousy job with it...

@NMS Now that I know it could be possible, I tested a few things without success.

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
×
×
  • Create New...