bowertom Posted May 29, 2012 Share Posted May 29, 2012 (edited) Hi, I was trying to do a script that automatically sets an menue option in another program, please see attached screenshot. I used "Au3Record" to record the mouse clicks, etc. "Au3Record" fails to get the right coordinates, it seems like the coordinates are mirrored on the diagonal screen axis: the programs' main window opens down right of the screen (standard), but the recorded "Au3REcord"-coordinates are in the upper left ("MouseClick("right",107,425,1)"). Is there a way to activate a menue option in a different or rather direct way than using the MouseXXX()-functions? Regards Tom ----------------------------------------- AutoIT v3.3.8.1, Win7 Pro 64 Bit Edited June 16, 2012 by bowertom Link to comment Share on other sites More sharing options...
Bert Posted May 29, 2012 Share Posted May 29, 2012 Look for "Tray Management" in the helpfile The Vollatran project My blog: http://www.vollysinterestingshit.com/ Link to comment Share on other sites More sharing options...
bowertom Posted May 29, 2012 Author Share Posted May 29, 2012 Thanks for your advice. But the attached screenshot from my first post is perhaps a bit misleading. It doesn't show a particular part from the system tray, it's the program itself. Please take a look at the attached screenshot. Link to comment Share on other sites More sharing options...
lark Posted May 29, 2012 Share Posted May 29, 2012 Try using the ControlClick function. Use the AutoIt Window Info tool to gather the information about the control, and use something likeControlClick("Phoner", "Destination Number", "[CLASS:Button]", "secondary")But then again, I have never tried to use that on the right-click menu button of a control. So you could find out how far up and over the menu button is from the actual control, and use ControlGetPos to get the x and y coords of the control. Let's say the menu button is 20 pixels over (x + 20) and 40 pixels up (y - 40). So you could try something like:Global $avControl = ControlGetPos("Phoner", "Destination Number", "[CLASS:Button]", "secondary") Global $iXPos = $avControl[0] + Floor($avControl[2] / 2) Global $iYPos = $avControl[1] + Floor($avControl[3] / 2) MouseClick("secondary", $iXPos, $iYPos) Sleep(300) MouseClick("primary", $iXPos + 20, $iYPos - 40) Link to comment Share on other sites More sharing options...
Zedna Posted May 29, 2012 Share Posted May 29, 2012 I think ideal will be to catch apropriate WM_COMMAND by Winspector and then use _SendMessage(). Search this forum for Winspector to see the details ... Resources UDF ResourcesEx UDF AutoIt Forum Search Link to comment Share on other sites More sharing options...
bowertom Posted June 4, 2012 Author Share Posted June 4, 2012 Thanks a lot, I tried the _SendMessage() solution first. This is what I did: 1) Used Microsoft Spy++ to get the params for the WM_COMMAND (couldn't get it done with Winspector). Spy++ had a lot of output. I considered this to be the important one: <00381> 00071B36 P WM_COMMAND wNotifyCode:0 (sent from a menu) wID:67 ... furthermore Spy++ showed that "00071B36" is a handle of an instance of the "TPUtilWindow" class Phoner uses. 2) I used this AutoIT-Code for testing: #include <SendMessage.au3> _SendMessage(0x00071B36,0x0111,67,0) ... and this works great! Both to enable and disable the Phoner option. But now I'm stuck as the handle of course changes with each start of the program. I read about the "get handle from classname", etc., but this didn't help because there are a lot of "TPUtilWindow" instances around (half a dozen from Phoner itself and a lot more e.g. from Skype). Is there a way to get the actual "TPUtilWindow" window class handle within AutoIT? Link to comment Share on other sites More sharing options...
Zedna Posted June 4, 2012 Share Posted June 4, 2012 Look at WinGetHandle() and "Title special definition" (Window Titles and Text (Advanced) to see what can be done ... Resources UDF ResourcesEx UDF AutoIt Forum Search Link to comment Share on other sites More sharing options...
bowertom Posted June 4, 2012 Author Share Posted June 4, 2012 Sorry, but I don't get the point in this. When I take a look at the WinGetHandle() function together with the "special title definition", I think (and may be wrong, most likely) that the only possibilities to get the correct handle are to pass ... a ) TITLE b ) CLASS c ) TITLE and CLASS d ) TITLE and CLASS and INSTANCE e ) CLASS and INSTANCE ... to the WinGetHandle() function. The problem now with a), c) and d) is, that these instances of the "TPUtilWindow" class do not have any titles and are invisible ("TPUtilWindow is used by components that require a window handle but have no windows" is what says another website about the "TPUtilWindow" class). Obviously b ) will not work, too, because the class is commonly used, so hitting the right "TPUtilWindow" instance would probably be impossible. Same with e). Perhaps there's another approach? Because the WM_COMMAND method seems to be the "cleanest" solution and I don't yet want to let it go Link to comment Share on other sites More sharing options...
Zedna Posted June 4, 2012 Share Posted June 4, 2012 (edited) You can also use second parameter of WinGetHandle() - Text EDIT: You can also write your own helper routine which will for example analyze all children windows/controls and their properties/texts in all Windows with the same ClassName to distinguish among them. Edited June 4, 2012 by Zedna Resources UDF ResourcesEx UDF AutoIt Forum Search Link to comment Share on other sites More sharing options...
bowertom Posted June 5, 2012 Author Share Posted June 5, 2012 (edited) ... ok, I finally managed it Though it's probably not the best performing code, it does its' job./edit 1: Version 0.2 ... The option wasn`t activated in 1 out of 10 cases, because the program needs a bit of extra time afer start to create all TPUtilWindow-class instances. Added a 5 sec. sleep, now it works 100%./edit 2: The option is turned on and off the same way, so if you start the script twice it will turn off the option again and vice versa.expandcollapse popup#include <SendMessage.au3> Global Const $PhonerPath = "C:Program Files (x86)Phonerphoner.exe";Path to the Phoner executable $pid = RunPhoner() sleep(5000) ; Phoner needs a bit of extra time during startup to create all TPUtilWindow-class instances. EnableOption($pid);Go for it ;---------------------------------Functions--------------------------------- ;Returns Phoner PID. If Phoner is not running we start it Func RunPhoner() Local $pid = ProcessExists("phoner.exe") If $pid == 0 Then;Phoner is not running, we start it now and return the PID $pid = Run($PhonerPath) If @error Then ShowErrorAndExit("Could not start Phoner.") ElseIf WinWait("Phoner", "", 10) == 0 Then ShowErrorAndExit("The Phoner main window did not show up.") Else Return $pid EndIf Else;Phoner is already running so we return the PID Return $pid EndIf EndFunc ;Activate the Option in Phoner Func EnableOption($pid) Local $phoner_pid = $pid Local $window_pid = "" If $phoner_pid == "" OR $phoner_pid < 0 Then ShowErrorAndExit("There was no or no correct Phoner PID passed to the function.") EndIf Local $WList_all_TPUtilWindows = WinList("[CLASS:TPUtilWindow]");First we get all window instances based on the TPUtilWindow class If $WList_all_TPUtilWindows[0][0] > 0 Then;Now we check for each window if it belongs to Phoner For $i = 1 To $WList_all_TPUtilWindows[0][0] $window_pid = WinGetProcess($WList_all_TPUtilWindows[$i][1]) If $window_pid < 0 Then ShowErrorAndExit("Could not retrieve PID from window handle.") Else If $window_pid == $phoner_pid Then ;we found a window that belongs to Phoner _SendMessage($WList_all_TPUtilWindows[$i][1],0x0111,67,0);firing WM_COMMAND with corresponding wID. As there`s no return code or anything else, we neither need any error checking nor can we find out if the command hit the right class-instance, so we have to use brute force and send our WM_COMMAND to every window found EndIf EndIf Next Else ShowErrorAndExit("No TPUtilWindow-class windows were found.") EndIf EndFunc ;Show MessageBox with an error text and exit the script Func ShowErrorAndExit($text) MsgBox(0, "Error", $text) Exit EndFunc... the function described in one sentence is: get all TPUtilWindow based windows, check which of these windows belong to our program, then send the WM_COMMAND to those windows. This is kind of brute force, but there seems to be no way how the right TPUtilWindow instance could be triggered directly, because there's no titel, no text, nothing. So, for now I'm really happy with the actual solution, but if someone knows a better way ... you're welcome.Thanks again to everyone!RegardsTom Edited June 16, 2012 by bowertom Link to comment Share on other sites More sharing options...
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