Sign in to follow this  
Followers 0
d233st

Z-Order, how to restore a window's position ?

13 posts in this topic

Neither WinGetpos() nor WinMove() functions deal with Z-Order information. That is the position (rather an order) of a window in a depth axis : the most below is the desktop (the wallpaper) and at all above the topmost windows.

It's useful to handle this when you want to activate a windows to click on it without messing with users windows disposition.

Do I need to use windows API for this ? If so, is there some example around ?

Share this post


Link to post
Share on other sites



Something like this maybe(??):

$window = "xxx"

If WinActive($window,"") = 0 Then
    WinActivate($window,"")
EndIf

UDF:Crypter a file encrypt / decrypt tool with no need to remember a password again. Based on Caesar cipher using entire ASCII Table.Script's: PixelSearch Helper, quick and simple way to create a PixelSeach.Chatserver - simplified, not so complicated multi-socket server.AutoIT - Firewall, simple example on howto create a firewall with AutoIt.

Share this post


Link to post
Share on other sites

Neither WinGetpos() nor WinMove() functions deal with Z-Order information. That is the position (rather an order) of a window in a depth axis : the most below is the desktop (the wallpaper) and at all above the topmost windows.

It's useful to handle this when you want to activate a windows to click on it without messing with users windows disposition.

Do I need to use windows API for this ? If so, is there some example around ?

WinList(), with no options, lists all windows in Z-order, allowing you to save the previous order in a 2D arra.

One usage of this is _WinPrevious().

:)


Valuater's AutoIt 1-2-3, Class... Is now in Session!For those who want somebody to write the script for them: RentACoder"Any technology distinguishable from magic is insufficiently advanced." -- Geek's corollary to Clarke's law

Share this post


Link to post
Share on other sites

thanks for your reply.

if I get it right, I have to activate every window I want above my window ?

Share this post


Link to post
Share on other sites

thanks for your reply.

if I get it right, I have to activate every window I want above my window ?

Good question. It's the only way I know of SETTING the z-order. The _WinAPI_GetWindow() function is kind of a teaser in that it gets windows based on z-order info, but there is no corresponding function to set the z-order that I know of (which ain't say'n much, smarter people may chime in here...).

:)


Valuater's AutoIt 1-2-3, Class... Is now in Session!For those who want somebody to write the script for them: RentACoder"Any technology distinguishable from magic is insufficiently advanced." -- Geek's corollary to Clarke's law

Share this post


Link to post
Share on other sites

Good question. It's the only way I know of SETTING the z-order. The _WinAPI_GetWindow() function is kind of a teaser in that it gets windows based on z-order info, but there is no corresponding function to set the z-order that I know of (which ain't say'n much, smarter people may chime in here...).

:)

I remember from the time I started with Visual Basic 5 - 6 there was a way to set z-order (through a function or a property).

I'll check that later, I'll post here if I go further with this issue.

Share this post


Link to post
Share on other sites

actually, I think the VB thing concerns controls in a form, not windows on the desktop

Share this post


Link to post
Share on other sites

Good question. It's the only way I know of SETTING the z-order. The _WinAPI_GetWindow() function is kind of a teaser in that it gets windows based on z-order info, but there is no corresponding function to set the z-order that I know of (which ain't say'n much, smarter people may chime in here...).

:)

It looks like you can use _WinAPI_SetWindowPos to set the z-order, by use of the $hAfter parameter. I tried but couldn't get anywhere, if PsaltyDS or anyone else can code an example I'd be very interested.

I'll keep trying too maybe I'll get somewhere... :)


While ProcessExists('Andrews bad day.exe')
	BlockInput(1)
	SoundPlay('Music.wav')
	SoundSetWaveVolume('Louder')
WEnd

Share this post


Link to post
Share on other sites

It looks like you can use _WinAPI_SetWindowPos to set the z-order, by use of the $hAfter parameter. I tried but couldn't get anywhere, if PsaltyDS or anyone else can code an example I'd be very interested.

I'll keep trying too maybe I'll get somewhere... :)

I don't think $hAfter is going to do it:

$hAfter Identifies the window to precede the positioned window in the Z order. This parameter must be a

window handle or one of the following values:

$HWND_BOTTOM - Places the window at the bottom of the Z order

$HWND_NOTOPMOST - Places the window above all non-topmost windows

$HWND_TOP - Places the window at the top of the Z order

$HWND_TOPMOST - Places the window above all non-topmost windows

You can only select top and bottom positions, not the middle ones. If you have 10 windows, you can't specify third from the bottom...

:)


Valuater's AutoIt 1-2-3, Class... Is now in Session!For those who want somebody to write the script for them: RentACoder"Any technology distinguishable from magic is insufficiently advanced." -- Geek's corollary to Clarke's law

Share this post


Link to post
Share on other sites

I'd say hAfter is the handle of the 2nd window in your example

Share this post


Link to post
Share on other sites

Well I got somewhere! Its a little hard to give a perfect reproducer, but essentially just create several windows and cascade them in some manner so you'll be able to 'see' when a window is activated, and then returned to its z-order.

I made it into a function but I'll show the code with/without...

#Include <WinAPI.au3>
#include <Constants.au3>

Global $iInsert

$hScite = WinGetHandle("C:\Documents and Settings") ; this and line below just to force minimize scite
WinSetState($hScite, "", @SW_MINIMIZE )
;Sleep(1000) ;can uncomment if minimize is too slow

$1 = WinGetHandle("Untitled") ;notepad
$2 = WinGetHandle("Google") ; IE
$3 = WinGetHandle("Local Disk") ; windows explorer
$4 = WinGetHandle("Autoit Help") ; help file

$hHandle = $3 ;window to restore z order of
$iInsert = _Restore_Z_Order($hHandle, $iInsert)
WinActivate($hHandle)
Sleep(1000)
_Restore_Z_Order($hHandle, $iInsert)




Func _Restore_Z_Order($hWnd, $hInsert = "")
    Local $aPOS
    If $iInsert = "" Then
        $hInsert = _WinAPI_GetWindow($hWnd, $GW_HWNDNEXT)
        Return $hInsert
    Else
        $aPOS = WinGetPos($hWnd)
        _WinAPI_SetWindowPos($hWnd, $hInsert, $aPOS[0], $aPOS[1], $aPOS[2], $aPOS[3], $SWP_NOMOVE)
    EndIf
EndFuncoÝ÷ Ùh­­¶ºw#ºËn±æ®¶­sbb33c¶æFÆRÒb33c³0¢b33c¶ç6W'BÒõväôvWEvæF÷rb33c¶æFÆRÂb33c´uuôtäDäUB¢b33c¶õ2ÒvävWE÷2b33c¶æFÆR¥vä7FfFRb33c¶æFÆR¥6ÆVW¥õväõ6WEvæF÷u÷2b33c¶æFÆRÂb33c¶ç6W'BÂb33c¶õ5³ÒÂb33c¶õ5³ÒÂb33c¶õ5³%ÒÂb33c¶õ5³5ÒÂb33cµ5uôäôÔõdR

Its not perfect though. For some reason the internet explorer window was the buggiest... I must be missing something but I really don't know what. Seems everything but the IE window always works, and IE works only sometimes, but I can't put my finger even on conditionally what seems to work/not work with it.

Also, you should be able to replace $hInsert with another handle and it will place the window one behind that z-order.


While ProcessExists('Andrews bad day.exe')
	BlockInput(1)
	SoundPlay('Music.wav')
	SoundSetWaveVolume('Louder')
WEnd

Share this post


Link to post
Share on other sites

I'd say hAfter is the handle of the 2nd window in your example

Yeah, I missed that. The example by someone clarified it.

You couldn't just set the third from bottom (my example), you'd have to work your way down (or up) and set the one before it first. But it looks like it would work.

:)


Valuater's AutoIt 1-2-3, Class... Is now in Session!For those who want somebody to write the script for them: RentACoder"Any technology distinguishable from magic is insufficiently advanced." -- Geek's corollary to Clarke's law

Share this post


Link to post
Share on other sites

Here's my version. Works basically : it cares only abouy yhe ZOrder. So if windows was initally minimized, it won't be restored to its minimized state. This can easily be done, but I think it should be kept out of this function.

The function itself :

#Include <WinAPI.au3>
;;;
;;; Function _RestoreZOrder($windowHandle, $InitialWinList)
;;; Description : move a window to the Z-Order it was in the windows list you provide
;;; Returns : false if failed
;;; Throw Error=1 if window wasn't found 
;;;   Error=2 if window is not in the WinList
;;; $windowHandle = handle of the window to be moved 
;;; $InitialWinList = initial window list returned by Winlist()
;;;
Func _RestoreZOrder($windowHandle, $InitialWinList)

    If WinExists($windowHandle) == 0 then 
    SetError(2); window is not found
    return false
    EndIF
    
   ; step up in ZOrder until we find our window
    For $i =1  to  $InitialWinList[0][0]
    If $InitialWinList[$i][1] == $windowHandle Then
        ; now, step down until we determined a visible window 
         For $j = $i - 1 To 1 Step -1   
         ; count only visible windows
          If BitAnd( WinGetState($InitialWinList[$i][1]), 2 ) Then 
            $justabovewindowindex = $j;
            ExitLoop
          EndIf
         Next

        ; Now, place our window behind the determined window
         $SWP_NOSIZE = 1 ;
         $SWP_NOMOVE = 2;
         $ret = _WinAPI_SetWindowPos($windowHandle, $InitialWinList[$justabovewindowindex][1], 20, 20, 20, 20, $SWP_NOSIZE Or $SWP_NOMOVE)
         return $ret;
    EndIf
    Next
    
    SetError(1); window handle not found in the list
    return false
EndFunc

Use example (you need a Notepad window opened)

;;;
;;; Example of use
;;;
$windowtoactivate = WinGetHandle("Notepad") ; get the handle of the window we want to use
$InitialZOrder = Winlist()  ; Get the list of all windows, we'll need it as a function parameter  


WinActivate($windowtoactivate)  ; brring our window to front and set focus
Sleep(1000);            ; do whatever you want with this window
_RestoreZOrder($windowtoactivate, $InitialZOrder);

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  
Followers 0