Jump to content

How can I identify "Normal" windows?


Recommended Posts

I've been struggling to find a way to identify what I'll call "Normal" windows (for lack of a better term). These are application windows as opposed to those windows which underlie applications. Some examples of Normal windows would include: A web browser (just the main window rather than a separate one for each open web page), a Text Editor, an Email application, RegEdit, Notepad, VLC, and so forth. But when I call WinList(), I get roughly 300 windows. Some of these ostensible "windows" are actually mere GUI controls, such as OK buttons and the like, which seems curious to me, but I excluded them. I just can't find a consistent way of separating Normal windows from the hundreds of other windows of various types. Note that minimized windows are included as Normal if they're otherwise Normal.

Eliminating windows with null titles and without $WS_EX_TOOLWINDOW and invisible ones helped a lot, but frustratingly the several other possible attributes are seemingly arbitrary even on just the Normal windows.

I looked into working from a process list instead of a window list, but that didn't pan out either.

Below is a snippet showing most of my Normal window selection function. I've also attached a report text file that lists the attributes of only those windows which make the Normal cut. You'll see how many of them are not Normal by my definition. How can I narrow this down further, please?

 

Thanks!

 

Func CreateSrcWinTable()


    Local $Lf_WinHdl, $Lf_ThisWinHdl, $Lf_ThisWinClass, $Lf_WinVisible, $Lf_WinEnabled
    Local $Lf_WinActive, $Lf_WinTableIx, $Lf_Left, $Lf_Right, $Lf_ThisWinState, $Lf_ThisExtStyle
    Local $Lf_ThisTitle, $Lf_ThisProcName, $Lf_MonForWin, $Lf_TitleSize, $Lf_NumAllWins, $Lf_WinMinimized
    Local $Lf_WinIconic, $Lf_ThisClassName, $Lf_ThisExtStyle, $Lf_ThisWinPID, $Lf_ThisProcName
    Local $Lf_StringSizeAra[4]

    Local $Lf_ThisWinRect = DllStructCreate($tagRect)

    Local $Lf_RptFileHdl = FileOpen( @ScriptDir & "\Report.txt", $FO_OVERWRITE + $FO_UTF8_NOBOM )

    Local $Lf_WinAra = WinList()
    $Lf_NumAllWins = $Lf_WinAra[0][0]
    If $Lf_NumAllWins = 0 Then
        Return 0
    EndIf

    For $i = 1 To $Lf_NumAllWins

        $Lf_ThisTitle = $Lf_WinAra[$i][0]
        If StringStripWS($Lf_ThisTitle, $STR_STRIPALL) = "" Then
            ContinueLoop
        EndIf

        $Lf_ThisWinHdl = $Lf_WinAra[$i][1]
        $Lf_ThisWinRect =_WinAPI_GetWindowRect( $Lf_ThisWinHdl )
        $Lf_Left = DllStructGetData( $Lf_ThisWinRect, "Left" )
        $Lf_Right = DllStructGetData( $Lf_ThisWinRect, "Right" )

        If ($Lf_Left >= 0) And ($Lf_Right <= 1920) Then ; If this window is on the primary monitor...
            $Lf_MonForWin = 0
        Else
            $Lf_MonForWin = 1
        EndIf

        $Lf_ThisWinState = WinGetState( $Lf_ThisWinHdl )

        If BitAND( $Lf_ThisWinState, $WIN_STATE_VISIBLE ) Then
            $Lf_WinVisible = True
        Else
            $Lf_WinVisible = False
        EndIf

        If BitAND( $Lf_ThisWinState, $WIN_STATE_ENABLED ) Then
            $Lf_WinEnabled = True
        Else
            $Lf_WinEnabled = False
        EndIf

        If BitAND( $Lf_ThisWinState, $WIN_STATE_ACTIVE ) Then
            $Lf_WinActive = True
        Else
            $Lf_WinActive = False
        EndIf

        If BitAND( $Lf_ThisWinState, $WIN_STATE_MINIMIZED ) Then
            $Lf_WinMinimized = True
        Else
            $Lf_WinMinimized = False
        EndIf

        If _WinAPI_IsIconic( $Lf_ThisWinHdl ) Then
            $Lf_WinIconic = True
        Else
            $Lf_WinIconic = False
        EndIf

        $Lf_ThisClassName   = _WinAPI_GetClassName( $Lf_ThisWinHdl )
        If StringInStr( $Lf_ThisClassName, "Button", $STR_NOCASESENSEBASIC ) > 0 Then
            ContinueLoop
        EndIf

        $Lf_ThisExtStyle    = _WinAPI_GetWindowLong( $Lf_ThisWinHdl, $GWL_EXSTYLE )
        $Lf_ThisWinPID      = WinGetProcess( $Lf_ThisWinHdl )
        $Lf_ThisProcName    = _ProcessGetName( $Lf_ThisWinPID )
        If $Lf_ThisProcName = "" Then
            ContinueLoop
        EndIf


        If NOT BitAND( $Lf_ThisExtStyle, $WS_EX_TOOLWINDOW ) Then   ; Only look at windows without $WS_EX_TOOLWINDOW extended style

            If $Lf_WinVisible Then

                Local $Lf_Text = "Win # " & $i & " -- Title: '" & $Lf_ThisTitle & "' -- Proc Name: " & $Lf_ThisProcName _
                    & @CRLF & " -- Class Name: " & $Lf_ThisClassName & " -- Enabled? " & $Lf_WinEnabled & " -- Mimimized? " _
                    & $Lf_WinMinimized & " -- Iconic? " & $Lf_WinIconic
                FileWriteLine( $Lf_RptFileHdl, $Lf_Text & @CRLF & @CRLF )

                $Lf_WinTableIx += 1

            EndIf

        EndIf

    Next

    FileClose( $Lf_RptFileHdl )

    If $Lf_WinTableIx = 0 Then
        Return -2
    EndIf

    $G_WinTableCount = $Lf_WinTableIx

    Return 1

EndFunc

 

 

Report.txt

Edited by Mbee
Link to post
Share on other sites

Maybe this ?

#include <WinAPISysWin.au3>

Example()

Func Example()
  Local $aList = WinList()
  Local $sList = ""
  For $i = 1 to $aList[0][0]
    If $aList[$i][0] <> "" And BitAND(WinGetState($aList[$i][1]), 2) Then
      If Not _WinAPI_GetParent ($aList[$i][1]) Then
        $sList &= $aList[$i][0] & @CRLF
      EndIf
    EndIf
  Next
  MsgBox ($MB_SYSTEMMODAL,"",$sList)
EndFunc   ;==>Example

 

Link to post
Share on other sites

Thanks enormously, @Nine !  I'd tried looking at parents, children, and ancestors, but I didn't see anything that might be helpful. It never occurred to me to check to see if the window in question simply had a parent or not, but that did the trick. Sure, I'll still have to weed out a few OS windows, but they're straightforward to recognize and eliminate.

Thanks again!

Edited by Mbee
Link to post
Share on other sites

There is 2 more API you could investigate :  

GetWindow with the GW_OWNER

 GetAncestor with the GA_PARENT

Honestly I never tried it...

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
  • Recently Browsing   0 members

    No registered users viewing this page.

×
×
  • Create New...