Gui, z-order and static control

Report problems with documented functionality
Zelio
Posts: 278
Joined: 30 Sep 2013, 00:45
Location: France

Gui, z-order and static control

11 Oct 2013, 09:00

I played and I have a problem with this script, I need a Bottom and not a Top for have the good drawing but that will don't work with the z-order of static control for trigger label or show wich control the mouse over, it is like drawing and static control have a different and reversed z-order priority when I use WinSet. Or Winset don't update corretly drawing or z-order control :

Code: Select all

SetBatchlines -1
SetControlDelay, -1
#SingleInstance force
#NoEnv

if !FileExist("background.png")
	UrlDownloadToFile, http://www.auto-hotkey.com/boards/styles/subsilver2/imageset/ahk_logo.png, background.png

OnMessage(WM_LBUTTONUP := 0x202, "OnClickUp")
OnMessage(WM_MOUSEMOVE := 0x200, "OnMouseMove")

SuperButton("test1", "background.png", 50, 50)
SuperButton("test2", "background.png", 200, 200)
SuperButton("test3", "background.png", 50, 200)


Gui, Show, w640 h480, TEST

SetTimer, check, 50
return

check:
CoordMode, Mouse, Client
MouseGetPos, mx, my, mw, mc, 0
tooltip % mx "`n" my "`n" mw "`n" mc, 0, 0, 3
return

ControlMove:
tooltip, % a_guicontrol, 100, 0, 2
mode := a_guicontrol
CoordMode, Mouse, Client
MouseGetPos, mx, my
GuiControlGet, %a_guicontrol%, Pos
mx0 := mx-%a_guicontrol%x
my0 := my-%a_guicontrol%y
return


OnClickUp(){
	global
if InStr(mode, "Text")
{
;DllCall("SetWindowPos", UInt,WinExist("ahk_id " %mode0%), Int,1, Int,0, Int,0, Int,0, Int,0, UInt,0x13)
;DllCall("SetWindowPos", UInt,WinExist("ahk_id " %mode%), Int,1, Int,0, Int,0, Int,0, Int,0, UInt,0x13)
WinSet, Bottom, , % "ahk_id " %mode0%
WinSet, Bottom, , % "ahk_id " %mode%
}
else
{
;DllCall("SetWindowPos", UInt,WinExist("ahk_id " %mode%), Int,1, Int,0, Int,0, Int,0, Int,0, UInt,0x13)
;DllCall("SetWindowPos", UInt,WinExist("ahk_id " %mode0%), Int,1, Int,0, Int,0, Int,0, Int,0, UInt,0x13)
WinSet, Bottom, , % "ahk_id " %mode%
WinSet, Bottom, , % "ahk_id " %mode0%
}
	mode := "static"
	WinSet, redraw, , A

return
}

OnMouseMove()
{
	global
if (mode != "static")
	{
	CoordMode, Mouse, Client
	MouseGetPos, mx, my
if InStr(mode, "Text")
{
	mode0 := RegExReplace(mode, "Text", "Background")
	GuiControl, Move, % mode0, % "x" mx-mx0 " y" my-my0
	GuiControl, Move, % mode, % "x" mx-mx0 " y" my-my0
	WinSet, redraw, , % "ahk_id " %mode0%
	WinSet, redraw, , % "ahk_id " %mode%

}
else
{
	mode0 := RegExReplace(mode, "Background", "Text")
	GuiControl, Move, % mode, % "x" mx-mx0 " y" my-my0
	GuiControl, Move, % mode0, % "x" mx-mx0 " y" my-my0
	WinSet, redraw, , % "ahk_id " %mode%
	WinSet, redraw, , % "ahk_id " %mode0%
}
	}
}

esc::
guiclose:
exitapp

SuperButton(text, picture, x, y) {
Global
Static id := 0
id += 1
Gui, Add, Picture, x%x% y%y% w300 h-1 gControlMove vBackground%id% hwndBackground%id%, % picture
Gui, Add, Text, x%x% y%y% w100 h30 +0x201 +Border gControlMove vText%id% hwndText%id% +Backgroundtrans, % text
return
}


/*
DllCall("SetWindowPos", UInt,WinExist("ahk_id " %mode0%), Int,1, Int,0, Int,0, Int,0, Int,0, UInt,0x13)

#define SWP_NOSIZE          0x0001
#define SWP_NOMOVE          0x0002
#define SWP_NOZORDER        0x0004
#define SWP_NOREDRAW        0x0008
#define SWP_NOACTIVATE      0x0010
#define SWP_FRAMECHANGED    0x0020  /* The frame changed: send WM_NCCALCSIZE */
#define SWP_SHOWWINDOW      0x0040
#define SWP_HIDEWINDOW      0x0080
#define SWP_NOCOPYBITS      0x0100
#define SWP_NOOWNERZORDER   0x0200  /* Don't do owner Z ordering */
#define SWP_NOSENDCHANGING  0x0400  /* Don't send WM_WINDOWPOSCHANGING */

#define SWP_DRAWFRAME       SWP_FRAMECHANGED
#define SWP_NOREPOSITION    SWP_NOOWNERZORDER

#if(WINVER >= 0x0400)
#define SWP_DEFERERASE      0x2000
#define SWP_ASYNCWINDOWPOS  0x4000
#endif /* WINVER >= 0x0400 */

#define HWND_TOP        0
#define HWND_BOTTOM     1
#define HWND_TOPMOST   -1
#define HWND_NOTOPMOST -2
*/
Zelio
Posts: 278
Joined: 30 Sep 2013, 00:45
Location: France

Re: Gui, z-order and static control

12 Oct 2013, 08:32

A better example, just for show the problem (I don't speak about flickering) : I need a winset bottom for show a control at top, draw will be in order 1->2->3, but control are selectable by order 3->2->1. If 3 image are overlapped then for sample the top most will be 3, but the selectable will be 1.

Code: Select all

#SingleInstance force
#NoEnv
SetBatchlines -1
SetControlDelay, -1

if !FileExist("background.png")
	UrlDownloadToFile, http://www.auto-hotkey.com/boards/styles/subsilver2/imageset/ahk_logo.png, background.png

OnMessage(WM_LBUTTONUP := 0x202, "OnClickUp")
OnMessage(WM_MOUSEMOVE := 0x200, "OnMouseMove")

SuperButton("background.png", 50, 50, 517)
SuperButton("background.png", 100, 100, 517)
SuperButton("background.png", 150, 150, 517)

Gui, Show, w640 h360, TEST

SetTimer, check, 50
return

check:
CoordMode, Mouse, Client
MouseGetPos, mx, my, mw, mc, 0
tooltip % mx "`n" my "`n" mw "`n" mc, 0, 0, 2
return

ControlMove:
mode := a_guicontrol
CoordMode, Mouse, Client
MouseGetPos, mx, my
GuiControlGet, %a_guicontrol%, Pos
mx0 := mx-%a_guicontrol%x
my0 := my-%a_guicontrol%y
WinSet, Bottom, , % "ahk_id " %mode%
;WinSet, redraw, , A
return


OnClickUp(){
	global
	mode := ""
	WinSet, redraw, , A
return
}

OnMouseMove()
{
	global
if (mode != "")
	{
	CoordMode, Mouse, Client
	MouseGetPos, mx, my
	GuiControl, Move, % mode, % "x" mx-mx0 " y" my-my0
;	WinSet, redraw, , % "ahk_id " %mode%
	WinSet, redraw, , A
	}
}

guiclose:
exitapp
return

SuperButton(picture, x, y, w, h=-1) {
Global
Static id := 0
id += 1
Gui, Add, Picture, x%x% y%y% w%w% h%h% gControlMove vBackground%id% hwndBackground%id% +Backgroundtrans, % picture
return % id
}
edit same in v2 (I had problem to found winset function)

Code: Select all

#SingleInstance force
;SetControlDelay, -1

if !FileExist("background.png")
	Download, http://www.auto-hotkey.com/boards/styles/subsilver2/imageset/ahk_logo.png, background.png

OnMessage(WM_LBUTTONUP := 0x202, "OnClickUp")
OnMessage(WM_MOUSEMOVE := 0x200, "OnMouseMove")

SuperButton("background.png", 50, 50, 517)
SuperButton("background.png", 100, 100, 517)
SuperButton("background.png", 150, 150, 517)

Gui, Show, w640 h360, TEST

SetTimer, check, 50
return

check:
CoordMode, Mouse, Client
MouseGetPos, mx, my, mw, mc, 0
tooltip % mx "`n" my "`n" mw "`n" mc, 0, 0, 2
return

ControlMove:
mode := a_guicontrol
CoordMode, Mouse, Client
MouseGetPos, mx, my
GuiControlGet, %a_guicontrol%, Pos
mx0 := mx-%a_guicontrol%x
my0 := my-%a_guicontrol%y
WinMoveBottom("ahk_id " %mode%)
return


OnClickUp(){
	global
	mode := ""
	WinRedraw()
return
}

OnMouseMove()
{
	global
if (mode != "")
	{
	CoordMode, Mouse, Client
	MouseGetPos, mx, my
	GuiControl, Move, % mode, % "x" mx-mx0 " y" my-my0
	WinRedraw()
	}
}

guiclose:
exitapp
return

SuperButton(picture, x, y, w, h:=-1) {
Global
Static id := 0
id += 1
Gui, Add, Picture, x%x% y%y% w%w% h%h% gControlMove vBackground%id% hwndBackground%id% +Backgroundtrans, % picture
return % id
}
just me
Posts: 9763
Joined: 02 Oct 2013, 08:51
Location: Germany

Re: Gui, z-order and static control

13 Oct 2013, 03:37

Same in AHK 1.0, same when using DllCall("User32.dll\BringWindowToTop", ...) in all versions.
lexikos
Posts: 9780
Joined: 30 Sep 2013, 04:07
Contact:

Re: Gui, z-order and static control

13 Oct 2013, 05:28

It is not clear from your post what you expect (or "need") to happen and what is actually happening. Do you expect MouseGetPos to return the control which is drawn on top?
Zelio
Posts: 278
Joined: 30 Sep 2013, 00:45
Location: France

Re: Gui, z-order and static control

13 Oct 2013, 07:38

Hmm I hope I will be more clear.

When I want to move or redraw a control in a ahk gui, I have to use WinMoveBottom to show a control at top of other control. I imagine that to use WinMoveBottom or WinMoveTop will sort z-order for that AHK internaly rebuild a blueprint to show control in the right order. Firstly, Why I need a "Bottom" and not a "Top".

MouseGet and gMyLabel option show and trigger the same thing, but at the opposite effect of the z-order drawing sorting... It is like drawing and all other control feature are not sync. It is like drawing control start from the end and not from the begin, that overlap in the wrong order.

The bug is a question about z-order or depth control layer when overlapping. In my point of view the fault is not about WinMoveBottom because that seems to work fine with windows, so control must have the same result ? That why I think AHK internally don't redraw control in the right order when change static order (can be visible only when overlapping). Else the problem is trigerring label order, I don't know...

The fact, when I use WinMoveBottom the control will be at the top of all other control, his static number will change. However it will be the last to be triggerable (mouseget, gMyLabel). Higly visible but unclicable.
just me
Posts: 9763
Joined: 02 Oct 2013, 08:51
Location: Germany

Re: Gui, z-order and static control

13 Oct 2013, 11:18

I did some more testing. It seems to depend on how drawing is done:

Code: Select all

#NoEnv
Gui, +hwndHGUI
Gui, Margin, 20, 20
Gui, Font, s24
Gui, Add, Text, w400 h100 Center 0x200 vTX1 hwndHTX1 +Border gDummy, Text 1
Gui, Add, Text, xp yp wp hp Center 0x200 vTX2 hwndHTX2 +Border gDummy, Text 2
Gui, Font
Gui, Add, Button, gToggle vBtnCtl, ToggleRedrawControl
Gui, Add, Button, x+20 yp gToggle vBtnWin, ToggleRedrawWindow
Gui, Add, StatusBar
Gui, Show, , Test
HWND := HTX2
SB_SetText("   OnTop: " . (HWND = HTX2 ? "Text 2" : "Text 1"))
Return

GuiCLose:
ExitApp

Toggle:
   ; DllCall("User32.dll\BringWindowToTop", "Ptr", HWND := (HWND = HTX2 ? HTX1 : HTX2))
   WinSet, Top, , % "ahk_id " . (HWND := (HWND = HTX2 ? HTX1 : HTX2))
   WinSet, Redraw, , % "ahk_id " . (A_GuiControl = "BtnCtl" ? HWND : HGUI)
   SB_SetText("   OnTop: " . (HWND = HTX2 ? "Text 2" : "Text 1"))
Return

Dummy:
   MsgBox, You clicked on %A_GuiControl%
Return
Zelio
Posts: 278
Joined: 30 Sep 2013, 00:45
Location: France

Re: Gui, z-order and static control

13 Oct 2013, 18:11

@justme: use WinSet, Redraw, , A, something is wrong in your code, no ? I have a different effect when I press button#2 then minimize and reshow window.
lexikos
Posts: 9780
Joined: 30 Sep 2013, 04:07
Contact:

Re: Gui, z-order and static control

14 Oct 2013, 02:42

I think you'll find that the ClassNN of each control changes when you change the z-order. This is because the NN part is based on the order in which controls are enumerated, which is defined by the OS, but appears to be based on z-order. AutoHotkey doesn't (and cannot) keep track of how it has identified controls for each and every window.

Instead of ClassNN, you should identify controls by HWND or associated variable.
Zelio
Posts: 278
Joined: 30 Sep 2013, 00:45
Location: France

Re: Gui, z-order and static control

14 Oct 2013, 06:30

"AutoHotkey doesn't (and cannot)" Did you mean that AHK don't manage z-order controls internally ? It is strange because I need a "Bottom" and not a "Top".
Nevermind, as you said I can get HWND or associated variable instead or CLassNN but in this report the tooltip was just for a demo and an help, because the fact is I can't change how gMyLabel will be triggered. The problem is with WinSet and gMyLabel, but if you think it is not a bug (out of my knowledge, I don't understand that is not a bug, maybe only OS managment as you said)
Also I can manage a kind of "z-buffer" with collision dection of control with mouse pos and see who are at top, but it is not elegeant and add pretty much code.
Anyway, thanks lexikos.
lexikos
Posts: 9780
Joined: 30 Sep 2013, 04:07
Contact:

Re: Gui, z-order and static control

15 Oct 2013, 03:42

After re-reading your previous post, I think I now understand the issue.

The static controls do not appear to be rendered in the correct order. Using GetWindow() to verify the z-order, I confirmed that Static controls appeared to be rendered in an order opposite to the z-order. I have reproduced the "bug" using a standalone C++ project, creating the controls either with CreateWindow() or by defining them in a dialog resource. So basically, this is standard Windows behaviour.

When I use Button or Edit controls, they don't appear to be drawn in any consistent order; they either flicker or kind of merge together.

For any type of control, adding WS_CLIPSIBLINGS (+0x4000000) appears to produce the correct behaviour.
Zelio
Posts: 278
Joined: 30 Sep 2013, 00:45
Location: France

Re: Gui, z-order and static control

15 Oct 2013, 06:57

Thanks a lot, it is works with WS_CLIPSIBLINGS ! (not +backgroundtrans) Aslo thanks for demystified windows behaviour.
just me
Posts: 9763
Joined: 02 Oct 2013, 08:51
Location: Germany

Re: Gui, z-order and static control

16 Oct 2013, 00:35

WS_CLIPSIBLINGS:
MSDN wrote:Clips child windows relative to each other; that is, when a particular child window receives a WM_PAINT message, the WS_CLIPSIBLINGS style clips all other overlapping child windows out of the region of the child window to be updated. If WS_CLIPSIBLINGS is not specified and child windows overlap, it is possible, when drawing within the client area of a child window, to draw within the client area of a neighboring child window.
Well, it seems clear now. The static controls are actually drawn from top to bottom, and without the WS_CLIPSIBLING style, the last drawn (the one at the bottom of the z-order) will paint over overlapping controls.

Return to “Bug Reports”

Who is online

Users browsing this forum: No registered users and 36 guests