Can't find the information you are looking for here? Then leave a message over on our WinBatch Tech Support Forum.
; **************************************************************************************** ; ; REQUIRES WinBatch 2003 ; ; **************************************************************************************** goto Main ;------------------------------------------------------------------------------------------ These comments are from the original Analysis script which is distributed with WinBatch: "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." In modifying the original script I had a twofold goal: 1) A personal project hit a bottleneck when it had to access a non-standard List-view control. The only way to perhaps overcome the bottleneck in my project was to have a better understanding of the information returned by the Analysis script. 2) Beyond the challenge to my understanding I found the presentation of the information in the Analysis script left something to be desired hence AnalysisEx. This script contains a UDF, udfGetHWnd, which is meant to augment the functionality of RoboScripter, not replace it. I wanted a way to test methods of drilling down to a control and wound up with a tool that let me master the EvilApp as a result. Perhaps, your EvilApp has a non-standard Treeview. Or you want avoid the time delay in some of Control Manager's window functions while your code tests different methods of getting to the target control. Using AnalysisEx and testing various criteria with Interactive Drilldown may provide the handle your code needs. I think the interface is fairly obvious but just in case: The "+/-" button is to reset the Tree expansion to the value shown in the UpDown control. It seems to work most of the time ;-) "Refresh" just updates the visible windows column if you change something in the target. The first column in the ListView is a session handle for the controls and is useful for verifying the results of queries. The Window column serves no useful purpose now that I've finished the project but... It shows the order in which the controls were found and the number found. "Show Controls" could probably use some work but I like it nonetheless. Whenever I use RoboScripter, I always find myself wondering about all these windows that the code is drilling down thru. Select any control(s) in the ListView and click the button and to see where they are or at least where they're hiding. Open a few files in Studio maximize one of them and run AnalysisEx to see what I mean. A final note. AnalysisEx finds more controls than the original script but I doubt that they're of any use. I haven't bothered to track down exactly which controls are missed by Analysis.wbt. Version History: Ver 1.0.0 Presents essentially the same information as the original script using a Tree-view and List-view controls with the option to save the results in a "report" which provides the same information as the original script. Ver 1.0.1 Added a show controls action. Fixed. Script would crash if you set UD to 0, prior to selecting either the Tvw or Lvw. Fixed. Changing levels was not ensuring that the current Tvw item was visible. Ver 1.0.2 Adds the ability to expand/collapse the tree to any level. Fixed. There was no "if Tests then return WorkWnd" after first "gosub Eval" before the code enters the while loop in udfGetHWnd. Ver 1.0.3 Added Drilldown Interactive using using udfGetHWnd Added an initial listing of all the WrkWnd handles to provide the user with check values for Interactive sessions. Inserted commentted line "if dllcall(user32, long:"GetFocus")==hEd", in the Main loop, as there may be a problem with earlier versions of Control Manager. Ver 1.0.4 - Modified the interactive interface. Changed ddFldList to a DropDown list, FldCbx. Clicking its buddy button appends the variable to the current query. Added a DropDown list for classes found with the same functionality as FldCbx. Ver 1.0.5 Forgot to run Gather on ver 1.0.4 changes and udfGetHwnd was not added to the LoadStuff code. Added code to skip hidden and iconized windows in the AskItemList() box. Ver 1.0.5b Made the skipping of hidden and iconized windows optional. Changed the massaging of the windows list to remove duplicates if user chooses to skip hidden and iconized windows. Fixed. Logic in Next/Previous control was wrong and the script would crash if the user initially tried to goto the previous control. ;------------------------------------------------------------------------------------------ :UpdateViews if !isdefined(aryVis) aryVis = arrdimension(300, 0, 0, 0, 0) arrinitialize(aryVis, 0) endif Swap = @false if hLvw==Lvw1 hNext = Lvw2 else hNext = Lvw1 endif csendmessage(hNext, 4105, 0, 0) ; LVM_DELETEALLITEMS lvNext = -1 visList = '' for winCnt = 0 to winCnts tvItem = Ary[winCnt, 1] binarypoke4(Rect, 0, tvItem) if csendmessage(hTvw, 4356, 0, pRect) aryVis[winCnt] = 1 visList = iteminsert(tvItem, -1, visList, tab) lvNext = lvNext+1 else aryVis[winCnt] = 0 tvItem = 0 ; TVM_GETITEMRECT returns false for unexpanded items. endif lvItem = aryLv[lvNext, 1] if tvItem==lvItem ; Just writting visible items to hNext, doesn't affect Swap flag. if winCnt==0 lvCnt = -1 endif Cnt = udfTvGetParam(hTvw, Tvi, tvItem) newNode = tvItem gosub LvInsertItem continue endif if tvItem ; Tree has expanded add new nodes and set Swap. Swap = @true Cnt = udfTvGetParam(hTvw, Tvi, tvItem) newNode = tvItem gosub LvInsertItem endif next f00 = csendmessage(hLvw, 4100, 0, 0)-1 ; LVM_GETITEMCOUNT Lim = lvNext+1 if f00>Lim ; Tree has collapsed remove appropriate lvItems and set Swap. Swap = @true while f00>Lim aryLv[f00-1, 0] = '' aryLv[f00-1, 1] = '' lvCnt = lvCnt-1 csendmessage(hNext, 4104, f00-1, 0) ; LVM_DELETEITEM f00 = f00-1 endwhile endif if Swap then gosub Swap if cgetfocus()==hTvw tvSel = csendmessage(hTvw, 4362, 9, Ary[0, 1]) ; TVM_GETNEXTITEM=4362, TVGN_CARET=9 tvSelNdx = udfTvGetParam(hTvw, Tvi, tvSel) lvSelected = udfLvGetSel(hLvw, 1) if lvSelected!=-1 if aryLv[lvSelected, 0]==tvSelNdx then return endif binarypoke4(Lvi, ilviStateMask, 2) binarypoke4(Lvi, ilviState, 0) ; LVIS_SELECTED for tsc = 0 to lvCnt csendmessage(hLvw, 4139, tsc, pLvi) ; LVM_SETITEMSTATE if aryLv[tsc, 0]==tvSelNdx then lvCurSel = tsc next binarypoke4(Lvi, ilviState, 2) csendmessage(hLvw, 4139, lvCurSel, pLvi) csendmessage(hLvw, 4115, lvCurSel, 0) ; LVM_ENSUREVISIBLE endif if cgetfocus()==hLvw tvNode = csendmessage(hTvw, 4362, 9, Ary[0, 1]) ; TVM_GETNEXTITEM=4362, TVGN_CARET=9 lvSelected = udfLvGetSel(hLvw, 1) if lvSelected==-1 then return chkNode = aryLv[lvSelected, 1] if tvNode==chkNode then return csendmessage(hTvw, 4363, 9, chkNode) ; TVM_SELECTITEM=4363 , TVGN_CARET=9 endif return ;------------------------------------------------------------------------------------------ :Swap if hLvw==Lvw1 hLvw = Lvw2 hHide = Lvw1 else hLvw = Lvw1 hHide = Lvw2 endif udfHideCtl(hHide, 1) udfHideCtl(hLvw, 0) dllcall(user32, long:"SetFocus", long:hTvw) return ;------------------------------------------------------------------------------------------ :InsertNode if pNode for pNdx = 0 to Cnt if Ary[pNdx, 1]==pNode then break next Ary[pNdx, 6] = Ary[pNdx, 6] + 1 Mask = 74 ; TVIF_CHILDREN|TVIF_HANDLE binarypoke4(Tvi, iMask, Mask) binarypoke4(Tvi, iTreeItem, pNode) binarypoke4(Tvi, iChildren, 1) ; f00 = dllcall(user32, long:"SendMessageA", long:hTvw, long:4365, long:0, lpbinary:Tvi) ; TVM_SETITEM=4365 dllcall(user32, long:"SendMessageA", long:hTvw, long:4365, long:0, lpbinary:Tvi) ; TVM_SETITEM=4365 binarypoke4(Tvi, iTreeItem, 0) binarypoke4(Tvi, iChildren, 0) endif Ary[Cnt, 0] = Level Ary[Cnt, 2] = pNode Ary[Cnt, 3] = WorkWnd Ary[Cnt, 4] = FirstChild Ary[Cnt, 5] = NextSibling ; Insert the new node. binarypoke4(Tvins, iParent, pNode) binarypoke4(Tvins, iInsertAfter, 65534) ;TVI_LAST binarycopy(Tvins, iTvi, Tvi, 0, 40) newNode = dllcall(user32, long:"SendMessageA", long:hTvw, long:4352, long:0, lpbinary:Tvins) ;TVM_INSERTITEM ; Expand Root to show Level1 nodes. if Level==1 then Rslt = dllcall(user32, long:"SendMessageA", long:hTvw, long:4354, long:2, long:pNode) ;TVM_EXPAND=4354, TVE_EXPAND=2 ; Update/set the title of the new node. Mask = 5 ;TVIF_TEXT|TVIF_PARAM binarypoke4(Tvi, iMask, Mask) binarypoke4(Tvi, iTreeItem, newNode) binarypoke4(Tvi, iParam, Cnt) Ary[Cnt, 1] = newNode Label = 'L%Level%: C' TextLen = binarypokestr(TextBuf, 0, Label) if TextLen<MaxText then binarypoke(TextBuf, TextLen, 0) Rslt = dllcall(user32, long:"SendMessageA", long:hTvw, long:4365, long:0, lpbinary:Tvi) ;TVM_SETITEM if Level<=1 then gosub LvInsertItem return ;------------------------------------------------------------------------------------------ :UpdateLabels binarypoke4(Tvi, iMask, 1) for wCnt = 0 to winCnts binarypoke4(Tvi, iTreeItem, Ary[wCnt, 1]) sLen = binarypokestr(TextBuf, 0, strcat('L', Ary[wCnt, 0], ': C', Ary[wCnt, 6])) binarypoke(TextBuf, sLen, 0) csendmessage(hTvw, 4365, 0, pTvi) ; TVM_SETITEM next return ;------------------------------------------------------------------------------------------ :GetAttributes maxLevel = 0 GetAttributes = @true WorkWnd = hWnd pNode = 0 Cnt = 0 Level = 0 Siblings = '' gosub GetWndInfo gosub InsertNode if !FirstChild then return while FirstChild || itemcount(Siblings, Sep) while FirstChild Cnt = Cnt+1 Level = Level+1 pNode = newNode WorkWnd = FirstChild gosub GetWndInfo gosub InsertNode if NextSibling then Siblings = iteminsert(Cnt, -1, Siblings, Sep) endwhile ; FirstChild if Level>maxLevel then maxLevel = Level sibCnt = itemcount(Siblings, Sep) if sibCnt Sib = itemextract(sibCnt, Siblings, Sep) Siblings = itemremove(sibCnt, Siblings, Sep) Cnt = Cnt+1 pNode = Ary[Sib, 2] WorkWnd = Ary[Sib, 5] Level = Ary[Sib, 0] gosub GetWndInfo if NextSibling then Siblings = iteminsert(Cnt, -1, Siblings, Sep) gosub InsertNode endif endwhile ; FirstChild || itemcount(Siblings, Sep) winCnts = Cnt csendmessage(hUd, 1125, 0, maxLevel<<32) ; UDM_SETRANGE csetedittext(hEd, '1') Classes = itemsort(Classes, @tab) gosub UpdateLabels return ;------------------------------------------------------------------------------------------ :Main gosub Init GetAttributes = 0 gosub GetAttributes winCnts = Cnt binarypoke4(Rect, 0, 2) ;LVIR_LABEL=2 csendmessage(hLvw, 4110, 0, pRect) ;LVM_GETITEMRECT=4110 csendmessage(hTvw, 4379, binarypeek4(Rect, 12) - binarypeek4(Rect, 4), 0) ;TVM_SETITEMHEIGHT=4 udfHideCtl(hTvw, 0) udfHideCtl(hLvw, 0) tvLevel = 1 SaveAnalysis = 1 ShowControls = 2 Refresh = 3 Close = 4 ExpandTree = 5 LReset = 5 DrillDown = 6 :Loop while 1 Action = 0 for cnt = 1 to zlgMaxButton if boxbuttonstat(1, Cnt) Action = Cnt break endif next ; if dllcall(user32, long:"GetFocus")==hEd if cgetfocus()==hEd chkLevel = cgetedittext(hEd) if chkLevel!=tvLevel tvLevel = chkLevel Action = ExpandTree endif endif gosub UpdateViews select Action case SaveAnalysis gosub WriteToFile break case ShowControls gosub ShowControls break case Refresh csendmessage(Lvw1, 4105, 0, 0) ; LVM_DELETEALLITEMS csendmessage(Lvw2, 4105, 0, 0) ; LVM_DELETEALLITEMS csendmessage(hTvw, 4353, 0, Ary[0, 1]) ; TVM_DELETEITEM=4353, TVI_ROOT=65536 arrinitialize(Ary, 0) arrinitialize(aryNfo, '') arrinitialize(aryLv, '') LvCnt = -1 hLvw = Lvw1 hNext = hLvw udfHideCtl(Lvw1, 1) udfHideCtl(Lvw2, 1) gosub GetAttributes udfHideCtl(hLvw, 0) break case Close goto Cancel break case ExpandTree for wCnt = 0 to winCnts Level = Ary[wCnt, 0] if Level>=tvLevel etFlag = 1 ; TVE_COLLAPSE else etFlag = 2 ; TVE_EXPAND endif csendmessage(hTvw, 4354, etFlag, Ary[wCnt, 1]) ; TVM_EXPAND next break case DrillDown gosub DrillDown break endselect endwhile ; Fall thru ------------------------------------------------------------------------------- :Cancel if isdefined(Tvi) then binaryfree(Tvi) if isdefined(TextBuf) then binaryfree(TextBuf) if isdefined(Tvins) then binaryfree(Tvins) if isdefined(lvhTextBuf) then binaryfree(lvhTextBuf) if isdefined(Lvi) then binaryfree(Lvi) if isdefined(lviTextBuf) then binaryfree(lviTextBuf) if isdefined(Lvcol) then binaryfree(Lvcol) if isdefined(Rect) then binaryfree(Rect) if isdefined(wFile) then fileclose(wFile) if isdefined(tempF) then fileclose(tempF) if fileexist(tmpWbt) then filedelete(tmpWbt) exit ;------------------------------------------------------------------------------------------ :WBERRORHANDLER wErrFile = thisVer wError=LastError() wErrStr = IntControl(34,wError,0,0,0) wErrLine = wberrorhandlerline wErrOffset = wberrorhandleroffset wErrAssign = wberrorhandlerassignment wErrRptFile = strcat(wbtDir, 'Error.txt') wErrMessage = 'Please email this file:%@CRLF%%@tab%"%wErrRptFile%"%@CRLF%to gvag@shaw.ca with the Subject line "AnalysisEx Error"' wErrTxt = strCat(`wErrFile = `, wErrFile, @CRLF, `wError = `, wError, @CRLF, `wErrStr = `, wErrStr, @CRLF, `wErrLine = `, wErrLine, @CRLF, `wErrOffset = `, wErrOffset, @CRLF, `wErrAssign = `, wErrAssign, @CRLF, @CRLF, wErrMessage) fw = fileopen(wErrRptFile, 'WRITE') filewrite(fw, wErrTxt) fileclose(fw) run('NotePad.exe', wErrRptFile) clipput(wErrTxt) goto Cancel ;------------------------------------------------------------------------------------------ :DrillDown ddCrit = 'Class==""Edit""' ddStatic = 'Enter the Eval parameter: udfGetHWnd(hApp, Eval)' zlgFormat=`WWWDLGED,6.1` zlgCaption = `Interactive Drilldown` zlgX = 049 zlgY = 170 zlgWidth = 406 zlgHeight = 168 zlgNumControls = 011 zlgProcedure = `zlg` zlgFont = `Tahoma|6656|40|34` zlgTextColor = `0|0|0` zlgBackground = `DEFAULT,251|251|222` zlgConfig = 0 ;varnnn = ` x , y, cx, cy, Control type, Variable, Title/Pre, RetVal, Tab, Style, , "Family|Size|St|PF", "FgColor", BgColor` zlg001 = `089,149,036,012, PUSHBUTTON, DEFAULT, "Continue", 1, 4, DEFAULT, "Tahoma|6656|40|34", "0|128|0", DEFAULT` zlg002 = `275,149,036,012, PUSHBUTTON, DEFAULT, "Quit", 2, 6, DEFAULT, "Tahoma|6656|40|34", "255|0|0", DEFAULT` zlg003 = `089,006,222,048, MULTILINEBOX, ddMsg, "%hWnd%", DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, DEFAULT` zlg004 = `089,062,222,008, VARYTEXT, ddCritTxt, "%ddStatic%", DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, DEFAULT` zlg005 = `089,072,222,042, DROPLISTBOX, ddCrit, "%ddCrit%", DEFAULT, 1, DEFAULT, DEFAULT, DEFAULT, DEFAULT` zlg006 = `089,104,086,062, DROPLISTBOX, ddFldList, "", DEFAULT, 2, 4, "Tahoma|6144|50|34", "0|0|0", DEFAULT` zlg007 = `174,103,16,012, PUSHBUTTON, DEFAULT, "Add", 3, 5, DEFAULT, "Tahoma|6656|40|34", "0|0|255", DEFAULT` zlg008 = `195,104,100,062, DROPLISTBOX, Classes, "", DEFAULT, 3, 4, "Tahoma|6144|50|34", "0|0|0", DEFAULT` zlg009 = `294,103,16,012, PUSHBUTTON, DEFAULT, "Add", 4, 5, DEFAULT, "Tahoma|6656|40|34", "0|0|255", DEFAULT` zlg010 = `089,094,100,012, STATICTEXT, DEFAULT, "Insert a field:", DEFAULT, 0, DEFAULT, "Tahoma|6144|50|34", "0|0|0", DEFAULT` zlg011 = `195,094,100,012, STATICTEXT, DEFAULT, "Insert a Class:", DEFAULT, 0, DEFAULT, "Tahoma|6144|50|34", "0|0|0", DEFAULT` zlgBtn=Dialog("zlg") return ;------------------------------------------------------------------------------------------ :WriteToFile verx=cGetInfo(0) Pad = 6+(maxLevel-1)*4 wFile=FileOpen(fname,"WRITE") filewrite(wFile, "Control Manager version %verx%") filewrite(wFile, '') filewrite(wFile, '') filewrite(wFile, strcat(strfill(' ', Pad), ' ', strfix("Class"," ",26), ' ', strfix("ID"," ",7), ' ', strfix("TITLE", ' ', 45))) filewrite(wFile, strfill("-", Pad+83)) binarypoke4(Tvi, iMask, 1) for wCnt = 0 to winCnts Level = Ary[wCnt, 0] if Level==1 then filewrite(wFile, '') binarypoke4(Tvi, iTreeItem, Ary[wCnt, 1]) csendmessage(hTvw, 4364, 0, pTvi) ; TVM_GETITEM sLen = binarypokestr(TextBuf, 0, strcat('L', Ary[wCnt, 0], ': C', Ary[wCnt, 6])) filewrite(wFile, strcat(strfix(strcat(strfill(' ', Level*4), binarypeekstr(TextBuf, 0, sLen)), ' ', Pad), ' ', strfix(aryNfo[wCnt, 3], ' ', 26), ' ', strfix(aryNfo[wCnt, 2], ' ', 7), ' ', strfix(aryNfo[wCnt, 1], ' ', 45))) next fileclose(wFile) drop(wFile) if isdefined(Editor) clipput(fname) sendmenusto(Editor, 'File Open') sendkey('^v{ENTER}') else run('Notepad.exe', fname) endif return ;------------------------------------------------------------------------------------------ :ShowControls Selected = udfLvGetSel(hLvw, @false) ; Get a list of selected items. if Selected==-1 then return binarypoke4(Lvi, ilviSubItem, 7) ; This sub-item is the index (window #) into aryNfo. sCnts = itemcount(Selected, tab) Nfo = '' sItem = -1 for sCnt = 1 to sCnts sLen = csendmessage(hLvw, 4141, itemextract(sCnt, Selected, tab), pLvi) ; LVM_GETITEMTEXT Nfo = iteminsert(binarypeekstr(lviTextBuf, 0, sLen), -1, Nfo, tab) next winplace(0, -4, 1000, 20, thisTitle) f00 = 'Down: Next Up: Previous Escape: EXIT' boxcaption(1, f00) wfk = waitforkey('{DOWN}', '{UP}', '{ESC}', '', '') run(tmpWbt, '') while !winexist('ShowControl') yield endwhile hTmp = dllhwnd('ShowControl') winactivate(f00) sCnt = 0 while wfk!=3 if wfk==1 then sCnt = sCnt+1 else sCnt = sCnt-1 if sCnt>sCnts then sCnt = 1 ; if sCnt==0 then sCnt = sCnts if sCnt<=0 then sCnt = sCnts Ndx = itemextract(sCnt, Nfo, tab) boxcaption(1, strcat('Class: ', aryNfo[Ndx, 3], ' ID: ', aryNfo[Ndx, 2], ' Title: ', aryNfo[Ndx, 1], ' X: ',aryNfo[Ndx, 9],' width: ', aryNfo[Ndx, 11], ' Y: ', aryNfo[Ndx, 10], ' height: ', aryNfo[Ndx, 12])) DllCall(User32, long:"SetWindowPos", long:hTmp, long:0, long:aryNfo[Ndx, 9], long:aryNfo[Ndx,10], long:aryNfo[Ndx, 11], long:aryNfo[Ndx, 12], long:16) DllCall(User32, long:"SetCursorPos", long:aryNfo[Ndx, 9]+5, long:aryNfo[Ndx,10]+5) wfk = waitforkey('{DOWN}', '{UP}', '{ESC}', '', '') endwhile boxcaption(1, thisTitle) winplace(0, 0, 1000, 448, thisTitle) Sel = udfLvGetSel(hLvw, @true) binarypoke4(Lvi, ilviStateMask, 2) ; LVIS_SELECTED binarypoke4(Lvi, ilviState, 0) csendmessage(hLvw, 4139, Sel, pLvi) ; LVM_SETITEMSTATE binarypoke4(Lvi, ilviState, 2) for sCnt = 1 to sCnts csendmessage(hLvw, 4139, itemextract(sCnt, Selected, tab), pLvi) csendmessage(hLvw, 4139, itemextract(sCnt, Selected, tab), pLvi) next return ;------------------------------------------------------------------------------------------ :Init thisVer = 'AnalysisEx 1.0.5b' thisTitle = 'Window AnalysisEx' if winexist(thisTitle) winactivate(thisTitle) exit endif :InitExtenders exclusive(@on) addextender("wwctl34i.dll") intcontrol(73,1,0,0,0) ; Use Goto ErrorHndlr gosub LoadStuff ; Load UDFs & message strings if winexist('WinEdit') Editor = '~WinEdit' else if winexist('WinBatch Studio') then Editor = '~WinBatch Studio' endif if winexist(Editor) then winiconize(Editor) WbtDir = filepath(IntControl(1004, 0, 0, 0, 0)) dirchange(WbtDir) tmp = StrCat(`IntControl (12, 4, '', 0, 0)`, @CRLF) tmp = StrCat(tmp, `hWnd = DllHwnd('')`, @CRLF) tmp = StrCat(tmp, `User32 = StrCat(DirWindows(1),"User32.dll")`, @CRLF) tmp = StrCat(tmp, `OldStyle = DllCall(User32, long:"GetWindowLongA", long:hWnd, long:-16) ; GWL_STYLE=-16`, @CRLF) tmp = StrCat(tmp, `NewStyle = OldStyle & ~12582912 ; WS_CAPTION`, @CRLF) tmp = StrCat(tmp, `DllCall(User32, long:"SetWindowLongA", long:hWnd, long:-16, long:NewStyle) `, @CRLF) tmp = StrCat(tmp, ``, @CRLF) tmp = StrCat(tmp, `BoxesUp('250,490,500,510', @normal) `, @CRLF) tmp = StrCat(tmp, `BoxCaption(1, 'ShowControl')`, @CRLF) tmp = StrCat(tmp, `BoxColor(1, '255,0,0', 0)`, @CRLF) tmp = StrCat(tmp, `BoxDrawText(1, '0,0,1000,1000', ' ', @true, 5)`, @CRLF) tmp = StrCat(tmp, `while 1`, @CRLF) tmp = StrCat(tmp, ` yield`, @CRLF) tmp = StrCat(tmp, ` if winexist('%thisTitle%') then break`, @CRLF) tmp = StrCat(tmp, `endwhile `, @CRLF) tmpWbt = 'tmp.wbt' tempF = fileopen(tmpWbt, 'WRITE') filewrite(tempF, tmp) fileclose(tempF) drop(tempF) 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) then AskList = iteminsert(Win, -1, AskList, @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("Choose a Window", a, @tab, @unsorted, @single) trgWnd = AskItemList(AskMsg, AskList, @tab, @sorted, @single) fname="%WbtDir%trash.txt" 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 bHeight = 72 zlgBtn1 = 'Save Analysis' zlgBtn2 = 'Show Controls' zlgBtn3 = 'Refresh' zlgBtn4 = 'Close' zlgBtn5 = '+ / -' zlgBtn6 = 'Query' zlgMaxButton = 6 Caption = '' hMenu = 0 Pad = 7 CtlEntry = strcat("long:", '"CreateWindowExA"') hInst = dllhinst('') bTop = 1000-Pad-bHeight Sep = ',' Sep2 = '|' Tab = @tab User32 = strcat(dirwindows(1), "User32.DLL") Classes = '' :InitParent boxesup ('0,0,1000,448', @NORMAL) boxtextcolor(1, '0,0,0') boxcaption (1, thisTitle) BoxColor (1, '192,192,192', 0) boxdrawrect (1, '0,0,1000,1000', 2) BoxButtonDraw(1, 1, zlgBtn1, udfMakeRect(Pad,bTop,163,bHeight,0)) BoxButtonDraw(1, 2, zlgBtn2, udfMakeRect(Pad+164,bTop,163,bHeight,0)) BoxButtonDraw(1, 3, zlgBtn3, udfMakeRect(Pad+328,bTop,163,bHeight,0)) BoxButtonDraw(1, 4, zlgBtn4, udfMakeRect(1000-2*Pad-72,bTop,72,bHeight,0)) BoxButtonDraw(1, 5, zlgBtn5, udfMakeRect(Pad+592,bTop,60,bHeight,0)) BoxButtonDraw(1, 6, zlgBtn6, udfMakeRect(Pad+700,bTop,100,bHeight,0)) :InitBuffers ; Treeview structures and text buffers. Tvi = binaryalloc(40) pTvi = IntControl(42, Tvi, 0, 0, 0) MaxText = 128 TextBuf = binaryalloc(MaxText) pTextBuf = IntControl(42, TextBuf, 0, 0, 0) ; Get a pointer to the buffer. Tvins = binaryalloc(48) pTvins = IntControl(42, Tvins, 0, 0, 0) ; Listview structures and text buffers. Lvi = binaryalloc(36) pLvi = IntControl(42, Lvi, 0, 0, 0) lviMaxText = 128 lviTextBuf = binaryalloc(lviMaxText) plviTextBuf = IntControl(42, lviTextBuf, 0, 0, 0) ; Get a pointer to the text buffer. ; Listview columns lvhTextMax = 64 lvhTextBuf = binaryalloc(lvhTextMax) plvhTextBuf = IntControl(42, lvhTextBuf, 0, 0, 0) ; Get ptr to binary buffer. Lvcol = binaryalloc(24) pLvcol = IntControl(42, Lvcol, 0, 0, 0) Rect = binaryalloc(16) pRect = IntControl(42, Rect, 0, 0, 0) ; Offsets for TV_ITEM iMask = 0 iTreeItem = 4 iState = 8 iStateMask = 12 ipTextBuf = 16 iMaxText = 20 iImage = 24 iSelectedImage = 28 iChildren = 32 iParam = 36 ; Offsets for TV_INSERTSTRUCT iParent = 0 iInsertAfter = 4 iTvi = 8 ; TV_INSERTSTRUCT contains a copy of TV_ITEM ; Offsets for LV_ITEM iMask = 0 ilviItem = 4 ilviSubItem = 8 ilviState = 12 ilviStateMask = 16 iplviTextBuf = 20 ilviTextMax = 24 ilviImage = 28 ilviParam = 32 binarypoke4(Tvi, ipTextBuf, pTextBuf) binarypoke4(Tvi, iMaxText, MaxText) ; Default values for LvInsertItem binarypoke4(Lvi, iMask, 15) ; LVIF_TEXT|LVIF_IMAGE|LVIF_PARAM|LVIF_STATE binarypoke4(Lvi, ilviItem, 0) binarypoke4(Lvi, ilviSubItem, 0) binarypoke4(Lvi, ilviState, 0) binarypoke4(Lvi, ilviStateMask, 0) binarypoke4(Lvi, iplviTextBuf, plviTextBuf) binarypoke4(Lvi, ilviTextMax, lviMaxText) binarypoke4(Lvi, ilviImage, 0) binarypoke4(Lvi, ilviParam, 0) :InitControls xSpec = udfGetSpec('', 0) ySpec = udfGetSpec('', 1) hParent = DllHwnd('') dwExStyle = 512 ; WS_EX_CLIENTEDGE dwStyle = 1073938471 ; WS_CHILD|WS_GROUP|WS_TABSTOP|TVS_HASBUTTONS|TVS_HASLINES|TVS_LINESATROOT|TVS_SHOWSELALWAYS CtlClass = 'SysTreeView32' xP = int(Pad*xSpec) cxP = int(150*xSpec) yP = int((Pad+58)*ySpec) cyP = int((1000-bHeight-4*Pad-58)*ySpec) hCtl = 'hTvw' gosub CtlSet dwStyle = 1073938441 ; WS_CHILD|WS_GROUP|WS_TABSTOP|LVS_REPORT|LVS_SHOWSELALWAYS CtlClass = 'SysListView32' xP = int((Pad+150)*xSpec) cxP = int((1000-3*Pad-150)*xSpec) yP = int(Pad*ySpec) cyP = int((1000-bHeight-4*Pad)*ySpec) hCtl = 'Lvw1' gosub CtlSet hLvw = Lvw1 gosub InsertColumnHeader csendmessage(hLvw, 4150, 0, csendmessage(hLvw, 4151, 0, 0)|16416) ; LVS_EX_FULLROWSELECT|LVS_EX_LABELTIP=16416 hCtl = 'Lvw2' gosub CtlSet hLvw = Lvw2 gosub InsertColumnHeader csendmessage(hLvw, 4150, 0, csendmessage(hLvw, 4151, 0, 0)|16416) ; LVS_EX_FULLROWSELECT|LVS_EX_LABELTIP=16416 wsDefault = 1342373888 ; WS_CHILD|WS_VISIBLE|WS_TABSTOP|WS_GROUP dwStyle = 1342382080 ; wsDefault|ES_NUMBER CtlClass = 'Edit' xP = int((Pad+655)*xSpec) cxP = int(40*xSpec) yP = int((1000-pad-bHeight)*ySpec) cyP = int(bHeight*ySpec) hCtl = 'hEd' gosub CtlSet udsDefault = 167 ; UDS_ALIGNRIGHT|UDS_ARROWKEYS|UDS_NOTHOUSANDS|UDS_SETBUDDYINT|UDS_WRAP dwExStyle = 0 dwStyle = 1342308519 ; wsDefault|udsDefault&~WS_TABSTOP CtlClass = "msctls_updown32" xP = 0 hCtl = 'hUd' gosub CtlSet csendmessage(hUd, 1129, hEd, 0) ; UDS_SETBUDDY :InitArrays ; Ary = arrdimension(300, 7, 0, 0, 0) Ary = arrdimension(600, 7, 0, 0, 0) ArrInitialize(Ary, 0) aryNfo = arrdimension(600, 13, 0, 0, 0) aryLv = arrdimension(600, 2, 0, 0, 0) arrinitialize(aryLv, '') LvCnt = -1 drop(a, Args, bHeight) drop(bTop, Caption, Close, CtlEntry, hInst, hMenu) drop(lParam, Pad, hwndChk, Spec) drop(CtlClass, cxP, cyP, dwExStyle, dwStyle, hCtl) drop(xP, xSpec, yP, ySpec) hLvw = Lvw1 ; Makes Lvw1 the displayed listview. hNext = hLvw ; One time only setting. return ;------------------------------------------------------------------------------------------ :InsertColumnHeader binarypoke4(Lvcol, 0, 15) ; Flags valid attributes to: LVCF_FMT|LVCF_SUBITEM|LVCF_TEXT|LVCF_WIDTH binarypoke4(Lvcol, 4, 0) ; LVCFMT_LEFT binarypoke4(Lvcol, 12, plvhTextBuf) binarypoke4(Lvcol, 16, 64) ; Headers = 'Title,200|ID,%lvhTextMax%|Class,%lvhTextMax%|WndStyle,%lvhTextMax%|WndStyleEx,%lvhTextMax%|ClassStyle,%lvhTextMax%|Window,%lvhTextMax%|Visible,%lvhTextMax%' Headers = 'sessHndl,%lvhTextMax%|Title,200|ID,%lvhTextMax%|Class,%lvhTextMax%|WndStyle,%lvhTextMax%|WndStyleEx,%lvhTextMax%|ClassStyle,%lvhTextMax%|Window,%lvhTextMax%|Visible,%lvhTextMax%' hCnts = itemcount(Headers, '|')-1 for ichSubItem = 0 to hCnts Header = itemextract(ichSubItem+1, Headers, '|') ichLabel = itemextract(1, Header, ',') binarypokestr(lvhTextBuf, 0, ichLabel) LblLen = strlen(ichLabel) if LblLen<lvhTextMax then binarypoke(lvhTextBuf, LblLen, 0) binarypoke4(Lvcol, 8, itemextract(2, Header, ',')) binarypoke4(Lvcol, 20, ichSubItem) cSendMessage(hLvw, 4123, ichSubItem, pLvcol) ; LVM_INSERTCOLUMN=4123 next return ;------------------------------------------------------------------------------------------ :LvInsertItem LvCnt = LvCnt+1 aryLv[LvCnt, 0] = Cnt aryLv[LvCnt, 1] = newNode ; Zero based indexing has its advantages, twit, the item count is the index of the new item. binarypoke4(Lvi, iMask, 5) ;LVIF_TEXT|LVIF_PARAM binarypoke4(Lvi, ilviParam, Cnt) binarypoke4(Lvi, ilviItem, cSendMessage(hNext, 4100, 0, 0)) ;LVM_GETITEMCOUNT=4100 insCnt = arrinfo(aryNfo, 2)-1 for ins = 0 to insCnt if strlen(aryNfo[Cnt, ins])>=lviMaxText insLen = binarypokestr(lviTextBuf, 0, strfix(aryNfo[Cnt, ins], '', lviMaxText-1)) else insLen = binarypokestr(lviTextBuf, 0, aryNfo[Cnt, ins]) endif binarypoke(lviTextBuf, insLen, 0) binarypoke4(Lvi, ilviSubItem, ins) if ins==0 then cSendMessage(hNext, 4103, 0, pLvi) ;LVM_INSERTITEM=4103 else cSendMessage(hNext, 4142, binarypeek4(Lvi, ilviItem), pLvi) ;LVM_SETITEMTEXT=4142 next return ;------------------------------------------------------------------------------------------ :CtlSet lpClassName = "%CtlClass%" hMenu = hMenu+1 Args = "long:dwExStyle" Args = StrCat(Args, ", lpstr:lpClassName") Args = StrCat(Args, ", lpstr:Caption") ; Caption Args = StrCat(Args, ", long:dwStyle") Args = StrCat(Args, ", long:xP") Args = StrCat(Args, ", long:yP") Args = StrCat(Args, ", long:cxP") ; Width of control. Args = StrCat(Args, ", long:cyP") ; Height of control. Args = StrCat(Args, ", long:hParent") Args = StrCat(Args, ", long:hMenu") Args = StrCat(Args, ", long:hInst") Args = StrCat(Args, ", long:0") %hCtl% = DLLCall(User32, %CtlEntry%, %Args%) Caption = '' return ;------------------------------------------------------------------------------------------ :GetWndInfo cTitle = cWndInfo(WorkWnd, 0) cID = cWndInfo(WorkWnd, 1) cClass = cWndInfo(WorkWnd, 2) cParent = cWndInfo(WorkWnd, 3) cFirstSibling = cWndInfo(WorkWnd, 4) cPreviousSibling = cWndInfo(WorkWnd, 5) NextSibling = cWndInfo(WorkWnd, 6) cLastSibling = cWndInfo(WorkWnd, 7) FirstChild = cWndInfo(WorkWnd, 8) cOwner = cWndInfo(WorkWnd, 9) cWndStyle = cWndInfo(WorkWnd, 20) cWndStyleEx = cWndInfo(WorkWnd, 21) cClassStyle = cWndInfo(WorkWnd, 22) if cTitle=='' then cTitle = ' -' f00 = dllcall(User32, long:"GetWindowRect", long:WorkWnd, lpbinary:Rect) aryNfo[Cnt, 0] = WorkWnd aryNfo[Cnt, 1] = cTitle aryNfo[Cnt, 2] = cID aryNfo[Cnt, 3] = cClass aryNfo[Cnt, 4] = cWndStyle aryNfo[Cnt, 5] = cWndStyleEx aryNfo[Cnt, 6] = cClassStyle aryNfo[Cnt, 7] = Cnt aryNfo[Cnt, 8] = dllcall(User32, long:"IsWindowVisible", long:WorkWnd) aryNfo[Cnt, 9] = binarypeek4(Rect, 0) aryNfo[Cnt, 10] = binarypeek4(Rect, 4) aryNfo[Cnt, 11] = binarypeek4(Rect, 8)-binarypeek4(Rect, 0) aryNfo[Cnt, 12] = binarypeek4(Rect, 12)-binarypeek4(Rect, 4) if !itemlocate(cClass, Classes, @tab) then Classes = iteminsert(cClass, -1, Classes, @tab) return ;------------------------------------------------------------------------------------------ :LoadStuff ; call('udfGetHWnd.udl', '') :udfGetHWnd #definefunction udfGetHWnd(hApp, Eval) IntControl(73,1,0,0,0) ; Use gosub ErrorHndlr AddExtender("wwctl34i.dll") if Eval=='' then return 0 if hApp!=0 && hApp!='' WorkWnd = hApp else return 0 endif rTitle = 0 rID = 1 rClass = 2 rParent = 3 rFirstSibling = 4 rPreviousSibling = 5 rNextSibling = 6 rLastSibling = 7 rFirstChild = 8 rOwner = 9 rWndStyle = 20 rWndStyleEx = 21 rClassStyle = 22 Sep = ',' Siblings = '' testCnts = itemcount(Eval, '?') gosub GetWndInfo gosub Eval if Tests then return WorkWnd if !FirstChild then return 0 while FirstChild || itemcount(Siblings, Sep) while FirstChild WorkWnd = FirstChild gosub GetWndInfo gosub Eval if Tests then return WorkWnd if NextSibling then Siblings = iteminsert(NextSibling, -1, Siblings, Sep) endwhile ; FirstChild Sib = itemcount(Siblings, Sep) if Sib WorkWnd = itemextract(Sib, Siblings, Sep) Siblings = itemremove(Sib, Siblings, Sep) gosub GetWndInfo gosub Eval if Tests then return WorkWnd if NextSibling then Siblings = iteminsert(NextSibling, -1, Siblings, Sep) endif endwhile return 0 ;--------------------------------------------------------------------------------------- :GetWndInfo Title = cWndInfo(WorkWnd, 0) 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) return ;--------------------------------------------------------------------------------------- :Eval Tests = @false ; testCnts = itemcount(Eval, '?') - initialized on entry. for testCnt = 1 to testCnts Query = itemextract(testCnt, Eval, '?') if testCnt==1 if %Query% then Tests = @true else qHndl = itemextract(1, Query, '|') if %qHndl%==0 Tests = @false else Rqst = itemextract(2, Query, '|') TestFor = itemextract(3, Query, '|') Tests = cwndinfo(%qHndl%, %Rqst%)%TestFor% endif endif if !Tests then break next return ;------------------------------------------------------------------- :WBErrorHandler WbtDir = filepath(IntControl(1004, 0, 0, 0, 0)) dirchange(WbtDir) wErrFile = 'udfGetHWnd 1.0.1' wError=LastError() if wError==204 then return wErrStr = IntControl(34,wError,0,0,0) wErrLine = wberrorhandlerline wErrOffset = wberrorhandleroffset wErrAssign = wberrorhandlerassignment wErrRptFile = strcat(wbtDir, 'Error.txt') wErrMessage = 'Please email this file:%@CRLF%%@tab%"%wErrRptFile%"%@CRLF%to gvag@shaw.ca with the Subject line "AnalysisEx Error"' wErrTxt = strCat(`wErrFile = `, wErrFile, @CRLF, `wError = `, wError, @CRLF, `wErrStr = `, wErrStr, @CRLF, `wErrLine = `, wErrLine, @CRLF, `wErrOffset = `, wErrOffset, @CRLF, `wErrAssign = `, wErrAssign, @CRLF, @CRLF, wErrMessage) fw = fileopen(wErrRptFile, 'WRITE') filewrite(fw, wErrTxt) fileclose(fw) run('NotePad.exe', wErrRptFile) clipput(wErrTxt) return #endfunction ;------------------------------------------------------------------------------------------ :zlg #definesubroutine zlg(zlgHndl, zlgEvent, zlgControlID, param4, param5) IntControl(73,1,0,0,0) ; Use Goto ErrorHndlr InitDialog = 0 BtnPush = 2 select zlgEvent case InitDialog winzoom(thisTitle) RetVal = -2 zlgContinue = 1 zlgQuit = 2 zlgText = 3 zlgCrit = 4 CritCbx = 5 hCritTbx = udfGetHWnd(zlgHndl, 'ID==1001') FldCbx = 6 zlgAddFld = 7 ClsCbx = 8 zlgAddCls = 9 ddCrits = '' dialogprocoptions(zlgHndl, BtnPush, 1) dialogcontrolset(zlgHndl, zlgText, 3, ddMsg) dialogcontrolset(zlgHndl, FldCbx, 5, ddFlds) dialogcontrolset(zlgHndl, FldCbx, 6, itemextract(1, ddFlds, @tab)) dialogcontrolset(zlgHndl, ClsCbx, 5, Classes) dialogcontrolset(zlgHndl, ClsCbx, 6, itemextract(1, Classes, @tab)) break case BtnPush Btn = zlgControlID select Btn case zlgContinue ddCrit = cgetedittext(hCritTbx) ddHndl = udfGetHWnd(hWnd, ddCrit) ddText = strCat(`Criteria:`, ddCrit, ` Handle returned: `, ddHndl) dialogcontrolset(zlgHndl, zlgCrit, 4, ddText) ddNdx = itemlocate(strlower(ddCrit), strlower(ddCrits), @tab) if !ddNdx ddCrits =iteminsert(ddCrit, 0, ddCrits, @tab) else ddCrits = itemremove(ddNdx, ddCrits, @tab) endif dialogcontrolset(zlgHndl, CritCbx, 5, ddCrits) return -2 break case zlgQuit RetVal = -1 winshow(thisTitle) break case zlgAddFld ddCrit = cgetedittext(hCritTbx) csetedittext(hCritTbx, strcat(ddCrit, dialogcontrolget(zlgHndl, FldCbx, 6))) RetVal = -2 break case zlgAddCls ddCrit = cgetedittext(hCritTbx) csetedittext(hCritTbx, strcat(ddCrit, '"', dialogcontrolget(zlgHndl, ClsCbx, 6), '"')) RetVal = -2 break endselect if Btn==3 then break endselect return RetVal ;------------------------------------------------------------------------------------------ :WBERRORHANDLER wErrFile = 'Query Dialog' wError=LastError() wErrStr = IntControl(34,wError,0,0,0) wErrLine = wberrorhandlerline wErrOffset = wberrorhandleroffset wErrAssign = wberrorhandlerassignment wErrRptFile = strcat(wbtDir, 'QueryDlg') wErrMessage = 'Please email this file:%@CRLF%%@tab%"%wErrRptFile%"%@CRLF%to gvag@shaw.ca with the Subject line "AnalysisEx Error"' wErrTxt = strCat(`wErrFile = `, wErrFile, @CRLF, `wError = `, wError, @CRLF, `wErrStr = `, wErrStr, @CRLF, `wErrLine = `, wErrLine, @CRLF, `wErrOffset = `, wErrOffset, @CRLF, `wErrAssign = `, wErrAssign, @CRLF, @CRLF, wErrMessage) fw = fileopen(wErrRptFile, 'WRITE') filewrite(fw, wErrTxt) fileclose(fw) run('NotePad.exe', wErrRptFile) return 1 #endsubroutine ;------------------------------------------------------------------------------------------ :udfLvGetSel #definefunction udfLvGetSel(hLvw, FirstOnly) selCnts = csendmessage(hLvw, 4146, 0, 0) ; LVM_GETSELECTEDCOUNT if selCnts==0 return -1 endif Cnts = csendmessage(hLvw, 4100, 0, 0)-1 ; LVM_GETITEMCOUNT if FirstOnly then goto FirstOnly Sels = '' for Cnt = 0 to Cnts if csendmessage(hLvw, 4140, Cnt, 2)==2 ; LVM_GETITEMSTATE=4140, LVNI_SELECTED=2 Sels = iteminsert(Cnt, -1, Sels, @tab) endif next return Sels :FirstOnly for Cnt = 0 to Cnts if csendmessage(hLvw, 4140, Cnt, 2)==2 then return Cnt next #endfunction ;------------------------------------------------------------------------------------------ :udfTvGetParam #definefunction udfTvGetParam(hTvw, Tvi, hItem) binarypoke4(Tvi, 0, 4) binarypoke4(Tvi, 4, hItem) ; TVM_GETITEM = 4364 if !dllcall(strcat(dirwindows(1), "User32.DLL"), long:"SendMessageA", long:hTvw, long:4364, long:hItem, lpbinary:Tvi) then return -1 return binarypeek4(Tvi, 36) #endfunction ;------------------------------------------------------------------------------------------ :udfHideCtl #definefunction udfHideCtl(hWnd, Hide) if Hide Show = 128 else Show = 64 endif hZOrder = 0 ; if uFlags includes swpNoSize && swpNoMove all positioning info is ignored so... uFlags = Show|3 ; swpNoSize=1 swpNoMove=2 rtn = udfSetWinPos(hWnd, hZOrder, 0, 0, 0, 0, uFlags) return rtn #endfunction ;------------------------------------------------------------------------------------------ :udfSetWinPos #definefunction udfSetWinPos(hWnd, hZOrder, xP, yP, cxP, cyP, uFlags) User32 = StrCat(DirWindows(1), "User32.DLL") swpEntry = 'word:"SetWindowPos"' swpArgs = StrCat(`long:hWnd`) swpArgs = StrCat(swpArgs, `,long:hZOrder`) swpArgs = StrCat(swpArgs, `,word:xP`) swpArgs = StrCat(swpArgs, `,word:yP`) swpArgs = StrCat(swpArgs, `,word:cxP`) swpArgs = StrCat(swpArgs, `,word:cyP`) swpArgs = StrCat(swpArgs, `,word:uFlags`) rtn = dllcall(User32, %swpEntry%, %swpArgs%) return rtn #endfunction ;------------------------------------------------------------------------------------------ :udfGetWinRect #definefunction udfGetWinRect(WndName, Rqst) ; as Long User32 = strcat(DirWindows(1), 'User32.dll') select Rqst case 0 Entry = '"GetWindowRect"' break case 1 Entry = '"GetClientRect"' break case Rqst return 0 endselect rtn = 0 Rect = binaryalloc(16) hWnd = dllhwnd(WndName) if hWnd==0 || hWnd==-1 then goto Free Rtn = DllCall(User32, long:%Entry%, long:hWnd, lpbinary:Rect) binaryeodset(Rect, 16) rtn = '' for cnt = 0 to 3 rtn = iteminsert(binarypeek4(Rect, cnt*4), -1, rtn, ',') next :Free binaryfree(Rect) return rtn #endfunction ;------------------------------------------------------------------------------------------ :udfGetSpec #definefunction udfGetSpec(WndName, Rqst) ; ***GATHER*** call('Controls.udl', 'udfGetWinRect') Rect = udfGetWinRect(WndName, 1) ; Get client area. ; Client width or height in pixels. Spec = itemextract(Rqst+3, Rect, ',') - itemextract(Rqst+1, Rect, ',') + .0 Spec = Spec/1000 return Spec #endfunction ;------------------------------------------------------------------------------------------ :udfMakeRect #definefunction udfMakeRect(x, y, cx, cy, Nudge) ; ***GATHER*** call('Controls.udl', 'udfGetSpec') if !Nudge cx = x+cx cy = y+cy return '%x%,%y%,%cx%,%cy%' endif if isint(Nudge) hSpec = udfGetSpec('', 0) hNudge = hSpec*Nudge hNudge = int(hNudge) if hNudge then inc = hNudge/abs(hNudge) ; Divide by zero? no thanks! if hNudge mod 2 then hNudge = hNudge+inc hNudge = int(hNudge/hSpec) if hNudge mod 2 then hNudge = hNudge+inc vSpec = udfGetSpec('', 1) vNudge = hSpec*Nudge vNudge = int(vNudge) if vNudge then inc = vNudge/abs(vNudge) if vNudge mod 2 then vNudge = vNudge+inc vNudge = int(vNudge/hSpec) if vNudge mod 2 then vNudge = vNudge+inc hNudgit = hNudge/2 vNudgit = vNudge/2 select 1 case cx>0 x = x-hNudgit cx = x+cx+hNudge continue case cy>0 y = y-vNudgit cy = y+cy+vNudge continue case cx<0 x = x+hNudgit cx = -hNudge+x+cx continue case cy<0 y = vNudgit+y cy = -vNudge+y+cy continue endselect return '%x%,%y%,%cx%,%cy%' else x1 = x-int(cx*Nudge) y1 = y-int(cy*Nudge) cx1 = x+int(cx*Nudge+cx) cy1 = y+int(cy*Nudge+cy) return '%x1%,%y1%,%cx1%,%cy1%' endif #endfunction ; Hide this clutter stuff way down here. ddMsg=StrCat(`The Fields ListBox contains the fields available for a query. A '*' prefix indicates a handle to another control.`, @CRLF) ddMsg=StrCat(ddMsg, ` Title *FirstSibling *LastSibling WndStyle `, @CRLF) ddMsg=StrCat(ddMsg, ` ID *PreviousSibling *FirstChild WndStyleEx`, @CRLF) ddMsg=StrCat(ddMsg, ` Class *NextSibling *Owner ClassStyle`, @CRLF) ddMsg=StrCat(ddMsg, ` *Parent`, @CRLF) ddMsg=StrCat(ddMsg, `In addition the Classes ListBox contains all the unique classes found in the application. Clicking the "Add" button will append the selected item to your query. Classes will be inserted as quoted strings, e.g. "Edit".`, @CRLF) ddMsg=StrCat(ddMsg, ``, @CRLF) ddMsg=StrCat(ddMsg, `These examples use the two Edit controls found in Studio's Output window. A simple query:`, @CRLF) ddMsg=StrCat(ddMsg, ` udfGetHWnd( hApp, ``Id==1047``)`, @CRLF) ddMsg=StrCat(ddMsg, `but what if the EvilApp doesn't have unique control IDs?`, @CRLF) ddMsg=StrCat(ddMsg, ` udfGetHWnd( hApp, ``Class=="Edit" && NextSibling!=0``)`, @CRLF) ddMsg=StrCat(ddMsg, `gets the first Edit control and`, @CRLF) ddMsg=StrCat(ddMsg, ` udfGetHWnd( hApp, ``Class=="Edit" && NextSibling==0``)`, @CRLF) ddMsg=StrCat(ddMsg, `gets the next.`, @CRLF) ddMsg=StrCat(ddMsg, ``, @CRLF) ddMsg=StrCat(ddMsg, `Sometimes there is a need to refer to an attribute of a parent or sibling window. In this case you can create complex queries that eliminate the repeated calls that drilling down sometimes requires:`, @CRLF) ddMsg=StrCat(ddMsg, ` udfGetHWnd( hApp,``Class=="Edit"?NextSibling|rClass|=="Edit"``)`, @CRLF) ddMsg=StrCat(ddMsg, `may do the trick. How it works.`, @CRLF) ddMsg=StrCat(ddMsg, ``, @CRLF) ddMsg=StrCat(ddMsg, `Eval may contain additional tests delimited by "?". If the first test is successful, the three parameters of subsequent items are substituted as follows:`, @CRLF) ddMsg=StrCat(ddMsg, ` Tests = cWndInfo(%%qHndl%%, %%Rqst%%)%%TestFor%%`, @CRLF) ddMsg=StrCat(ddMsg, `udfGetHWnd defines variables for each of the request codes supported by cWndInfo, just prepend an "r" to the field name.`, @CRLF) ddFlds = StrCat('Title', @tab,'FirstSibling', @tab, 'LastSibling', @tab, 'WndStyle', @tab) ddFlds = StrCat(ddFlds, 'ID', @tab, 'PreviousSibling', @tab, 'FirstChild', @tab, 'WndStyleEx', @tab) ddFlds = StrCat(ddFlds, 'Class', @tab, 'NextSibling', @tab, 'Owner', @tab, 'ClassStyle', @tab, 'Parent') ddFlds = itemsort(ddFlds, @tab) return ; to Init ;------------------------------------------------------------------------------------------ ; weuglLabelLines=:UpdateViews:Swap:InsertNode:UpdateLabels:GetAttributes:Main:Loop:Cancel:WBERRORHANDLER:DrillDown:WriteToFile:ShowControls:Init:InitExtenders:InitParent:InitBuffers:InitControls:InitArrays:InsertColumnHeader:LvInsertItem:CtlSet:GetWndInfo:LoadStuff:udfGetHWnd:GetWndInfo:Eval:WBErrorHandler:zlg:WBERRORHANDLER:udfLvGetSel:FirstOnly:udfTvGetParam:udfHideCtl:udfSetWinPos:udfGetWinRect:Free:udfGetSpec:udfMakeRect;***LABEL LIST***
Article ID: W15832
File Created: 2004:03:30:15:41:02
Last Updated: 2004:03:30:15:41:02