AutoHotkey SendInput Problems - autohotkey

[Key Mappings of New Media Remote]
http://i.stack.imgur.com/ivMSK.png
Using AutoHotkey I want to interrupt Keyboard Keys sent like AppsKey and Browser_Home and send another key instead. Unfortanately the best I can manage is to send a key as well as the key function.
F3::SendInput {a}
Browser_Home::SendInput {a}
Browser_Home::SendInput a
Browser_Home:: a
The first line 'F3 to a' works as intended; the F3 Key outputs the letter a.
The 2nd and 3rd line Browser_Home only launches Browser to Home.
The 4rd line launches the Browser_Home as well as outputting the letter a.
Anyone know what I'm doing wrong / know how to fix my script to output a without launching browser to home?

According to documentation under Hotkey:
$ is usually only necessary if the script uses the Send command to send the keys that comprise the hotkey itself, which might otherwise
cause it to trigger itself. The $ prefix forces the keyboard hook to
be used to implement this hotkey, which as a side-effect prevents the
Send command from triggering it. The $ prefix is equivalent to having
specified #UseHook somewhere above the definition of this hotkey
Try this and report back: $Browser_Home::SendInput {a}

Related

AutoHotKey function to perform File-Rename without relying on sending F2 key code

I want define a custom hotkey to rename a selected file in File Explorer. So my new hotkey should behave exactly like the F2 key does by default. That is, when I press the hotkeys, the file name should be editable, allowing me to type a new name. However, I can't use the F2 key to cause windows to do this.
The reason is that I'm using the default hotkeys for something else. I am often running an application (unrelated to AutoHotKey) where the buttons in the UI are triggered using keyhooking for all of the F keys. The only suggestions that I can find on this are to have my custom hotkey use 'send' to raise the default key codes that would be associated with the action. This won't work, because I am using those hotkeys for something else. What I need is a solution that causes a file to be renameable without sending the F2 keycode.
^+!R::
Send {F2} ;This won't work for me
return
Actually the original hotkey can be used, just add $ before the hotkey that you don't want to be fired by the send command. Also using app-specific hotkeys a good idea to minimize possible conflicts.
Try this:
#If winActive("ahk_exe Explorer.EXE")
^+!R::
send {F2}
return
$F2::
send {down}
return
In case you have an application which scans the F2 key globally and unconditionally, and you cannot redefine it, there is not much you can do from within AHK. So ideally you should get rid of that application, and use e.g. AHK for same functionality, or find some workaround.
In this particular case the easiest workaround is alternative way to rename the file:
^+!R::
send {AppsKey}
sleep 100
send {m}
return

Sending keys from ahk so ahk registers them

Is it possible to Send key strokes (e.g., ctrl+alt+b xyz) using ahk and have activated corresponding hotkey ?
E.g., I have ^!b:: that shows MsgBox. I have ^!c:: from which I'd like to Send, ^!b and I want ^!b:: code to be activated.
My goal: I have various hotkeys in combination with Input. I want to have a hotkey to repeat last command.
Thank you

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.

Send command, isn't something wrong with AutoHotkey?

So I have this game, called AirMech. It doesn't recognize mouse buttons as controls (yet) so I tried to use AutoHotkey to circumvent it until it's implemented.
#IfWinActive, AirMech
XButton1::Send c
Didn't work. So I tried SendGame, SendPlay and everything else, didn't work either. I googled it, and found out that some games don't recognize any Send commands at all.
Before giving up, I just tried a simple mapping:
#IfWinActive, AirMech
XButton1::c
It actually worked.
Is it expected than no Send command works, but the latter does? What if I wanted to trigger other actions ('c' plus a MsgBox, for instance)?
AutoHotkey has the ability to send keystrokes in a variety of different ways (SendRaw / SendInput / SendPlay / SendEvent). I'm not quite sure what approach the simple key::key mapping uses, but it must be one of them. My guess is that one of SendRaw, SendInput, SendPlay, or SendEvent will work the same as key::key.
Also #IfWinActive sometimes doesn't work exactly the way you expect, especially with fullscreen games. So I usually test my AHK scripts without the #IfWinActive to make sure they're working correctly. Once it's working, I introduce the conditional.
UPDATE
From http://www.autohotkey.com/docs/misc/Remap.htm:
When a script is launched, each remapping is translated into a pair of
hotkeys. For example, a script containing a::b actually contains the
following two hotkeys instead:
*a::
SetKeyDelay -1 ; If the destination key is a mouse button, SetMouseDelay is used instead.
Send {Blind}{b DownTemp} ; DownTemp is like Down except that other Send commands in the script won't assume "b" should stay down during their Send.
return
*a up::
SetKeyDelay -1 ; See note below for why press-duration is not specified with either of these SetKeyDelays. If the destination key is a mouse button, SetMouseDelay is used instead.
Send {Blind}{b Up}
return
My notes:
I suspect the reason a::b is working but a::Send b is not is because of how a::b breaks button down and button up handlers into two separate mappings. The game's gameloop probably polls the gameplay keys for "keydown" state, which would not be maintained consistently if AHK is synthesizing repeats. Remapping a_down->b_down and a_up->b_up probably makes AHK emulate more accurately the act of holding the key down, which may matter for programs which test for key state in particular ways (GetAsyncKeyState?).
The asterisk in the mapping means "Fire the hotkey even if extra modifiers are being held down."

Autohotkey: Commands with Alt Key Working Properly only if not Restricted to a Specific Application

I'm trying to add custom keyboard commands to an application using Autohotkey.
In many of these hotkeys I would like to use the alt key in combination with some other key of my choice (any of the standard letters).
All works fine as long as I don't restrict their usage in such a manner that they work in the target application only (via the #IfWinActive directive ). If I do so, the hotkeys themselves still work, however their behavior is very strange.
I found that they get activated either if
a) I hold down the alt key and then press the second key (in my case the 'b' key) twice
or
b) I use this hotkey two times consecutively with a very short delay between the two triggerings
- The above two cases might actually be 1 case. I'm not sure...
I have no problems when doing the same with Shift or CTRL.
The 'b' key is not what's causing the problem - no alt + 'letter' combination works.
I have tried all SendModes, but so far with no effect.
Code sample:
#IfWinActive, MyAppTitle ahk_class MyAppClass
!b::
click 367, 86
return
Alt+letter commands in AutoHotkey such as !b work without issue. It's possible the version at the time of this post contained certain bugs or was out of date from the current version.
For your code, it could be done like so:
!b::
WinGetTitle, Title, A
if (RegExMatch(Title, "MyAppTitle"))
{
MouseClick, left, 367, 86
}
return