Unable to find control - autoit

I want to find and click a button using Autoit. I tried AutoIt Window Information Tool but the button is not recognized so ControlClick() fails.
The button is active on the current window but Send("Enter") does not work. Tried using MouseClick() but the window does not appear in the same place every time, and I tried this script:
$hWnd = WinWait("vcredist_x86")
WinWaitActive("vcredist_x86")
ControlClick($hWnd, "", "[CLASS FROM AUTOITINFO]", "Left", 1)
but neither of them works. Is there any other way to identify and click the button?

If both version of AutoItWindowInfo(32 and 64bit) don't "see" the control you need to automate, here is what you can do:
Method 1 - Sending keystrokes:
Activate the window with WindowActivate
Send a number of TABs until the control is focused(if its not initially)
Send ENTER or SPACE
Method 2 - MouseClick:
Activate the window
Get the coordinates of a control relative to the application window(position the window at 0,0. Open Autoit Window Info, click on Mouse tab and get the position of the button). That position is usually always the same
When your code is running it must get the window position with WinGetPos and then add control position you got in step 2. That's your clicking position.
Method 3 - PixelSearch(If the control has unique color):
Get the desired color with AutoIt Window Info(mouse tab)
Search it using PixelSearch
Click the coords you got
Method 4 - ImageSearch:
Get ImageSearch UDF and DLL
Make a picture of the button
Search and click it
NOTE: Sometimes you need to give your script Admin rights in order to automate certain windows.

When AutoIt Window Information Tool failed me I had success using the text property of the button/ui control:
ControlClick($hwin, '', '[CLASS:Button; TEXT:Cancel]')
Experiment with "&" in front of one of the characters (underlined by Windows to indicate an Alt + key shortcut), so try "&Cancel" instead of "Cancel". If that fails try ControlFocus() first:
ControlFocus($hwin, '', '[CLASS:Button; TEXT:Cancel]')
ControlClick($hwin, '', '[CLASS:Button; TEXT:Cancel]')
Inspecting .exe files for GUI resources (using Resource Hacker for example) may expose text/properties of a control. Example:

Related

How to click on visible text under a class?

I created an AutoIt script for a program that has a navigator bar
like this :
Using Au3Info.exe I'm getting following info:
So the problem is Encode tab is active and I want the script to click on the Decode tab, but Au3Info.exe is only identifying the navigator bar :
I'm only getting mouse coordinates or Visible Text for both tabs. I tried :
Run("C:\Users\Dumpty\Desktop\Selenium\WebPconvPortable\WebPconv.exe")
WinWaitActive("Romeolight WebPconv")
Sleep(3000)
ControlFocus("Romeolight WebPconv", "", "WindowsForms10.Window.8.app.0.378734a62")
ControlClick("Romeolight WebPconv", "", "[CLASS:WindowsForms10.Window.8.app.0.378734a62;CONTROLCLICK COORDS:165, 9]")
I tried to click using mouse coordinates too but that's not working either.
You can try MouseClick as you have object position available.
Go to AutoIt v3 Window info and select the Mouse tab.
get the position mentioned over of object. and use in below code.
Below is code you can try:
Run("C:\Users\Dumpty\Desktop\Selenium\WebPconvPortable\WebPconv.exe")
WinWaitActive("Romeolight WebPconv")
Sleep(3000)
MouseClick("left",0,51)==> use actual value
Please let me know if this worked.

How can I make a script focus on an application?

I am creating some automated test scripts to test a piece of software. Im doing this in a modular way so that I can more easily dictate which scripts are being and change this, while having all the scripts pre-compiled
I have a script which is launched with parameters from a batch, this opens up my compiled script which enters in the login details and presses OK to any dialogs that may appear. This part works as intended.
At the end of the script I am trying to re-gain focus onto the main application window, set the window to fullscreen and then run the next batch file to perform the next test etc.
in this example "$practice" refers to the main application's window title, which I have derived using the AutoItv3 Info tool.
WinWaitActive($practice)
$hWnd = WinGetHandle($practice)
; FullScreen
WinSetState($practice,"",#SW_RESTORE)
WinSetState($practice,"",#SW_MAXIMIZE)
RunWait(#ComSpec & " /c " & "TestStart.bat")
However, this is not regaining focus and maximising the window as expected, i think the applications splash screen could be interfering.
If I manually Click into any part of the application to focus on it, then the dialog will be set to fullscreen and then my second script will run.
What should I do to make this last part of the script behave as I wish?
WinActivate ( "title" [, "text"] ) - Activates (gives focus to) a window.
title - The title/hWnd/class of the window to activate. See Title
special definition.
text [optional] The text of the window to activate. Default is an
empty string. See Text special definition.
More info here.
This is how I ended up resolving the issue
WinActivate($practice)
WinWaitActive($practice)
$hWnd = WinGetHandle($practice)
ControlFocus($hWnd, "", "[CLASS:XTPToolBar; INSTANCE:1]")
; FullScreen
WinSetState($practice,"",#SW_RESTORE)
WinSetState($practice,"",#SW_MAXIMIZE)
RunWait(#ComSpec & " /c " & "sequence.bat")
By adding WinActivate and then manually giving control focus before calling WinSetState

Print Friendly Page

So I would like to be able to have a print button for entries in our database so users can print an entry via a print friendly "form".
My thought was to create a separate page, add labels and have those labels pull the relevant information.
I know I can add the open widget information via this code:
app.datasources.ModelName.selectKey(widget.datasource.item._key);
app.showPage(app.pages.TestPrint);
But I'm running into a few problems:
I can't get the page to open in a new window. Is this possible?
window.open(app.pages.TestPrint);
Just gives me a blank page. Does the browser lose the widget source once the new window opens?
I can't get the print option (either onClick or onDataLoad) to print JUST the image (or widget). I run
window.print();
And it includes headers + scroll bars. Do I need to be running a client side script instead?
Any help would be appreciated. Thank you!
To get exactly what you'd want you'd have to do a lot of work.
Here is my suggested, simpler answer:
Don't open up a new tab. If you use showPage like you mention, and provide a "back" button on the page to go back to where you were, you'll get pretty much everything you need. If you don't want the back to show up when you print, then you can setVisibility(false) on the button before you print, then print, then setVisibility(true).
I'll give a quick summary of how you could do this with a new tab, but it's pretty involved so I can't go into details without trying it myself. The basic idea, is you want to open the page with a full URL, just like a user was navigating to it.
You can use #TestPrint to indicate which page you want to load. You also need the URL of your application, which as far as I can remember is only available in a server-side script using the Apps Script method: ScriptApp.getService().getUrl(). On top of this, you'll probably need to pass in the key so that your page knows what data to load.
So given this, you need to assemble a url by calling a server script, then appending the key property to it. In the end you want a url something like:
https://www.script.google.com/yourappaddress#TestPage?key=keyOfYourModel.
Then on TestPage you need to read the key, and load data for that key. (You can read the key using google.script.url).
Alternatively, I think there are some tricks you can play by opening a blank window and then writing directly to its DOM, but I've never tried that, and since Apps Script runs inside an iframe I'm not sure if it's possible. If I get a chance I'll play with it and update this answer, but for your own reference you could look here: create html page and print to new tab in javascript
I'm imagining something like that, except that your page an write it's html content. Something like:
var winPrint = window.open('', '_blank', 'left=0,top=0,width=800,height=600,toolbar=0,scrollbars=0,status=0');
winPrint.document.write(app.pages.TestPage.getElement().innerHTML);
winPrint.document.close();
winPrint.focus();
winPrint.print();
winPrint.close();
Hope one of those three options helps :)
So here is what I ended up doing. It isn't elegant, but it works.
I added a Print Button to a Page Fragment that pops up when a user edits a database entry.
Database Edit Button code:
app.datasources.ModelName.selectKey(widget.datasource.item._key);
app.showDialog(app.pageFragments.FragmentName);
That Print Button goes to a different (full) Page and closes the Fragment.
Print Button Code:
app.datasources.ModelName.selectKey(widget.datasource.item._key);
app.showPage(app.pages.ModelName_Print);
app.closeDialog();
I made sure to make the new Print Page was small enough so that Chrome fits it properly into a 8.5 x 11" page (728x975).
I then created a Panel that fills the page and populated the page with Labels
#datasource.item.FieldName
I then put the following into the onDataLoad for the Panel
window.print();
So now when the user presses the Print Button in the Fragment they are taken to this new page and after the data loads they automatically get a print dialog.
The only downside is that after printing the user has to use a back button I added to return to the database page.
1.
As far as I know, you cannot combine window.open with app.pages.*, because
window.open would require url parameter at least, while app.pages.* is essentially an internal routing mechanism provided by App Maker, and it returns page object back, suitable for for switching between pages, or opening dialogs.
2.
You would probably need to style your page first, so like it includes things you would like to have printed out. To do so please use #media print
ex: We have a button on the page and would like to hide it from print page
#media print {
.app-NewPage-Button1 {
display : none;
}
}
Hope it helps.
1. Here is how it is done, in a pop up window, without messing up the current page (client script):
function print(widget, title){
var content=widget.getElement().innerHTML;
var win = window.open('', 'printWindow', 'height=600,width=800');
win.document.write('<head><title>'+title+'/title></head>');
win.document.write('<body>'+content+'</body>');
win.document.close();
win.focus();
win.print();
win.close();
}
and the onclick handler for the button is:
print(widget.root.descendants.PageFragment1, 'test');
In this example, PageFragment1 is a page fragment on the current page, hidden by adding a style with namehidden with definition .hidden{display:none;} (this is different than visible which in App Maker seems to remove the item from the DOM). Works perfectly...
2. You cannot open pages from the app in another tab. In principle something like this would do it:
var w=window.parent.parent;
w.open(w.location.protocol+'//'+w.location.host+w.location.pathname+'#PrintPage', '_blank');
But since the app is running in frame nested two deep from the launching page, and with a different origin, you will not be able to access the url that you need (the above code results in a cross origin frame access error). So you would have to hard code the URL, which changes at deployment, so it gets ugly very fast. Not that you want to anyway, the load time of an app should discourage you from wanting to do that anyway.

Next and previous control button in winAPI to go to next page (c++)

I am creating an winAPI application in c++ I have a photo in preview pane and I want to create two buttons NEXT and PREVIOUS on clicking them I will go to the next page .
Could you please give me the idea how to do that in c++ ??
Do I need to use QT libraray or it can be done using the in built function of WinAPI like -
HWND hwndButton1 = CreateWindow(L"BUTTON",L"NEXT",WS_TABSTOP | WS_VISIBLE | WS_CHILD | BS_DEFPUSHBUTTON,550,800,100,30,m_hwndPreview,(HMENU)buttonid1,(HINSTANCE)GetWindowLong(m_hwndPreview, -6),NULL);
HWND hwndButton2 = CreateWindow(L"BUTTON",L"PREVIOUS",WS_TABSTOP | WS_VISIBLE | WS_CHILD | BS_DEFPUSHBUTTON,650,800,100,30,m_hwndPreview,(HMENU)buttonid2,(HINSTANCE)GetWindowLong(m_hwndPreview, -6),NULL);
and then using WM_COMMAND for both the button clicks.
Am I going right?
I just want my API application work like a .pdf extension file...as in PDF files we have up and down arrow and on clicking upon them we can go to the next page..In winAPIc++ I couldn't find any such arrow function.. please tell me if there is any such arrow up/down function present to go to next page (because I am very less interested in creating NEXT and PREVIOUS button using createwindow function.. It looks odd).
You have not mentioned what tools you are using, so we don't know if you have a resouce editor. You should research that in a forum appropriate for the tools. If you think writing one line of code to create a button is "very complicated" then you need a better tool.
If you do not want the buttons to appear on top of the picture then you need another place to put them. One common possibility is a toolbar. It is a strip for buttons along the top or bottom of the main window:
http://msdn.microsoft.com/en-us/library/windows/desktop/bb760435(v=vs.85).aspx
With a resource editor you can draw an arrow on the button. Without a resource editor you can set the button text to a unicode arrow:
SetWindowText(hwndButton1, L"\x25bc"); // down arrow, use 25b2 for up arrow
Most buttons (and other controls) are created using a resource editor, placing the controls on a dialog template or a toolbar resource. If you do that Windows will create the buttons when you create the dialog or toolbar. This method is much preferred because Windows will adjust the size of the buttons as required for the screen settings in use.
If you can't do that you must use CreateWindow as you are doing.
Finally it is done.. I have created the buttons neither using Qt or nor using any createWindowEx..The best and easy approach to follow is resource editor ...just put some button on dialog and use IDD_MAINDIALOG (in my case)
m_hwndPreview = CreateDialogParam( g_hInst,MAKEINTRESOURCE(IDD_MAINDIALOG), m_hwndParent,(DLGPROC)DialogProc, (LPARAM)this);
and then
BOOL CALLBACK AMEPreviewHandler::DialogProc(HWND m_hwndPreview, UINT Umsg, WPARAM wParam, LPARAM lParam)
{
switch(Umsg) // handle these messages
{ .........
}
....
}
and thats done. Very easy task.

anchor target blank - how to always open in same popup window

I have a number of anchors in a page. I want that when the user clicks on an anchor it would open a blank window. I have used target='_blank' and that works correctly. However, I want that if the user clicks on another link in the original page, I would like that it uses the same popup that was opened for the first window. What I do not want is that the user ends up with like 10 popups as this would be a bit messy for the user.
Is this achievable please?
Any assistance would be greately appreciated.
target is deprecated since HTML 4.01, you can however use JS like this:
test
<script>
var clicky = document.getElementById("clicky");
clicky.onclick = function(){
window.open(clicky.href, "test");
return false;
}​
</script>
in the window.open, the first attribute is the URL the link should go to, the second is the name of the window, clicking any link setup like this will open in the same window.
there's better and easier ways to do this to multiple elements with jquery etc. but it all hinges on the window.open.
Instead of using _blank (which is a special value for a new window), use a name - any name would do.
target="mySpecialPopup"
When naming a window this way, every time you call it by name it uses the same instance.
Just name your target.
target='mywindow'
This should open a blank window the first click and repopulate it when other target='mywindow' links are clicked.

Resources