Jump to content
Sign in to follow this  
CountyIT

[Solved] How do you detect what window(s) are obstructing another?

Recommended Posts

CountyIT

I have hit a delima. I have been tasked with a little project. I am going to pick on notepad for lack of anything better to pick on. I need to keep this one notepad document always forefront, always fully visible and not let anything obstruct its view. It must always be forefront and un-obstructed.

I can get the size and coordinates of this notepad window easily but I am stuck trying to determine what other window(s) might be overlapping it and obstructing its view. Any ideas?

Edited by CountyIT

Share this post


Link to post
Share on other sites
Jos

Should this window also always have the focus or are other windows allowed to have the focus as long as they do not overlap?


Visit the SciTE4AutoIt3 Download page for the latest versions  - Beta files                                How to post scriptsource        Forum Rules
 
Live for the present,
Dream of the future,
Learn from the past.
  :)

Share this post


Link to post
Share on other sites
CountyIT

I don't think it makes a lot of difference if this notepad window has focus or not. They just need to have a clear, un-obstructed view of it.

Share this post


Link to post
Share on other sites
MilesAhead

The help also uses Notepad in the example

WinSetOnTop("[CLASS:Notepad]", "", 1)

It's a good idea to get the handle to the particular window using WinGetHandle() in case another copy of notepad is opened or the user loads a different file changing the title etc..

Also you could periodically use

WinGetState() to see if someone has minimized the window or whatever.

Not sure what happens if some other window is set as Topmost after notepad. I would search MSDN Topmost and read how conflicts are resolved.

Edited by MilesAhead

Share this post


Link to post
Share on other sites
CountyIT

Yes there is a lot to be considered. I have been thinking about it. The real problem in a nutshell is how can you tell if one window is obstructing the view of another. I am not sure there is a way to determine this is there?

I mean even if you could determine, for instance by window coordinates, that two windows overlap or take up the same space that you can't really determine which on is on top can you? That would take some kind of 3D "depth" reading would it?

Share this post


Link to post
Share on other sites
MilesAhead

On another board I saw a suggestion that catching this msg will notify you

WM_WINDOWPOSCHANGED will let you know when the z-order has been changed...

the z order is the depth coordinate

edit: I'm sure there are example of registering a message handler on the forum. One method is GuiRegisterMsg().

Edited by MilesAhead

Share this post


Link to post
Share on other sites
Jos

Here you have something to play with.

The Script retrieves the Windows "above" the Window you specified in $Mywindow and displays all in a small window including indication whether they over lap your window or not.

#include <WindowsConstants.au3>
#include <GUIConstantsEx.au3>
Global $MyWindow = "Your Window Title"
Global $EditText, $S_EditText
Global $aWinInfo[1][7]
AdlibRegister("GetWinOnTopOnMine", 1000)
$hwin = GUICreate("Z-order Demo", 600, 100, 0, 0, Default, $WS_EX_TOPMOST)
$hEdit = GUICtrlCreateEdit("", 1, 1, 598, 98)
GUISetState()
; Run the GUI until the dialog is closed
While 1
    $msg = GUIGetMsg()
    Select
        Case $msg = $GUI_EVENT_CLOSE
            ExitLoop
    EndSelect
    $EditText = ""
    For $y = 0 To UBound($aWinInfo) - 1
        ; determine whether window is overlapping
        $EditText &= $aWinInfo[$y][6] ;X
        If $aWinInfo[$y][6] Then $EditText &= "*** OverLap***"
        $EditText &= "  POS="
        $EditText &= $aWinInfo[$y][1] ;X
        $EditText &= ":"
        $EditText &= $aWinInfo[$y][2] ;Y
        $EditText &= "  Size="
        $EditText &= $aWinInfo[$y][3] ;Width
        $EditText &= ":"
        $EditText &= $aWinInfo[$y][4] ;Height
        $EditText &= "  Title="
        $EditText &= $aWinInfo[$y][0]
        $EditText &= @CRLF
    Next
    If $EditText <> $S_EditText Then
        GUICtrlSetData($hEdit, $EditText)
        ConsoleWrite("Updated" & @CRLF)
        $S_EditText = $EditText
    EndIf
WEnd

Func GetWinOnTopOnMine()
    Local $var = WinList()
    ReDim $aWinInfo[UBound($var)][7]
    Local $NWin = 0
    Local $Overlap = 0
    $MyWinPos = WinGetPos($MyWindow)
    If @error Then
        MsgBox(0, "Error", "Your specified window title is not found: " & @lf & $MyWindow)
        Exit
    EndIf
    For $i = 1 To $var[0][0]
        ; Only check for visble windows
        If IsVisible($var[$i][1]) Then
            ; Check for MYWNDOW and exit when found
            If $var[$i][0] = $MyWindow Then
                ReDim $aWinInfo[$NWin][7]
                Return
            EndIf
            ; save all Window info of windows with an Higher Z-Order in an Array
            $WinPos = WinGetPos($var[$i][1])
            $aWinInfo[$NWin][0] = $var[$i][0]
            $aWinInfo[$NWin][1] = $WinPos[0]
            $aWinInfo[$NWin][2] = $WinPos[1]
            $aWinInfo[$NWin][3] = $WinPos[2]
            $aWinInfo[$NWin][4] = $WinPos[3]
            $aWinInfo[$NWin][5] = $var[$i][1]
            ; *** Check for Full overlap
            $Overlap = 0
            If $MyWinPos[0] > $WinPos[0] And $MyWinPos[0] + $MyWinPos[2] < $WinPos[0] + $WinPos[2] _
                    And $MyWinPos[1] > $WinPos[1] And $MyWinPos[1] + $MyWinPos[3] < $WinPos[1] + $WinPos[3] Then
                $Overlap = 1
                ; *** Check for app corners inside my window
                ; Check if left top is inside my window
            ElseIf $MyWinPos[0] < $WinPos[0] And $MyWinPos[0] + $MyWinPos[2] > $WinPos[0] _
                    And $MyWinPos[1] < $WinPos[1] And $MyWinPos[1] + $MyWinPos[3] > $WinPos[1] Then
                $Overlap = 2
                ; Check if left bottom is inside my window
            ElseIf $MyWinPos[0] < $WinPos[0] And $MyWinPos[0] + $MyWinPos[2] > $WinPos[0] _
                    And $MyWinPos[1] < $WinPos[1] + $WinPos[3] And $MyWinPos[1] + $MyWinPos[3] > $WinPos[1] + $WinPos[3] Then
                $Overlap = 3
                ; Check if Right Top is inside my window
            ElseIf $MyWinPos[0] < $WinPos[0] + $WinPos[2] And $MyWinPos[0] + $MyWinPos[2] > $WinPos[0] + $WinPos[2] _
                    And $MyWinPos[1] < $WinPos[1] And $MyWinPos[1] + $MyWinPos[3] > $WinPos[1] Then
                $Overlap = 4
                ; Check if Right bottom is inside my window
            ElseIf $MyWinPos[0] < $WinPos[0] + $WinPos[2] And $MyWinPos[0] + $MyWinPos[2] > $WinPos[0] + $WinPos[2] _
                    And $MyWinPos[1] < $WinPos[1] + $WinPos[3] And $MyWinPos[1] + $MyWinPos[3] > $WinPos[1] + $WinPos[3] Then
                $Overlap = 5
                ; Check for Myapp corners inside App
                ; Check if left top is inside my window
            ElseIf $WinPos[0] < $MyWinPos[0] And $WinPos[0] + $WinPos[2] > $MyWinPos[0] _
                    And $WinPos[1] < $MyWinPos[1] And $WinPos[1] + $WinPos[3] > $MyWinPos[1] Then
                $Overlap = 6
                ; Check if left bottom is inside my window
            ElseIf $WinPos[0] < $MyWinPos[0] And $WinPos[0] + $WinPos[2] > $MyWinPos[0] _
                    And $WinPos[1] < $MyWinPos[1] + $MyWinPos[3] And $WinPos[1] + $WinPos[3] > $MyWinPos[1] + $MyWinPos[3] Then
                $Overlap = 7
                ; Check if Right Top is inside my window
            ElseIf $WinPos[0] < $MyWinPos[0] + $MyWinPos[2] And $WinPos[0] + $WinPos[2] > $MyWinPos[0] + $MyWinPos[2] _
                    And $WinPos[1] < $MyWinPos[1] And $WinPos[1] + $WinPos[3] > $MyWinPos[1] Then
                $Overlap = 8
                ; Check if Right bottom is inside my window
            ElseIf $WinPos[0] < $MyWinPos[0] + $MyWinPos[2] And $WinPos[0] + $WinPos[2] > $MyWinPos[0] + $MyWinPos[2] _
                    And $WinPos[1] < $MyWinPos[1] + $MyWinPos[3] And $WinPos[1] + $WinPos[3] > $MyWinPos[1] + $MyWinPos[3] Then
                $Overlap = 9
                ; Check for app side go through MyApp
                ; Check Horizontal is inside my window
            ElseIf $MyWinPos[0] > $WinPos[0] And $MyWinPos[0] + $MyWinPos[2] < $WinPos[0] + $WinPos[2] _
                    And $MyWinPos[1] < $WinPos[1] And $MyWinPos[1] + $MyWinPos[3] > $WinPos[1] Then
                $Overlap = 10
                ; Check Vertical is inside my window
            ElseIf $MyWinPos[1] > $WinPos[1] And $MyWinPos[1] + $MyWinPos[3] < $WinPos[1] + $WinPos[3] _
                    And $MyWinPos[0] < $WinPos[0] And $MyWinPos[0] + $MyWinPos[2] > $WinPos[0] Then
                $Overlap = 11
            EndIf
            $aWinInfo[$NWin][6] = $Overlap
            $NWin += 1
        EndIf
    Next
    ConsoleWrite("- Not Found -----------------------------------------" & @LF)
EndFunc   ;==>GetWinOnTopOnMine

Func IsVisible($handle)
    If BitAND(WinGetState($handle), 2) Then
        Return 1
    Else
        Return 0
    EndIf
EndFunc   ;==>IsVisible

Jos :)

Edited by Jos
Some improvements
  • Like 1

Visit the SciTE4AutoIt3 Download page for the latest versions  - Beta files                                How to post scriptsource        Forum Rules
 
Live for the present,
Dream of the future,
Learn from the past.
  :)

Share this post


Link to post
Share on other sites
ajit

@Jos,

Thanks for that i had been struggling to find a solution to a similar problem without success

Regards,

Ajit

Share this post


Link to post
Share on other sites
CountyIT

Absolutely righteous! Thanks Jos!

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  

×