Matlab: How to change focus between external and internal windows? - matlab

I'm hoping this is an easy problem, but I haven't figured out the answer yet nor seen a good resource for this. I'm running an experiment in Matlab, and at times we call to an external program. After a certain amount of time, I want the participants to return to Matlab to take a survey, and then resume their task after they are done. The problem is the external code is interactive, so a person could be typing or clicking and not see the survey open up, and after completing the survey I don't know how to automatically return them to their open program (although I know when they are done with their survey and automatically close the browser). My toy code example would be:
system('start \max notepad.exe')
pause(60) %After x seconds a web page opens up in Matlab, how to ensure users see it?
web('cnn.com') %I have code that will close this after they click on a certain link
%After close browser, how to return to notepad where they left off?

Two solutions may help you. Actually, it is a little complicate. Solution 1 use mex method control window of program by c code. Solution 2 is also complicate, just use MATLAB parallel toolbox. Hmm, I suggest your use solution 1.
solution 1:
Create a cpp file, which controls your interactive program(i.e. window explorer here). code is below. copy and save the code as "ctrlWindow.cpp" at your MATLAB current folder.
compile ctrlWindow.cpp by compiler lcc:
mex -setup % choose compiler: type this command at MATLAB command, then choose lcc complier on windows 32 system
mex ctrlWindow.cpp % compile cpp: you would find ctrlWindow.mexw32 at current folder
run the mex file as m-file at MATLAB command:
ctrlWindow('your_program_window_name',command);
i.e. window name of a folder "myfold" is myfold which is display on the top left of window, type command:
ctrlWindow('myfold',6);
this would minimize your folder window. I suggest you minimize your program window firstly, then maximize it, and participants would focus on your program again:
ctrlWindow('myfold',6);%minimize window
ctrlWindow('myfold',3);%maximize window and participants would focus on this window
command is here:
HIDE 0
SHOWNORMAL 1
NORMAL 1
SHOWMINIMIZED 2
SHOWMAXIMIZED 3
MAXIMIZE 3
SHOWNOACTIVATE 4
SHOW 5
MINIMIZE 6
SHOWMINNOACTIVE 7
SHOWNA 8
RESTORE 9
SHOWDEFAULT 10
FORCEMINIMIZE 11
MAX 11
//filename:ctrlWindow.cpp
#include <windows.h>
#include "mex.h"
void mexFunction( int nlhs, mxArray *plhs[],
int nrhs, const mxArray *prhs[] )
{
mxChar* winName; //name of window wanted to be found
HWND hwnd; //handle of window
int command; //command of control window
// check number of input
if(nrhs!=2)
mexErrMsgTxt("input must be 2");
// check class of input
if (mxIsChar(prhs[0]))
winName=mxGetChars(prhs[0]);//get name of window
else
mexErrMsgTxt("input 1 should be char -- name of window");
if (mxIsDouble(prhs[1]))
{
command = (int) mxGetScalar(prhs[1]);//get command
if(command<0 || command >11)//check command
mexErrMsgTxt("No such command!!!");
}
else
mexErrMsgTxt("input 2 should be a double");
// find window
hwnd = FindWindowW(NULL, (LPCWSTR)winName);
if(NULL==hwnd)
{
MessageBoxW(NULL,(LPCWSTR) L"Can't find the window!!!",NULL,MB_OK);
return;
}
ShowWindow(hwnd, command);//control the window
}
Solution 2:
matlabpool open 2
open two matlab background, use first control your first program, use second one control your second program.

Related

Is it possible to use GDK or GTK to pull user generated content from an active firefox window? (Similair to FIndWIndow on Windows)

I am working on a bit of a hobby project while trying to better understand the windowing system in Linux. I want to create a program that will constantly print the contents of the active textbox in a firefox window. I know this is possible on windows with FindWindow, but I am curious whether this could be duplicated on Linux.
I am currently running this on ubuntu, with the standard version of firefox. So far, I have been able to pull in a foreign window based on the window ID, but cannot seem to get past that. The current script simply prints out the display width of the firefox window.
uint xlib_window = 0x00800010; //firefox window id
gtk_init(&argc, &argv);
GdkDisplay * gdk_display = gdk_display_get_default();
GdkWindow * temp = gdk_x11_window_foreign_new_for_display(gdk_display, xlib_window);
cout << gdk_window_get_width(temp) << endl;
I would like to be able to find the current active widget, and print whatever it contains it is a text buffer. Right now, I am only able to find generic information about the window.

Stopping/pausing execution in Matlab to check the value of the variables while running [duplicate]

This question already has answers here:
Stop and continue execution from debugger possible?
(6 answers)
Closed 6 years ago.
I am trying to write a program in Matlab which is quite large and I want to stop or pause the execution to see what my variables values are.
I want to stop or pause the execution to see what my variables are.
One alternative is to use keyboard:
keyboard pauses execution of a running program and gives control to
the keyboard. Place the keyboard function in a program at the location
where you want MATLABĀ® to pause. When the program pauses, the prompt
in the Command Window changes to K>>, indicating that MATLAB is in
debug mode. You then can view or change the values of variables to see
if the new values produce expected results. The keyboard function is
useful for debugging your functions.
To continue executing your function, type dbcont, or type dbquit to quit the debug mode.
If you want to view the variables after a given number of iterations you can insert if ii = stop_point; keyboard; where ii is the iterator of the loop.
Another option is:
Use dbstop. This is shown with an example from the documentation:
Set a breakpoint to stop when n >= 4, and run the code.
dbstop in myprogram at 4 if n>=4
myprogram
Yet another option is to manually insert breakpoints in the MATLAB editor. Click on the left side of the code to insert breakpoints (indicated by a red dot). Now you can view the variable by hovering the mouse over the variable names in the editor
Have a look at this very relevant link to get more information.
Note, the following paragraph is a direct copy of chappjc's answer here. Please upvote his/her answer if you like this approach!
With the release of R2016a, you can just hit the Pause button in the code editor and it will halt right away.
To pause the execution of a program while it is running, in the Editor
tab, click the Pause button. MATLAB pauses execution at the next
executable line*. When your code is running, the Start button will
turn into a pause:

programmatically press an enter key after starting .exe file in Matlab

In Matlab I can start external .exe files that sometime have a pop up that requires an enter key pressed. For example:
system('C:\Program Files (x86)\WinZip\WINZIP32.EXE')
will start Winzip, and then in order to use it you need to pass the "buy now" pop up window by pressing enter.
Now my problem is not with winzip, I only gave it as an example (i use winrar anyway :).
How can I programmatically press an enter key in Matlab in such cases ? (I use win 7)
Can an event listener be used to solve that?
EDIT: The java.awt.Robot class indeed works on explorer, but not on any software that has a pop up window with an OK button that needs to be pressed. I don't know why it doesn't work for that. I gave the winzip example because I assume everybody has winzip/winrar installed in their machine. The actual software I have is different and irrelevant for the question.
There is a way using Java from Matlab, specifically the java.awt.Robot class. See here.
Apparently there are two types of programs, regarding the way they work when called from Matlab with system('...'):
For some programs, Matlab waits until the program has finished before running the next statement. This happens for example with WinRAR (at least in my Windows 7 machine).
For other programs this doesn't happen, and Matlab proceeds with the next statement right after the external program has been started. An example of this type is explorer (the standard Windows file explorer).
Now, it is possible to return execution to Matlab immediately even for type 1 programs: just add & at the end of the string passed to system. This is standard in Linux Bash shell, and it also works in Windows, as discussed here.
So, you would proceed as follows:
robot = java.awt.Robot;
command = '"C:\Program Files (x86)\WinRAR\WinRAR"'; %// external program; full path
system([command ' &']); %// note: ' &' at the end
pause(5) %// allow some time for the external program to start
robot.keyPress (java.awt.event.KeyEvent.VK_ENTER); %// press "enter" key
robot.keyRelease (java.awt.event.KeyEvent.VK_ENTER); %// release "enter" key
If your applications are only on Windows platform, you can try using .net objects.
The SendWait method of the SendKeys objects allows to send virtually any key, or key combination, to the application which has the focus, including the "modifier" keys like Alt, Shift, Ctrl etc ...
The first thing to do is to import the .net library, then the full syntax to send the ENTER key would be:
NET.addAssembly('System.Windows.Forms');
System.Windows.Forms.SendKeys.SendWait('{ENTER}'); %// send the key "ENTER"
If you only do it once the full syntax is OK. If you plan to make extensive use of the command, you can help yourself with an anonymous helper function.
A little example with notepad
%% // import the .NET assembly and define helper function
NET.addAssembly('System.Windows.Forms');
sendkey = #(strkey) System.Windows.Forms.SendKeys.SendWait(strkey) ;
%% // prepare a few things to send to the notepad
str1 = 'Hello World' ;
str2 = 'OMG ... my notepad is alive' ;
file2save = [pwd '\SelfSaveTest.txt'] ;
if exist(file2save,'file')==2 ; delete(file2save) ; end %// this is just in case you run the test multiple times.
%% // go for it
%// write a few things, save the file then close it.
system('notepad &') ; %// Start notepad, without matlab waiting for the return value
sendkey(str1) %// send a full string to the notepad
sendkey('{ENTER}'); %// send the {ENTER} key
sendkey(str2) %// send another full string to the notepad
sendkey('{! 3}'); %// note how you can REPEAT a key send instruction
sendkey('%(FA)'); %// Send key combination to open the "save as..." dialog
pause(1) %// little pause to make sure your hard drive is ready before continuing
sendkey(file2save); %// Send the name (full path) of the file to save to the dialog
sendkey('{ENTER}'); %// validate
pause(3) %// just wait a bit so you can see you file is now saved (check the titlebar of the notepad)
sendkey('%(FX)'); %// Bye bye ... close the Notepad
As explained in the Microsoft documentation the SendKeys class may have some timing issues sometimes so if you want to do complex manipulations (like Tab multiple times to change the button you actually want to press), you may have to introduce a pause in your Matlab calls to SendKeys.
Try without first, but don't forget you are managing a process from another without any synchronization between them, so timing all that can require a bit of trial and error before you get it right, at least for complex sequences (simple one should be straightforward).
In my case above for example I am running all my data from an external hard drive with an ECO function which puts it into standby, so when I called the "save as..." dialog, it takes time for it to display because the HDD has to wake up. If I didn't introduce the pause(1), sometimes the file path would be imcomplete (the first part of the path was send before the dialog had the focus).
Also, do not forget the & character when you execute the external program. All credit to Luis Mendo for highlighting it. (I tend to forget how important it is because I use it by default. I only omit it if I have to specifically wait for a return value from the program, otherwise I let it run on its own)
The special characters have a special code. Here are a few:
Shift +
Control (Ctrl) ^
Alt %
Tab {TAB}
Backspace {BACKSPACE}, {BS}, or {BKSP}
Validation {ENTER} or ~ (a tilde)
Ins Or Insert {INSERT} or {INS}
Delete {DELETE} or {DEL}
Text Navigation {HOME} {END} {PGDN} {PGUP}
Arrow Keys {UP} {RIGHT} {DOWN} {LEFT}
Escape {ESC}
Function Keys {F1} ... {F16}
Print Screen {PRTSC}
Break {BREAK}
The full list from Microsoft can be found here
There is a small javascript utility that simulates keystrokes like this on the Windows javascript interpreter.
Just create a js file with following code:
var WshShell = WScript.CreateObject("WScript.Shell");
WshShell.SendKeys(WScript.Arguments(0));
then call it from Matlab after the necessary timeout like this:
system('c:\my\js\file\script.js {Enter}');
Can't test here now, but I think this should work...
If you need to run a console-only program in a context that permits full DOS redirection, you can create a file called, say, CR.txt containing a carriage return and use the '<' notation to pipe the value into the program.
This only works if you can provide all the keyboard input can be recorded in the file. It fails dismally if the input has to vary based on responses.
An alternative is to duplicate the input (and possibly output) stream(s) for the program and then pipe data into and out of the program. This is more robust and can permit dynamic responses to the data, but will also likely require substantial effort to implement a robot user to the application.
Rog-O-Matic is an example of a large application completely controlled by a program that monitors screen output and simulates keyboard input to play an early (1980s) ASCII graphic adventure game.
The other responses will be required for GUI-based applications.
Python package pywinauto can wait any dialog and click buttons automatically. But it's capable for native and some .NET applications only. You may have problems with pressing WPF button (maybe QT button is clickable - not checked), but in such case code like app.DialogTitle.wait('ready').set_focus(); app.DialogTitle.type_keys('{ENTER}') may help. Your case is quite simple and probably some tricks with pywinauto are enough. Is your "app with popup" 64-bit or 32-bit?
wait and wait_not functions have timeout parameter. But if you need precisely listener with potentially infinite loop awaiting popups, good direction is global Windows hooks (pyHook can listen mouse and keybd events, but cannot listen dialog opening). I'll try to find my prototype that can detect new windows. It uses UI Automation API event handlers... and... ops... it requires IronPython. I still don't know how to set UI Automation handler with COM interface from standard CPython.
EDIT (2019, January): new module win32hooks was implemented in pywinauto a while ago. Example of usage is here: examples/hook_and_listen.py.

How to return to prompt after running an exe file compiled with mcc (Matlab compiler)

I have an executable created with mcc. The .m file has a simple function that reads and plots values. After I run it from DOS, it freeze without returning execution to DOS. 2 questions:
1) How can i return execution to dos? I tried "return" and "exit" commands but didnt help
2) How to close the dos windows? is the only way to use a batch file or can I do it with a command in the .m file?
thanks
A.
There are 2 scenarii:
If your run your matlab executable from a DOS window, the DOS window will not get control back until the program terminates. If the program generate matlab figures (plot, surf, etc...), the program will not return to the console until all of the figures are closed.
You may think it is a waste for a simple plot, but after all your figure could be a evolved gui with a lot of code to execute. Or even a simple figure with a closeRequestFcn. So in Matlab terms, your program may still have instructions to execute as long as a figure is opened, so it will not return until it sure there is nothing more to do.
If you simply double clicked on your executable, the DOS looking console which open with your program will have the same behaviour. It will not disappear until the program returns (so until all your figures are closed if relevant).
I am not sure about linux, versions, but if you are running on windows, there is a way to suppress the DOS looking console for your graphic applications. Look at the -e switch in the mcc options.
This switch will compile your program in a way that no DOS console is opened when you double click on your executable.
So to summarize, I would recommend:
If your program is a 'command line' type (a function that takes input from the console and return values to the same). => Compile with normal options, and execute it from a DOS window (you do not want the window to disapear as soon as the program terminates.)
If your program is a gui or even simple plotting functions, with no need for console interactions, then compile with the -e switch and execute it by double clicking the .exe file.
note that in case you use the -e switch, it is recommended to direct potential output to a logfile. Look at the mcc documentation for more info.
edit
If you really need the DOS console and some graphic output, run your program form the command window with the following syntax:
start /b YourProgram
This will start the program in "background mode" (use YourProgram & in Linux terminal). You will be able to do anything in this console window, and you will also see the output from your matlab executable.
It can be confusing because the output from your program will be added to the simple dos prompt and you may think you do not have the control but if you type any command it will work. You can even start many program this way and retain control in your console, but all the output will arrive in the same window and they may be difficult to differentiate.

How to debug matlab code without gui

I have recently started using MATLAB without GUI by starting matlab with -nodesktop option and it is considerably faster.
However presently I have no way to debug a .m script in non gui mode. I have to open the default matlab editor every time I have to debug.Has anyone figured out a way to do it?
Thanks in advance
I am using Ubuntu Linux, in case that helps.
To set breakpoints with the command line, dbstop is the tool (plus dbclear to clear breakpoints and dbstatus to list them).
There are presently 17 different forms to dbstop, which allow you to specify various combinations of:
The M-file in which to stop
Line number
Sub-function
Conditional to an arbitrary expression. For example,
dbstop in myFun.m at 224 if ~exist('x','var')
At any run-time error (dbstop if error)
At a specific error (e.g dbstop if error myFun.m:barErrorId)
At any warning (dbstop if warning) or specific warning
If NaN or Inf are encountered (dbstop if naninf)
See the documentation for dbstop for details and good examples.
Also get used to dbcont (or F5), dbstep (or F10), dbquit (Shift+F5), dbstep (also dbstep in, dbstep out), dbstack (to see where you are and how you got there). The keyboard shortcuts may be different outside of Windows.
Far less used, but still very useful are dbup and dbdown, which allow you to switch workspace context (memory stacks).
See the summary of functions and a list of examples and how-to pages in the MathWorks page on Debugging.
Related to the "db" functions is checkcode, which will check your code for possible problems before you even run it. This is a nice substitute for the red squiggly underlines that you would get in the MATLAB Editor.
Once you get a hang of dbstop and it's syntax, you won't often need to insert a keyboard into your code, but it's always an option.
Try placing the keyboard command in your code to insert a breakpoint. When the keyboard command is reached, MATLAB will drop into an interactive prompt that you can use to inspect variables. For example:
x = rand(10,10);
y = rand(10,5);
z = x * y;
keyboard; % you can interactively inspect x, y, z here
z = sort(z);
To leave keyboard mode, you can type dbquit to exit the program, or return to continue executing the program.
Another trick is to turn on dbstop if error which will automatically drop you into an interactive prompt whenever your code crashes.
You can use MATLAB -Dgdb if that helps. This sets gdb as the debugger. You will need to be familiar with gdb of course.
Once you do that, use the standard gdb commands to debug it.
EDIT
My mistake. Above won't work for M-Files. (Not having MATLAB to try things out is a pain :)
MATLAB has a pretty good set of debugging commands you can use from the commandline. If you insert keyboard commands in your MATLAB code, you can then use the commands.
You can use MATLAB's editor debug button to debug within MATLAB environment