Click here to Skip to main content
Click here to Skip to main content

CKeystrokeEngine

By , 21 Jun 2004
 

Introduction

CKeystrokeEngine was originally written to allow users of my product, Macro Angel, to send keystrokes to the active or to a selected window. Its functionality is similar to VB's SendKeys's functionality, but it allows more complex operations. In addition to sending keystrokes to the active window, by the help of CWindowEngine (which was also written for Macro Angel), it can send keystrokes to only a specified window.

A simple CKeystrokeEngine expression looks like this:

Hello CPians<ENTER><REPEAT 10>I love CP <END_REPEAT><ENTER>http://www.macroangel.com

All special keys are put between '<' and '>' characters. For example to simulate an Enter key, you should use <ENTER>. Or to press Shift key, use <SHIFT>. Here are some more examples:

  • To send Ctrl+A use <CTRL>A
  • To send Alt+F4 use <ALT><F4>
  • To send Ctrl+Alt+Shift+A use <CTRL+ALT+SHIFT>A
  • You can also use <CTRL+ALT>, <CTRL+SHIFT> and <ALT+SHIFT>
  • To hold Shift key and many keys, use <SHIFT_LOCK>write your keys here<SHIFT_UNLOCK>
  • You can also use <ALT_LOCK>, <ALT_UNLOCK>, <CTRL_LOCK> and <CTRL_UNLOCK>
  • To add a delay use <DELAY xxx> where xxx is the amount of time in miliseconds. For example, <DELAY 1500> waits 1.5 seconds.
  • To repeat a sequence of keys 100 times, use <REPEAT 100>you keys here<END_REPEAT>. Please note that nested repeats are not supported

All other keys are listed in the sample application. Here are the public functions of CKeystrokeEngine

CKeystrokeEngine (const CString &sKeys);

void SetPause (bool bPause, int nPause);
void SetSendToWnd (bool bSendToWnd);
// if lpszTitle == NULL, then the feature is disabled
void SetWndTitle (LPCSTR lpszTitle);
// if lpszClass == NULL, then the feature is disabled
void SetWndClass (LPCSTR lpszClass);
void SetExactMatch (bool bExact);
void SetCaseSensitive (bool bCaseSensitive);
void SetReActivate (bool bReactivate, int nMiliseconds);

// Tadaaa. Here is the best function...
bool SendKeys ();

SetPause (bool bPause, int nPause)<br>
  
Adjusts how much time CKeystrokeEngine should wait in-between each key-press when sending keystrokes. On some faster machines, CKeystrokeEngine may type the keys too quickly, flooding the keyboard buffer and causing unpredictable results. Increasing this setting will prevent this from occurring.

SetSendToWnd (bool bSendToWnd)<br>
  
If bSendToWnd is true, then CKeystrokeEnginesends all keystrokes to a specified window. By this way, sending keystrokes to wrong windows is prevented.

If bSendToWnd is set to false, then active window gets all keystrokes.

SetWndTitle (LPCSTR lpszTitle)<br>
  
Sets the window title, to which the keystrokes will be sent. If lpszTitle is set to NULL, then CKeystrokeEngine does not searh for a window title. Note that this is effective only if SetSendToWnd (true) is used.

SetWndClass (LPCSTR lpszClass)<br>
  
Sets the window class, to which the keystrokes will be sent. If lpszClass is set to NULL, then CKeystrokeEngine does not search for a window class. Note that this is effective only if SetSendToWnd (true) is used.

SetExactMatch (bool bExact)<br>
  
Specified whether the Windows title entered is a partial title match or must match exactly. When set to false,CKeystrokeEngine will search for window titles that contain that text. Note that this is effective only if SetSendToWnd (true) is used.

SetCaseSensitive (bool bCaseSensitive)<br>
  
If enabled, Window Title/Window Class and Text searches would be case sensitive. Note that this is effective only if SetSendToWnd (true) is used.

SetReActivate (bool bReActivate, int nMiliseconds)<br>
  
If bReActivate is set to true, then CKeystrokeEngine automatically re-activates the window whenever it looses focus. If 0 seconds is entered, then the window is immediately activated when it looses focus. Otherwise, CKeystrokeEngine waits for the specified amount of time and then re-activates the window.

Adding a delay before re-activating windows prevents collisions between applications that are trying to send keystrokes at the same time.

Note that this is effective only if SetSendToWnd (true)is used. Also, if bReActivate is set to false, and specified window looses focus, then SendKeys () function returns false.

bool SendKeys ()<br>
  
Finally, this functions sends the keys with the specifed options. Use this function setting all attributes of CSendKeystrokes.

To get more information about the supported keywords, please use the sample application...

Some points that you should keep in mind

  • To use CKeystrokeEngine in your applications, copy KeystrokeEngine.cpp, KeystrokeEngine.h, WindowEngine.cpp and WindowEngine.h into your project and include KeystrokeEngine.h in your cpp file.
  • This class uses its own syntax, instead of using VBs SendKeys () syntax. Please don't want me to change the syntax. My customers are really happy with this syntax :)
  • This class is not used in the current version of Macro Angel. It will be used in the next version. Current version uses the same syntax, but the implementation is not as good as this. But this is class is not tested yet and may include some bugs. Please send me the bugs, so that I can fix them. If you find a bug, please send me the String that causes is not working properly. Also, please send me the real output and the expected output.
  • If you have any suggestions, please let me know.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

About the Author

Mustafa Demirhan
Software Developer (Senior)
United States United States
Member
No Biography provided

Sign Up to vote   Poor Excellent
Add a reason or comment to your vote: x
Votes of 3 or less require a comment

Comments and Discussions

 
You must Sign In to use this message board.
Search this forum  
    Spacing  Noise  Layout  Per page   
GeneralProblem Sending Keystroke to MDI applicationmembergewoog5 Oct '07 - 14:04 
I try to send some keystrokes (say "Hello") to one of the Visual Studio Child Window, nothing is being done to that window. Do anyone know why? Thanks
 
ewoo
Generalport to vb.netmemberraventatatatata14 May '07 - 16:41 
I would like to know if this could be ported to vb.net as the vb sendkeys.send method is terrible.
It has lots of lag, even when sending to itself let alone another process, where as this method is for all practical terms instantaneous. (and brilliant)
 
Cheers.
GeneralHotkeysmemberOle Martin Brynildsen16 Mar '07 - 2:52 
Thanks for great code!
 
Is it possible to avoid hotkey/shortcut-programs to react on the keystrokes from this class? The same hotkeys is not activated when using the standard xp onscreen keyboard.
 
We now need to deactivate hotkey-programs, specialy on laptops, to avoid all kinds of hotkey-actions, when we uses this class to write to a standard editor control.
 
Any ideas on how to avoid this behaviour?

QuestionCan This Be Called From Vb6memberkillervolt12 Feb '07 - 20:12 
Hi,
 
Can i use your program and send it keys from a VB6 project?
 
Thanks.
AnswerRe: Can This Be Called From Vb6memberMustafa Demirhan13 Feb '07 - 9:54 
No, you can't. But you can use the SendKeys function in VB.
 
Mustafa Demirhan
http://www.macroangel.com

"What we do in life echoes in eternity" - Gladiator
It's not that I'm lazy, it's just that I just don't care

QuestionRe: Can This Be Called From Vb6memberraventatatatata20 May '07 - 16:02 
What if the source was compiled to a dll with WinAPI functions in it? Could that work? And would it be an improvement over sendkeys??
 
Cheers
General5/5memberRajesh R. Subramanian9 Dec '05 - 19:21 
Simply,



"FIVE OUT OF FIVE"




 
Regards,
Rajesh R. Subramanian
 
You have an apple and me too. We exchange those and We have an apple each.
You have an idea and me too. We exchange those and We have two ideas each.

GeneralRe: 5/5memberMustafa Demirhan9 Dec '05 - 23:57 
Thanks for the compliment Wink | ;)
 
Mustafa Demirhan
http://www.macroangel.com

"What we do in life echoes in eternity" - Gladiator
It's not that I'm lazy, it's just that I just don't care

Questionhow to send to a processmemberlbolanos27 Jan '05 - 10:31 
How can i send a keystroke to a process?
 
thanks
AnswerRe: how to send to a processmemberz-taken20 Nov '06 - 5:13 
Hi lbolanos,
I am looking for a solution just like what you were trying to do. According to MSDN, it seems that sending a keystroke is quite different than sending a keystroke to a window in the same process.
 
Basically, I would like to send a character to a edit control which resides in a dialog box on another process.
 
thanks
 

 
Zhi

GeneralTerminal ServicessussAnonymous17 Dec '04 - 11:42 
Do you know if the sending keystrokes thiw way will work with a W2K PC sending the keystrokes thru a Terminal Services Client ?
QuestionUpdated 22 Jun 2004?memberJL00225 Jun '04 - 3:48 
Hello Mustafa!
 
I got very happy when I saw that your article was updated, but I tried the demo executable and still had the same problem with the key, it simple doesn´t work!
 
What was exactly updated in the article?
 
It is a pitty that this beautiful job get almost useless (on some Windows XP versions at least) due this little bug...
 
Have a nice day! Smile | :)

AnswerRe: Updated 22 Jun 2004?memberMustafa Demirhan25 Jun '04 - 10:57 
Hi there,
 
The article was not actually updated. I put my e-mail adresses into all my articles and my stupidity paid of well by hundreds of spam e-mails every day.
 
So, I contacted to the CodeProject and told them that I want to remove my e-mail address. They did it in a few hours (thanks Wink | ;) ) but the articles showed as updated. I am sorry for the confusion.
 
Actually, I have another Keystroke Engine that is based on an MSDN articles code - this new engine works fine on Windows Xp/2000/NT but does not support win9x/me. It also works with different locales and it can send any unicode characaters. I think I will send another article with that engine Wink | ;)
 
PS: If you send me an e-mail via Codeproject's e-mail options, I can send it to you...
 


 
Mustafa Demirhan
http://www.macroangel.com

"What we do in life echoes in eternity" - Gladiator
It's not that I'm lazy, it's just that I just don't care

QuestionIt is possible to send keystrokes without bringing the window forefront?memberJL0021 Jun '04 - 11:05 
Sometimes bringing the receiving keystrokes window forefront is quite annoying. Is there a way to avoid it?
 
Thanx! And congratulations for the great work!
AnswerRe: It is possible to send keystrokes without bringing the window forefront?memberMustafa Demirhan2 Jun '04 - 7:32 
This code simulates the key presses of a keyboard - so, it is no different than using a keyboard. Because of that, you cannot send keystrokes to a window that is not on the foreground.
 
However, you can use SendMessage function and send WM_CHAR and some other messages to a background window. You can find such an example at
 
http://www.autoitscript.com/autoit3/files/archive/autoit/
 
This is an automation program. Download the source code for v3 and extract the send keys part of the code.
 
Mustafa Demirhan
http://www.macroangel.com

"What we do in life echoes in eternity" - Gladiator
It's not that I'm lazy, it's just that I just don't care

GeneralRe: It is possible to send keystrokes without bringing the window forefront?memberJL00214 Jun '04 - 8:33 
Thanxs for your answer! Smile | :)
 
I´m facing the same issue JessicaLampe highlighted, I cannot send keys. I use Windows XP sp1 with all the updates from Windows Update and my keyboard layout it´s set to portuguese(ABNT2) did you find what is going on?
 

And the last one...
Are you still developing MacroAngel? Or even CKestrokeEngine?
 
Thank you !
GeneralRe: It is possible to send keystrokes without bringing the window forefront?memberMustafa Demirhan15 Jun '04 - 10:26 
Hi there,
 
I actually developped a completely different Keystroke engine, but I did not send it to the code project yet OMG | :OMG:
 
The new code was based on an MSDN article's sample code. I modified it and added my own features. It seems to be working perfectly, but I dont know whether I should post that too or not - I first need to consult the author of the MSDN article and see if I have the rights to re-distribute a modified version of it.
 
I am still developping Macro Angel but I couldnt spend as much time as I should spend on it Frown | :(
 
Mustafa Demirhan
http://www.macroangel.com

"What we do in life echoes in eternity" - Gladiator
It's not that I'm lazy, it's just that I just don't care

GeneralRe: It is possible to send keystrokes without bringing the window forefront?membersfirouza8 Dec '04 - 21:07 

Mustafa Demirhan wrote:
The new code was based on an MSDN article's sample code
 

Would u please atleast send the msdn example link?
AnswerRe: It is possible to send keystrokes without bringing the window forefront?memberInfiniTeEn10 Jul '04 - 4:36 
Hi,
First, let me comment that it is a very nice program Wink | ;) , Especially liked the magnifying glass...
 
I'm also trying to find out how to send keystrokes and mouse clicks to a window that is minimised.
Any clues? Confused | :confused:
Thanks Big Grin | :-D
 
"Do Nothing and Nothing WILL Be Done Wrongly" -- InfiniTeEn
General&lt;Repeat 10&gt; Great! &lt;end repeat&gt;memberbdiamond20 May '04 - 4:52 
Great! I give you a 5!
 
If it's broken, I probably did it
 
bdiamond
GeneralRe: &lt;Repeat 10&gt; Great! &lt;end repeat&gt;memberMustafa Demirhan20 May '04 - 5:26 
Smile | :)
 
Mustafa Demirhan
http://www.macroangel.com

"What we do in life echoes in eternity" - Gladiator
It's not that I'm lazy, it's just that I just don't care

QuestionCan not Compile In VC.NET2003, Miss Afximpl.hmemberzhbjhwli13 Mar '04 - 15:38 
Good, But Can not Compile In VC.NET2003, Miss Afximpl.h, will you can repair?
AnswerRe: Can not Compile In VC.NET2003, Miss Afximpl.hmemberMustafa Demirhan13 Mar '04 - 23:05 
Sorry, but I dont have VC.NET or VC.NET2003 and I don't know what the problem is Frown | :(
 
Mustafa Demirhan
http://www.macroangel.com

"What we do in life echoes in eternity" - Gladiator
It's not that I'm lazy, it's just that I just don't care

GeneralImplementation part of that version of MFC used in this applicaitonmemberyuhaian17 Jan '05 - 10:24 
This file is not missing, it's in C:\Program Files\Microsoft Visual Studio .NET 2003\Vc7\atlmfc\src\mfc. So update source to:
 
#include "../src/mfc/afximpl.h"
 
Other possible updates:
. change 'bWin4' to 'bWin95'
. LRESULT CSystemTray::OnTaskbarCreated(WPARAM, LPARAM)
. // DrawAnimatedRects( pWnd->m_hWnd, IDANI_CAPTION, rectFrom, rectTo);
 
But this application use implementation part of that version of MFC. The afxData structure etc. need to update as well. Not working even after above changes.
 
Attached following message for Mustafa Demirhan, if he is interested to take some functions out for VC.NET 2003:
 
------ Build started: Project: KeyTest, Configuration: Debug Win32 ------
 
Compiling...
MiscCtrls.cpp
d:\TestDev\CKeystrokeEngine\KeyTest\miscctrls.h(675) : warning C4183: 'Create': missing return type; assumed to be a member function returning 'int'
d:\TestDev\CKeystrokeEngine\KeyTest\MiscCtrls.cpp(53) : error C2039: 'bWin4' : is not a member of 'AUX_DATA'
c:\Program Files\Microsoft Visual Studio .NET 2003\Vc7\atlmfc\src\mfc\afximpl.h(54) : see declaration of 'AUX_DATA'
d:\TestDev\CKeystrokeEngine\KeyTest\MiscCtrls.cpp(60) : error C2039: 'bWin4' : is not a member of 'AUX_DATA'
c:\Program Files\Microsoft Visual Studio .NET 2003\Vc7\atlmfc\src\mfc\afximpl.h(54) : see declaration of 'AUX_DATA'
d:\TestDev\CKeystrokeEngine\KeyTest\MiscCtrls.cpp(64) : error C2039: 'bWin4' : is not a member of 'AUX_DATA'
c:\Program Files\Microsoft Visual Studio .NET 2003\Vc7\atlmfc\src\mfc\afximpl.h(54) : see declaration of 'AUX_DATA'
d:\TestDev\CKeystrokeEngine\KeyTest\MiscCtrls.cpp(74) : error C2039: 'bWin4' : is not a member of 'AUX_DATA'
c:\Program Files\Microsoft Visual Studio .NET 2003\Vc7\atlmfc\src\mfc\afximpl.h(54) : see declaration of 'AUX_DATA'
d:\TestDev\CKeystrokeEngine\KeyTest\MiscCtrls.cpp(1398) : error C2440: 'static_cast' : cannot convert from 'void (__thiscall CSystemTray::* )(WPARAM,LPARAM)' to 'LRESULT (__thiscall CWnd::* )(WPARAM,LPARAM)'
None of the functions with this name in scope match the target type
d:\TestDev\CKeystrokeEngine\KeyTest\MiscCtrls.cpp(1630) : error C2660: 'CWnd::DrawAnimatedRects' : function does not take 4 arguments
d:\TestDev\CKeystrokeEngine\KeyTest\MiscCtrls.cpp(1647) : error C2660: 'CWnd::DrawAnimatedRects' : function does not take 4 arguments
KeyTest - 7 error(s), 1 warning(s)

 
---
Herbert Yu
Are you sure the speed of computer industry is proper? Are you sure the software you released is a bug free one?
GeneralProblem with WinXPsussJessicaLampe20 Jan '04 - 8:18 
Hello,
 
this is a good class, but there is a problem with Microsoft XP.
The ALT-key is not send to the selected window.
 
For example I would send a combination "ALT+F4" to close the window.
These keys are only send to the window when the window is in the task and not on the screen.
 
It seems, the problem is that I use a non-U.S. keyboard layout or the error is in the "loose-focus"-function.
 
Or is it a problem from WinXP???
 
I need help, please!
 
THANX
JESSICA Rose | [Rose]

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Permalink | Advertise | Privacy | Mobile
Web01 | 2.6.130516.1 | Last Updated 22 Jun 2004
Article Copyright 2002 by Mustafa Demirhan
Everything else Copyright © CodeProject, 1999-2013
Terms of Use
Layout: fixed | fluid