What does the Windows Analysis script do? The Windows Analysis script (analysis.wbt) creates a report on the windows visible at the time the report is run. The basic technique is to open the application and get the dialog boxes you are interested in displayed on the screen. This Window Analysis script will display output detailing the contents of the window in question.
How do I use it? Run the script, by double clicking on analysis.wbt (which is most likely located in the WinBatch\Samples subdirectory). A dialog with all the visible window titles, will appear. Choose the window of interest. The Window Analysis script will process and display the results. Each window and control has its own unique window handle (often seen as hWnd or Wnd). Use the output of the Window Analysis script and the various cWndBy... functions in this extender to obtain the handle to the window or control you need, then use the specific functions designed for each type of control to either obtain information about the item, or to set it to the desired value. The relationships, names, IDs, and exactly what windows controls are on the screen can get confusing. To help sort it out, run your application, and get to the point where the windows of interest are visible on the screen. Then run this script. It will create a report detailing the relationships between the windows and controls in your application. You can usually pick off window IDs, Names, and sequence numbers from the list to use in the Control Manager extender functions. The IDs are usually the best to use if possible since they are unique, then the titles, then the sequence numbers. The sequence numbers are the most likely to change unexpectedly...
|
|
;*************************************************************************** ;** Window Analysis Script ;** ;** This script creates a report on the windows visible at the time ;** the report is run. Run the script. Choose a top-level ;** window of interest, and it will show pertinent information ;** that may be necessary to use the Control Manager extender. ;** ;** Note that Tabbed dialogs sometimes must be displayed before ;** their controls are brought into existence. So when using ;** tabbed dialogs, tab to the correct dialog first. The ;** cWndInfo example shows how to move through a tabbed dialog. ;** ;** Revisions: ;** 6.0 July 7th 2011 ;** Load 64 bit Control manager when running 64 bit version of WinBatch. ;** ;** 5.0 Jan 7th 2010 ;** FIX: Handle titles with embedded double quotes. Fixes issue with ;** ItemExtractCSV returning error 1707. ;** ;** 4.0 Sept 4th 2009 ;** FIX: Handle strings with embedded linefeeds. Fixes issue with ;** ArrayFileGetCSV returning error 1808. ;** ;** 3.0 Sept 29th 2008 ;** FIX: Handle Windows Names that contain a comma. ;** ;** 2.0 ; ** Initial Release ;** ;*************************************************************************** thisver = '6.0' thistitle = 'Window Analysis' csvfile ='Analysis.csv' htmfile ='Analysis.htm' ; Application Data directory to store CSV file output appdatadir = ShortCutDir( 'AppData', 0 , @TRUE ) : 'WinBatch\Temp\' ;Check if dir exists. it not create it If !DirExist( appdatadir ) Then DirMake( appdatadir ) ;if this is already running then exit If WinExist( thistitle ) WinActivate( thistitle ) Exit EndIf ;Tell Winbatch to be greedy Exclusive(@ON) ;Load the Control Manager Extender If WinMetrics(-3) == 5 Then AddExtender( 'wwctl64i.dll' ) Else AddExtender( 'wwctl44i.dll' ) ;Handle errors ;Intcontrol( 73, 1, 0, 0, 0 ) ; Use Goto ErrorHndlr ;Change to current working directory wbtdir = FilePath( IntControl( 1004, 0, 0, 0, 0 ) ) DirChange( wbtdir ) ;Get list of all windows currently on the screen wins = WinItemize( ) If AskYesNo( 'Ok to Ignore', 'Duplicate, hidden and iconized windows will be removed from the list' ) == @YES AskMsg = 'Duplicate, hidden and iconized windows are not shown.' AskList = '' aCnts = ItemCount(wins, @TAB) For aCnt = 1 To aCnts Win = ItemExtract(aCnt, wins, @TAB) If (WinState(Win)!=-1 && WinState(Win)!=1) If !ItemLocate(Win, AskList, @TAB) Then AskList = ItemInsert(Win, -1, AskList, @TAB) EndIf Next Else AskMsg = 'Showing all windows.' Asklist = wins EndIf trgWnd = AskItemlist(AskMsg, AskList, @TAB, @SORTED, @SINGLE) ;Get chosen window handle hWnd=DllHwnd(trgWnd) ; Some error checking from the help file to make sure we have a valid handle to the target window. hwndChk = DllHwnd(trgWnd) Spec = cWndGetWndSpec(hwndChk) ; Get the window specification. hWnd = cWndByWndSpec(%Spec%) ; Get the handle by the window specification. If hWnd!=hwndChk ; Make sure the result matches the original handle Pause('ERROR!', "Could not get valid handle for %trgWnd% window.%@crlf%Exiting program.") ClipPut(Spec) Goto CANCEL EndIf GoSub InitUDFs ;Get maximum number of child levels maxlevel = udfMaxLevelCount( hWnd, 1, 0 ) ;include parent by setting level to one ;Get total number of child windows wincnt = udfWinCount( hWnd, 0 ) ;Initialize database ; Format: ; RowNumber, MaxLevels, ParentCount, [Child1, Child2, Child3, Etc ] , Class , Id , Title , WndStyle, WndStyleEx, ClassStyle staticcols = 9 data = ArrDimension( wincnt, maxlevel + staticcols - 1 ) ; Subtract one because Parent is included in maxlevel ArrInitialize(data, '') ;Get Window data info = udfGetWndInfo( hWnd ) name = ItemExtractCSV( 1, info, 1 ) name = StrReplace( name, @LF, ' ' ) ; 4.0 fix id = ItemExtractCSV( 2, info, 1 ) class = ItemExtractCSV( 3, info, 1 ) wndsytle = ItemExtractCSV( 11, info, 1 ) wndstyleex = ItemExtractCSV( 12, info, 1 ) classstyle = ItemExtractCSV( 13, info, 1 ) ; RowNumber, MaxLevels , ParentCount, [Child1, Child2, Child3, Etc ] , Class , Id , Title , WndStyle, WndStyleEx, ClassStyle data[0, 0] = 0 ;RowNumber data[0, 1] = maxlevel ;MaxLevels data[0, 2] = 0 ;Parent ;data[0, 3] = level ; ;*Ignore* Child Windows data[0, maxlevel+2 ] = class ;Class data[0, maxlevel+3 ] = id ;ID data[0, maxlevel+4 ] = name ;Title data[0, maxlevel+5 ] = wndsytle ;WndStyle data[0, maxlevel+6 ] = wndstyleex ;WndStyleEx data[0, maxlevel+7 ] = classstyle ;ClassStyle ;Initalize Level level = 0 ;Gather CSV data about the window into the data array udfGetWinData( hWnd, level, maxlevel, data ) ; Write out CSV the Application Data\Temp (C:\Documents and Settings\Deana\Application Data\WinBatch\Temp) appdatadir = ShortCutDir( 'AppData', 0 , @TRUE ) : 'WinBatch\Temp\' ;Check if dir exists. it not create it If !DirExist( appdatadir ) Then DirMake( appdatadir ) ArrayFilePutCSV( appdatadir : csvfile, data ) ;Run(appdatadir : csvfile, '') ;Run('Notepad.exe', appdatadir : csvfile ) ;*************************************************************************** ;** ;** Read CSV create HTML Table ;** ;*************************************************************************** headcolor = '#C0C0C0' colcolors = '#EEEEFF,#DDDDFF,#CCCCFF,#BBBBFF,#AAAAFF,#9999FF' greytext = '#808080' greybkgrnd = '#DBEADC' greenbkgrnd = '#BAFEA3' ; Write out CSV the Application Data\Temp (C:\Documents and Settings\Deana\Application Data\WinBatch\Temp) appdatadir = ShortCutDir( 'AppData', 0 , @TRUE ) : 'WinBatch\Temp\' ;Check if dir exists. it not create it If !DirExist( appdatadir ) Then DirMake( appdatadir ) csvdata = ArrayFileGetCSV(appdatadir : csvfile, 0) ; Database Format: ; RowNumber, MaxLevels, Parent, [Child1, Child2, Child3, Etc ] , Class , Id , Title , WndStyle, WndStyleEx, ClassStyle ;Read max level from data maxlevel = csvdata[0,1] ;Read parent windowname topwin = csvdata[0,maxlevel + 4] handle = FileOpen( appdatadir: htmfile, 'Write') FileWrite(handle, '<HTML>') FileWrite(handle, '<HEAD></HEAD>') FileWrite(handle, '<TITLE>' : thistitle: '</TITLE>') FileWrite(handle, ' <!-- <DEFANGED_STYLE type="text/css"><!--p {font-family: Courier, monospace;font-size: 9pt;}TD{font-family: Courier, monospace; font-size: 9pt;}TH{font-family: Courier, monospace; font-size: 9pt;}--> --> </DEFANGED_STYLE>') FileWrite(handle, '<BODY>') FileWrite(handle, '<H2>': thistitle : ' ' : thisver : '</H2><P>' : 'Windowname : ': topwin: '<BR>') FileWrite(handle, 'Max Level : ' : maxlevel : '<P>' ) FileWrite(handle, '<TABLE border="1" cellpadding="5">' ) ; Write header for table FileWrite(handle, '<TR bgcolor="':headcolor:'">' ) FileWrite(handle, '<TH>Parent<BR> </TH>' ) For count = 1 To maxlevel-1 FileWrite(handle, '<TH>Child<BR>': count :'</TH>' ) If count == maxlevel - 1 FileWrite(handle, '<TH> </TH>' ) ; Write a blank col at the end of all the child windows EndIf Next FileWrite(handle, '<TH>Class</TH>' ) FileWrite(handle, '<TH>Id</TH>' ) FileWrite(handle, '<TH>Name</TH>' ) FileWrite(handle, '<TH>WndStyle</TH>' ) FileWrite(handle, '<TH>WndStyleEx</TH>' ) FileWrite(handle, '<TH>ClassStyle</TH>' ) FileWrite(handle, '</TR>' ) greenflag = 0 For darow = 0 To ArrInfo(csvdata, 1 )-1 FileWrite(handle, '<TR>' ) For dacol = 2 To ArrInfo(csvdata, 2 )-1 data = csvdata[darow, dacol] ;Compare to previous data if one of the parent/child columns If dacol <= maxlevel+1 ;Special Handling for first row If darow == 0 Then prevrow = '' Else prevrow = csvdata[darow-1, dacol] ;Need to decide Whether to Write in grey or green. If data == prevrow && greenflag == 0 ; if previous row matches current rowdata and green flag set to false ;if data == csvdata[darow-1, dacol];if previous row matches current rowdata FileWrite(handle, '<TD bgcolor="':greybkgrnd:'"><FONT COLOR="':greytext:'">' ); Grey Else FileWrite(handle, '<TD bgcolor="':greenbkgrnd:'">' ); Green greenflag = 1 EndIf If data == '' FileWrite(handle, ' ' ) Else FileWrite(handle, data ) EndIf FileWrite(handle, '</FONT></TD>' ) If dacol == maxlevel+1 ; Write a blank col at the end of all the child windows FileWrite(handle, '<TD bgcolor="':greybkgrnd:'"> </TD>' ); Grey Empty Col EndIf Else ;Colorize all non - child window columns ;Get RGB rgb = ItemExtract( dacol-maxlevel-1, colcolors, ',' ) FileWrite(handle, '<TD bgcolor=': rgb : '>' ) If data == '' FileWrite(handle, ' ' ) Else FileWrite(handle, data ) EndIf FileWrite(handle, '</TD>' ) EndIf Next greenflag = 0 FileWrite(handle, '</TR>' ) Next FileWrite(handle, '</TABLE>' ) FileWrite(handle, '</BODY>') FileWrite(handle, '</HTML>') FileClose( handle ) Run( appdatadir: htmfile, '') Exit ;*************************************************************************** ;** ;** User Defined Functions ;** ;*************************************************************************** :InitUDFs #DefineFunction udfMaxLevelCount( WorkWnd, Level, MaxLevel ) level = level + 1 ;Locate child nextchild = cWndinfo( workwnd, 8 ) While nextchild ;Keep track of the highest level number If level > MaxLevel MaxLevel = level EndIf ;Recurse MaxLevel = udfMaxLevelCount( nextchild, level, MaxLevel ) ;Get next Sibling nextchild = cWndinfo( nextchild, 6 ) EndWhile Return MaxLevel #EndFunction ;udfMaxLevelCount #DefineFunction udfWinCount( WorkWnd, count ) count = count + 1 ;Locate child nextchild = cWndinfo( workwnd, 8 ) While nextchild ;Recurse count = udfWinCount( nextchild, count ) ;Get next Sibling nextchild = cWndinfo( nextchild, 6 ) EndWhile Return count #EndFunction ;udfWinCount #DefineFunction udfGetWinData( WorkWnd, level, maxlevel, data ) delim = ',' level = level + 1 ;Keep track of row number ptr_rowcount = PtrPersistent( rowcount, 0 ) *ptr_rowcount = *ptr_rowcount + 1 ;Locate child nextchild = cWndinfo( workwnd, 8 ) count = 0 While nextchild count = count+1 ;Keeps track of Childcount windows ;Pause(count, *ptr_prevchild) ; Get Window Data info = udfGetWndInfo( nextchild ) name = ItemExtractCSV( 1, info, 1 ) name = StrReplace( name, @LF, ' ' ) ; 4.0 fix id = ItemExtractCSV( 2, info, 1 ) class = ItemExtractCSV( 3, info, 1 ) wndsytle = ItemExtractCSV( 11, info, 1 ) wndstyleex = ItemExtractCSV( 12, info, 1 ) classstyle = ItemExtractCSV( 13, info, 1 ) ; RowNumber, MaxLevels , ParentCount, [Child1, Child2, Child3, Etc ] , Class , Id , Title , WndStyle, WndStyleEx, ClassStyle row = *ptr_rowcount data[row, 0] = row+1 ;RowNumber - add one because parent already written data[row, 1] = maxlevel ;MaxLevels data[row, 2] = 0 ;ParentCount will always be zero ; HandleChild Windows ; Keep track of previous childs For col = 3 To level+2 ;Loop once for each child ;Grab data from previous rows column prevdata = data[row-1, col] ;Check if col is equal to the current level plus 2 If col == level+2 data[row, level+2] = count ; insert child count number Else data[row, col] = prevdata ; insert data from previous line EndIf Next data[row, maxlevel+2 ] = class ;Class data[row, maxlevel+3 ] = id ;ID data[row, maxlevel+4 ] = name ;Title data[row, maxlevel+5 ] = wndsytle ;WndStyle data[row, maxlevel+6 ] = wndstyleex ;WndStyleEx data[row, maxlevel+7 ] = classstyle ;ClassStyle ;Recurse data = udfGetWinData( nextchild, level, maxlevel, data ) ;Get next Sibling nextchild = cWndinfo( nextchild, 6 ) EndWhile Return data #EndFunction ;udfGetWinData #DefineFunction udfGetWndInfo( WorkWnd ) ;Returns a delimited list of Window information delim = ',' Title = cWndinfo(WorkWnd, 0) Title = StrReplace( Title, '"', '""' ); 5.0 fix : Replace any embedded doublequotes in the title with double doublequotes ID = cWndinfo(WorkWnd, 1) Class = cWndinfo(WorkWnd, 2) Parent = cWndinfo(WorkWnd, 3) FirstSibling = cWndinfo(WorkWnd, 4) PreviousSibling = cWndinfo(WorkWnd, 5) NextSibling = cWndinfo(WorkWnd, 6) LastSibling = cWndinfo(WorkWnd, 7) FirstChild = cWndinfo(WorkWnd, 8) Owner = cWndinfo(WorkWnd, 9) WndStyle = cWndinfo(WorkWnd, 20) WndStyleEx = cWndinfo(WorkWnd, 21) ClassStyle = cWndinfo(WorkWnd, 22) info = '"':Title:'"':delim:ID:delim:Class:delim:Parent:delim:FirstSibling:delim:PreviousSibling:delim:NextSibling:delim:LastSibling:delim:FirstChild:delim:Owner:delim:WndStyle:delim:WndStyleEx:delim:ClassStyle Return info #EndFunction ;udfGetWndInfo Return ;*************************************************************************** ;** ;** Cancel and Error Handling ;** ;*************************************************************************** :CANCEL Exit :WBERRORHANDLER wErrFile = thisVer wError=LastError() wErrStr = IntControl(34,wError,0,0,0) wErrLine = wberrorhandlerline wErrOffset = wberrorhandleroffset wErrAssign = wberrorhandlerassignment wErrMessage = 'Please email this info:%@CRLF%%@tab%"%wErrRptFile%"%@CRLF%to support@winbatch.com with the Subject line "Analysis Error"' wErrTxt = StrCat(`wErrFile = `, wErrFile, @CRLF, `wError = `, wError, @CRLF, `wErrStr= `, wErrStr, @CRLF, `wErrLine = `, wErrLine, @CRLF, `wErrOffset = `, wErrOffset,@CRLF, `wErrAssign = `, wErrAssign, @CRLF, @CRLF, wErrMessage) Pause( 'Notice', wErrTxt) ClipPut(wErrTxt) Goto CANCEL