maestro1024 Posted March 24, 2008 Posted March 24, 2008 Hello, I have been playing around with this a couple ways but wanted to see what you guys recommend. I want to be able to the menu or control or whatever piece of a window a user has selected. I can get the current window but I guess the real trick is know what type of control they have open. What is the right approach for this? Do I try to read what type of controls the window has available and enumerate that? Thanks
PsaltyDS Posted March 24, 2008 Posted March 24, 2008 ControlGetFocus() 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
maestro1024 Posted March 24, 2008 Author Posted March 24, 2008 ControlGetFocus() Thanks for the help. What I want to do here is determine if the user has selected a different control on the screen.I had looked at that but wasn't sure what to do with the control ref. When I look at a window this doesn't appear to change when I select different parts of the windoe (IE, I am in notepad and select file and then select view, problem is the same control ref is returned). What can I do with the control ref, getting text appears to use the control ID. Are the two things related?Also, it looks like ControlGetFocus only does keyboard focus (I might be wrong) is their a way to get whatever the focus is?thanks againPlaying around with CODE$temp=0$text=ControlGetFocus(WinGetTitle(""), "")While($temp<10)MsgBox(0, "", WinGetTitle("") & " has " & $text)if $text==ControlGetFocus(WinGetTitle(""), "") thenElse MsgBox(0, "", WinGetTitle("") & " has " & $text) $text=ControlGetFocus(WinGetTitle(""), "")EndIf$temp=$temp+1Sleep(3000)WEnd
FreeFry Posted March 25, 2008 Posted March 25, 2008 (edited) Try this:Opt("WinTitleMatchMode", 4) Dim $exitTimer = TimerInit() ;$oldWindowInfo[0] = Active Window Handle ;$oldWindowInfo[1] = Active Window Control Focus Dim $oldWindowInfo[2] = [WinGetHandle("[ACTIVE]"), ControlGetFocus("[ACTIVE]")] Do If $oldWindowInfo[0] = WinGetHandle("[ACTIVE]") And $oldWindowInfo[1] <> ControlGetFocus("[ACTIVE]") Then ConsoleWrite("Control focus has changed in window " & @LF & WinGetTitle($oldWindowInfo[0]) & @LF & " from " & @LF & $oldWindowInfo[1] & @LF & _ " to " & @LF & ControlGetFocus("[ACTIVE]") & @LF & @LF) $oldWindowInfo[1] = ControlGetFocus("[ACTIVE]") ElseIf $oldWindowInfo[0] <> WinGetHandle("[ACTIVE]") Then ConsoleWrite("Window focus has changed from " & @LF & WinGetTitle($oldWindowInfo[0]) & @LF & " to " & @LF & WinGetTitle("[ACTIVE]") & @LF & _ " new control focused is " & @LF & ControlGetFocus("[ACTIVE]") & @LF & @LF) $oldWindowInfo[0] = WinGetHandle("[ACTIVE]") $oldWindowInfo[1] = ControlGetFocus("[ACTIVE]") Else ToolTip("Active window has control " & $oldWindowInfo[1] & " focused") EndIf Sleep(25) Until TimerDiff($exitTimer) > 30000 ; 30 SecondsEdit:Edited so the code would fit into the forum view.. Edited March 25, 2008 by FreeFry
maestro1024 Posted March 25, 2008 Author Posted March 25, 2008 Thanks again for all the help and code. I think I may have asked my question wrong and/or misunderstand windows GUIs. In the help for controls I see it says for instance that notepad is one big control. I had some checks for comparing controls but that doesn't appear to much different from just checking to see if the active window is different. So then how would a person go about finding out what part of the screen or what menu is selected. I would like to be able to use the same piece of code to know if the current menu is different in IE or notepad or any windows app with standard GUIs and controls. I also tried getting the current text for a window which is helpful but really doesn't tell me if a certain menu is selected. Is this possible with autoit? What type of functions should I be looking at? And again thanks.
FreeFry Posted March 26, 2008 Posted March 26, 2008 I believe that a control and a menu is two different things... I guess you'd have to check what window is open, and do assumptions based on what window and/or control is active.. You can retrieve the classname of a control with the UDF _WinAPI_GetClassName, if that's what you want.. For an example(unrelated) of how to retrieve all windows owned by a process with a special classname, one can use this function: #include <WinAPI.au3> ; All shell windows will be found: $a = _ProcessGetWinEx(WinGetProcess("Program Manager")) For $i = 1 To $a[0] ConsoleWrite('Window: "' & WinGetTitle($a[$i]) & '" has class: ' & _WinAPI_GetClassName($a[$i]) & @LF) Next ; Only the start button will be found: $a = _ProcessGetWinEx(WinGetProcess("Program Manager"), "Button") For $i = 1 To $a[0] ConsoleWrite('Window: "' & WinGetTitle($a[$i]) & '" has class: ' & _WinAPI_GetClassName($a[$i]) & @LF) Next Func _ProcessGetWinEx($ivPid, $svClass = "") $ivPid = ProcessExists($ivPid) If Not $ivPid Then Return(SetError(1, 0, 0)) Local $avwArray = WinList() Local $avRet[1] = [0] For $i = 1 To $avwArray[0][0] If WinGetProcess($avwArray[$i][1]) = $ivPid Then If $svClass = "" Or _WinAPI_GetClassName($avwArray[$i][1]) = $svClass Then $avRet[0] += 1 ReDim $avRet[$avRet[0]+1] $avRet[$avRet[0]] = $avwArray[$i][1] EndIf EndIf Next Return $avRet EndFunc
PsaltyDS Posted March 26, 2008 Posted March 26, 2008 I posted this yesterday and I am not sure if I asked the question correctly.http://www.autoitscript.com/forum/index.php?showtopic=67100what I want to get is if a new button or menu or any sort of item is opened by the user.I know how to see if the active window has changed but how would I for instance in notepad if a user selects File or selects View (is same control). Can Autoit get this information and what approach could I use to get it?ThanksCheck out the _GuiCtrlMenu_* functions, probably leading to _GuiCtrlMenu_GetItemState(). 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
maestro1024 Posted March 26, 2008 Author Posted March 26, 2008 (edited) FreeFry thanks again. A couple questions. I have played with get class name but wasn't sure exactly what that was (you are getting the class names but what does that mean?). If I get all the class names for an active window does that mean I can somehow plug those classes back in somewhere? You were talking about assumptions for window types does that mean for example if the window name starts with Internet Explorer I can look for Web controls and menus or was that about something else? Edited March 26, 2008 by maestro1024
FreeFry Posted March 26, 2008 Posted March 26, 2008 (edited) FreeFry thanks again.A couple questions.I have played with get class name but wasn't sure exactly what that was (you are getting the class names but what does that mean?). If I get all the class names for an active window does that mean I can somehow plug those classes back in somewhere? Sorry, I might have misunderstood what you wanted there. Sorry, my example code was more related to the assumptions you could make based on what classname the window has...You were talking about assumptions for window types does that mean for example if the window name starts with Internet Explorer I can look for Web controls and menus or was that about something else?Well, you could get the classname of the window with the previously mentioned _WinAPI_GetClassName, and then you can make assumptions based on what "type" of classname it has(note that _WinAPI_GetClassName also works on controls, etc.), but a internet explorer window has only a few controls, the main one(ie. the part where you do the actual surfing in) is called "Internet Explorer_Server", but you can't use most of the WinX and ControlX functions on it..If what you really want is to automate the web browser, you should look into the IE UDFs..Sorry for any confusion I might have caused you. :/ Edited March 26, 2008 by FreeFry
maestro1024 Posted March 26, 2008 Author Posted March 26, 2008 Thanks again. You guys have been very helpful. I am thinking maybe I can create a test app (some menus in C#) and see if I can get the menus,etc from it. Maybe this isn't possible in AutoIt (which is fine, I wouldn't want to bang my head too hard if it is not even possible). I don't actually have to have the names of menus but just need to know if they change. I was playing with this hoping to see different info when I play this and select drop downs on notepad or IE. Problem is I didn't see a difference when selecting different drop downs. CODE#include "GuiMenu.au3" $temp=0 While($temp<7) ; $title = WinGetClassList(WinGetTitle(""), "") ; FileWriteLine("test.txt","Text read was:"& $text) $hWnd = WinGetHandle(WinGetTitle("")) FileWrite("test.txt", "Title: " & WinGetTitle("")) $hMain = _GUICtrlMenu_GetMenu ($hWnd) $hFile = _GUICtrlMenu_GetItemSubMenu ($hMain, 2) $state= _GuiCtrlMenu_GetItemState($hFile,$hFile) FileWriteLine("test.txt","Window: " & $hWnd & " Menu : " & $hMain & " Sub Menu: " & $hFile & " State " & $state) $temp=$temp+1 Sleep(2000) WEnd
FreeFry Posted March 26, 2008 Posted March 26, 2008 (edited) Try this: #include <GuiMenu.au3> Sleep(2500) ; To allow time to activate a window.. $hMain = _GUICtrlMenu_GetMenu (WinGetHandle("")) $Timer = TimerInit() For $i = 0 To _GUICtrlMenu_GetItemCount($hMain) ConsoleWrite("Detected a menu item: " & _GUICtrlMenu_GetItemText($hMain, $i) & @LF) $subMenu = _GUICtrlMenu_GetItemSubMenu($hMain, $i) For $x = 0 To _GUICtrlMenu_GetItemCount($subMenu) ConsoleWrite(@TAB & "Detected a sub-menu item: " & _GUICtrlMenu_GetItemText($subMenu, $x) & @LF) Next Next Do For $i = 0 To _GUICtrlMenu_GetItemCount($hMain) $subMenu = _GUICtrlMenu_GetItemSubMenu($hMain, $i) For $x = 0 To _GUICtrlMenu_GetItemCount($subMenu) If BitAND(_GUICtrlMenu_GetItemState($subMenu, $x), 16) Then ConsoleWrite(_GUICtrlMenu_GetItemText($subMenu, $x) & @TAB & "is Highlighted" & @LF) EndIf Next Next Until TimerDiff($Timer) > 12500 ; 12.5 Seconds I tested it on SciTE, and it works fine there.. Edit: I noticed a small error I made in the code, it was supposed to use BitAND against the item state, not comparing it to 16 directly.. Edited March 26, 2008 by FreeFry
maestro1024 Posted March 27, 2008 Author Posted March 27, 2008 CODEBitAND(_GUICtrlMenu_GetItemState($subMenu, $x),16 ) Not sure I follow on the bitAnd you have the itemstate which makes sense Help says "16 - Item is highlighted" Doesn't that mean if it is highlighted the function will return that and the code would be correct?
maestro1024 Posted March 27, 2008 Author Posted March 27, 2008 Also, wanted to make sure I understand what you did here. Tell me if I am wrong. I played with this some and looked up the function calls but I still might be mising something. You get all of the current menus and sub-menus for the current window. And then you look at every one of those menus to see if they are currently highlighted. Please correct me if I am wrong. This is where the assumption about window type comes in. This code should work on a standard windows app with menus but will definately not work on an IE page.
FreeFry Posted March 27, 2008 Posted March 27, 2008 Also, wanted to make sure I understand what you did here.Tell me if I am wrong. I played with this some and looked up the function calls but I still might be mising something.You get all of the current menus and sub-menus for the current window.And then you look at every one of those menus to see if they are currently highlighted.That's correct.Please correct me if I am wrong.This is where the assumption about window type comes in. This code should work on a standard windows app with menus but will definately not work on an IE page.Well, as far as I know, all windows that has a menu should be able to be 'automated' this way, but then again, if what you're trying to do is to see/handle the content on a webpage these functions will not work..CODEBitAND(_GUICtrlMenu_GetItemState($subMenu, $x),16 )Not sure I follow on the bitAndyou have the itemstate which makes senseHelp says "16 - Item is highlighted"Doesn't that mean if it is highlighted the function will return that and the code would be correct?The helpfile also says "Can be one or more of the following:"Which means that it can be a combination(added together I believe) of those values. What BitAND does is check if has the value 16 in it. If you want to see an example in the helpfile of another similar scenario have a look at WinGetState.
Recommended Posts
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 accountSign in
Already have an account? Sign in here.
Sign In Now