pixelsearch Posted Sunday at 08:21 PM Posted Sunday at 08:21 PM (edited) Hello everybody I got an issue with the following script (tested on Windows 11) expandcollapse popup#include <EditConstants.au3> #include <GUIConstantsEx.au3> #include <StaticConstants.au3> #include <WinAPISysWin.au3> #include <WindowsConstants.au3> Opt("MustDeclareVars", 1) Global $g_hGui Example() ;============================================== Func Example() Local $idButton, $idLabel, $idCheckbox, $idEdit $g_hGui = GUICreate("Drag controls (GUI_ONTOP issue)", 400, 150) $idButton = GUICtrlCreateButton("", 10, 30, 80, 80, $WS_CLIPSIBLINGS) GUICtrlSetData(-1, "Button " & $idButton) $idLabel = GUICtrlCreateLabel("", 100, 40, 80, 60, BitOr($SS_CENTERIMAGE, $SS_CENTER, $WS_CLIPSIBLINGS)) GUICtrlSetData(-1, "Label " & $idLabel) GUICtrlSetBkColor(-1, 0x00FF00) ; green $idCheckbox = GUICtrlCreateCheckbox("", 190, 50, 80, 40, $WS_CLIPSIBLINGS) GUICtrlSetData(-1, "Checkbox " & $idCheckbox) GUICtrlSetBkColor(-1, 0xFFFF00) ; yellow $idEdit = GUICtrlCreateEdit("", 280 ,40, 100, 70, BitOr($GUI_SS_DEFAULT_EDIT, $WS_CLIPSIBLINGS)) GUICtrlSetData(-1, "Edit " & $idEdit) GUISetState() While 1 Switch GUIGetMsg() Case $GUI_EVENT_CLOSE Exit Case $GUI_EVENT_PRIMARYDOWN _ControlMove() EndSwitch WEnd EndFunc ;==>Example ;============================================== Func _ControlMove() Local $aInfo, $idControl, $hControl, $aPos, $iSubtractX, $iSubtractY, $iLoopCount $aInfo = GUIGetCursorInfo($g_hGUI) If Not @error And $aInfo[4] Then $idControl = $aInfo[4] $hControl = GUICtrlGetHandle($idControl) $aPos = ControlGetPos($g_hGui, "", $idControl) $iSubtractX = $aInfo[0] - $aPos[0] $iSubtractY = $aInfo[1] - $aPos[1] While $aInfo[2] ; LMB pressed $iLoopCount += 1 If $iLoopCount = 1 Then ; GUICtrlSetState($idControl, $GUI_ONTOP) ; changes wrongly the z-order of a label control, why ? ; _WinAPI_SetWindowPos($hControl, $HWND_TOP, 0, 0, 0, 0, BitOr($SWP_NOMOVE, $SWP_NOSIZE, $SWP_NOACTIVATE)) EndIf $aInfo = GUIGetCursorInfo($g_hGui) GUICtrlSetPos($idControl, $aInfo[0] - $iSubtractX, $aInfo[1] - $iSubtractY) Sleep(10) WEnd EndIf EndFunc ;==>_ControlMove 1) When you run the script "as-is" (without modifying any line) : * Each control dragged to the right covers the controls found at its right * Each control dragged to the left is covered by the controls found at its left. 2) Now let's uncomment the $GUI_ONTOP line : GUICtrlSetState($idControl, $GUI_ONTOP) ; seems to change wrongly the z-order of a label control, why ? ; _WinAPI_SetWindowPos($hControl, $HWND_TOP, 0, 0, 0, 0, BitOr($SWP_NOMOVE, $SWP_NOSIZE, $SWP_NOACTIVATE)) * Button, Checkbox, Edit : they all behave correctly, covering all controls when dragged. * Label : on the contrary, the label control is covered by any control when dragged. So the question is : why the label control doesn't follow the other controls behavior ? 3) Final test : please comment out the $GUI_ONTOP line and uncomment the _WinAPI_SetWindowPos line, like this : ; GUICtrlSetState($idControl, $GUI_ONTOP) ; changes wrongly the z-order of a label control, why ? _WinAPI_SetWindowPos($hControl, $HWND_TOP, 0, 0, 0, 0, BitOr($SWP_NOMOVE, $SWP_NOSIZE, $SWP_NOACTIVATE)) Now the label control behaves differently and covers all other controls when dragged. So is there a bug with $GUI_ONTOP when applied to label controls ? For the record, a track ticket #2287 concerning this question was closed by Jon 12 years ago. But isn't the test in 2) enough to show that the label behaves differently from the other controls when $GUI_ONTOP is applied to it ? Edit 1: no more sure of anything as the $WS_CLIPSIBLINGS style seems to interfere with all this ! Edit 2 : even if you remove the 4 $WS_CLIPSIBLINGS style at control creation, you'll notice that test 2) shows a different behavior when it comes to the label control, compared to the 3 other controls, but test 3) shows the same behavior for all controls. That's why I prefer to use _WinAPI_SetWindowPos which behaves in the same way for the 4 controls, rather than $GUI_ONTOP which treats labels control differently, especially in this kind of script where we want the dragged control to appear above (in front of) any other control during the drag process. Edited Monday at 12:42 AM by pixelsearch added Edit1 then Edit2 "I think you are searching a bug where there is no bug... don't listen to bad advice."
argumentum Posted Monday at 01:07 AM Posted Monday at 01:07 AM 4 hours ago, pixelsearch said: ..use _WinAPI_SetWindowPos which behaves in the same way for the 4 controls.. Yes, what you described is true in my testing too ( Win11 25H2 ). Open a ticket in trac to let them know that it needs attention. Follow the link to my code contribution ( and other things too ). FAQ - Please Read Before Posting.
MattyD Posted Monday at 08:48 AM Posted Monday at 08:48 AM Yeah it looks like $GUI_ONTOP sends labels to the wrong end of the z-order. Just thought I'd add that the example in the track ticket #2287 seems to kind-of work... "Set ONTOP Label 2" is printed when Label 2 comes to the front... but it's not clipping siblings. When you click in the area where the 2 controls overlap, its the control underneath that receives the click. So I take that to mean the "top" control here is being painted into areas where it shouldn't be. #include <GUIConstants.au3> GUICreate("Test", 300, 200) GUISetState() $idLab1 = GUICtrlCreateLabel("Label 1", 30, 30, 200, 100) GUICtrlSetBkColor(-1, 0xFF0000) $idLab2 = GUICtrlCreateLabel("Label 2", 50, 50, 200, 100) GUICtrlSetBkColor(-1, 0x00FF00) Local $iMsg While 1 $iMsg = GUIGetMsg() Switch $iMsg Case $idLab1, $idLab2 ConsoleWrite("Set ONTOP " & GUICtrlRead($iMsg) & @CRLF) GUICtrlSetState($iMsg, $GUI_ONTOP) Case $GUI_EVENT_CLOSE Exit EndSwitch WEnd
pixelsearch Posted Monday at 01:42 PM Author Posted Monday at 01:42 PM Thanks guys for your comments I just rested with older versions of AutoIt, hoping secretly to detect if $GUI_ONTOP behaved correctly for the 4 controls in my initial script from post 1. Bingo ! Reminder of test 2) : $GUI_ONTOP line uncommented, _WinAPI_SetWindowPos line commented out, like this : GUICtrlSetState($idControl, $GUI_ONTOP) ; changes wrongly the z-order of a label control, why ? ; _WinAPI_SetWindowPos($hControl, $HWND_TOP, 0, 0, 0, 0, BitOr($SWP_NOMOVE, $SWP_NOSIZE, $SWP_NOACTIVATE)) * AutoIt 3.3.12.0 (2014) The script works fine for ALL 4 controls, which are correctly on top when dragged (label control too, yes !) * AutoIt 3.3.14.0 (2015) The script doesn't work for all controls : the label control doesn't behave as the 3 other controls. Which means that some code has changed between these 2 versions and the timeline shows that it is connected to Track ticket #2287 owned and closed by Jon, who wrote in the AutoIt history/changelog : Fixed #2287: GUICtrlSetState() $GUI_ONTOP not set. Unfortunately, what worked fine (at least for me) with the previous version from 2014 doesn't work anymore with the version from 2015 and further. For the record, I don't understand trancexx answer in the track ticket, quote : Changed 13 years ago by trancexx Resolution set to No Bug Status changed from new to closed $GUI_ONTOP does what it's docummented that it does. There is no bug here. Documentation says that control will get to the top of z-order. By default if the control is on top, it's the closest to the parent window (GUI) and it's therefore covered by all other controls being lower down the z-order. On the other hand, for example, if the GUI would have WS_EX_COMPOSITED ex-style, you would see different effect (also docummented). Maybe I'm wrong, but an "ontop" control is not covered by all other sibling controls. On the contrary, it is supposed to be in front of us, before all other controls, with the greatest z-order index of the sibling controls. What would be the point of sending it at the bottom of the controls stack, hidden by all of them, and name the variable $GUI_ONTOP ? I know the actual doc indicates what follows for $GUI_ONTOP, but maybe it has been badly retranscripted in the help file : $GUI_ONTOP (2048) : Control will be have the ontop attribute for the window (zOrdering). Also, I have no idea where this link took its source from, in 2017, to indicate a more complete definition : $GUI_ONTOP : Control will be given the ontop attribute, making it show on top of other elements (zOrdering). What I may simply do one of these days, it's to add a new comment in trac ticket #2287, linking to the thread we are in, and we'll see what happens : if nothing can be done, at least we'll have the _WinAPI_SetWindowPos function that behaves the same way for all controls. argumentum 1 "I think you are searching a bug where there is no bug... don't listen to bad advice."
MattyD Posted Monday at 04:10 PM Posted Monday at 04:10 PM Yeah, not sure about trancexx's comment - it doesn't sound right given $HWND_TOP works as expected. $WS_EX_COMPOSITED does say it "paints all descendants of a window in bottom-to-top painting order". I take that as it'll paint each control (within an area) one at a time into a buffer so you can mix alpha channels, then dump the result to the screen.. I don't think the description is alluding to changes in the z-ordering - I'd say its more it's pointing out controls aren't just getting painted on top with some auto-clipping.
Recommended Posts
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 accountSign in
Already have an account? Sign in here.
Sign In Now