keybd_event is not working right =( - c++

I can't get this to work right. This should press left for 1 second then wait 10 seconds, then right 1 second, etc.:
keybd_event(0x25, 0xCB, 0, 0); // press left
cout << "Ldown\n"; // so i know it worked
Sleep(1000); // hold it for 1sec
keybd_event(0x25, 0xCB, KEYEVENTF_KEYUP, 0);// let go of the key
cout << "Lup\n"; // so i know i let go
Sleep(10000); // Sleep for 10secs
keybd_event(0x27, 0xCD, 0, 0); // press right
cout << "Rdown\n"; // so i know i pressed right
Sleep(1000); // sleep 1sec
keybd_event(0x27, 0xCD, KEYEVENTF_KEYUP, 0);// let go of the key
cout << "Rdown\n"; // so i know i let go.
This is in a loop but it wont do anything :( Unless I close the program before the key is let go, then it will just keep the key down until I press the key again.
I know you can use only one key code if you want but I need to use both.
So what am I missing?

The code seems to work for me. I cleaned it up a bit (no magic numbers!, use MapVirtualKey, helper functions, etc.):
#include <iostream>
#include <windows.h>
// for key pushing
BYTE scan_code(DWORD pKey)
{
const DWORD result = MapVirtualKey(pKey, MAPVK_VK_TO_VSC);
return static_cast<BYTE>(result);
}
void press_key(DWORD pKey)
{
keybd_event(static_cast<BYTE>(pKey), scan_code(pKey), 0, 0);
}
void release_key(DWORD pKey)
{
keybd_event(static_cast<BYTE>(pKey), scan_code(pKey), KEYEVENTF_KEYUP, 0);
}
// for testing
#define PRESS(x) press_key(x); std::cout << "Press: " #x << std::endl
#define RELEASE(x) release_key(x); std::cout << "Release: " #x << std::endl
// test
int main(void)
{
for (;;)
{
PRESS(VK_LEFT);
Sleep(10); // hold it for 1/100'th of a second
RELEASE(VK_LEFT);
Sleep(1000); // wait for a second
PRESS(VK_RIGHT);
Sleep(10); // hold it for 1/100'th of a second
RELEASE(VK_RIGHT);
Sleep(1000); // wait for a second
}
}
I tested by opening Notepad, typing a bunch of characters, then ran the program. The caret moved back and forth. How are you testing it?

How are you measuring "doesn't do anything"? Is it just that no output appears? Use std::endl to end your lines, as GMan does, instead of "\n", because endl performs a flush in addition to outputting a newline character.

Related

Why is std::wcout not working after using FillConsoleOutputCharacter()?

I am currently working on a simple console application that is to become a text-based RPG game based on economy. I have an 80x20 (character cells) window that will work as my display.
I have been experimenting with the FillConsoleOutputCharacter() API function, which seems to work as desired for clearing the console.
Before I use the function, I have simple output using wcout to display certain characteristics, such as the screen buffer size and the window size; but after outputting with FillConsoleOutputCharacter(), I notice that wcout does not output as it should.
I have the API function nested in another function named clearConsole(), and have noticed that output using wcout works as it should after leaving the function, but not after the call to FillConsoleOutputCharacter() (within the function).
Here is the function:
void clearConsole(HANDLE screen)
{
DWORD cCharsWritten;
CONSOLE_SCREEN_BUFFER_INFO bufferInfo;
DWORD dwConsoleSz;
if(!GetConsoleScreenBufferInfo(screen, &bufferInfo))
{
return;
}
dwConsoleSz = bufferInfo.dwSize.X * bufferInfo.dwSize.Y; /* This should be equivalent to the number of character cells in the buffer. */
/* Now we fill the entire screen with blanks. */
if(!FillConsoleOutputCharacter(
screen,
L' ',
dwConsoleSz,
cursorHome,
&cCharsWritten
));
{
return;
}
/* Then we get the current text attribute (maybe unnecessary?) */
if(!GetConsoleScreenBufferInfo(screen, &bufferInfo)) /* Perhaps the ScreenBuffer needs to be set again, see SetConsoleCursorPosition. */
{
return;
}
/* And set the buffer's attributes accordingly. */
if(!FillConsoleOutputAttribute(
screen,
bufferInfo.wAttributes,
dwConsoleSz,
cursorHome,
&cCharsWritten
))
{
return;
}
if(!SetConsoleCursorPosition(screen, bufferInfo.dwCursorPosition))
/*Research is needed regarding this function as it does not seem to move the cursor. */
{
wcout << L"SetConsoleCursorPosition failed. Error Code: " << GetLastError();
system("pause");
}
wcout << L"Screen Buffer Size: " << bufferInfo.dwSize.X << L',' << bufferInfo.dwSize.Y << L'\n' << L"Cursor Position: " <<
bufferInfo.dwCursorPosition.X << L',' << bufferInfo.dwCursorPosition.Y << L'\n' <<
L"Buffer Top X: " << bufferInfo.srWindow.Left << L' ' << L"Buffer Top Y: " << bufferInfo.srWindow.Top << L'\n' << L"Buffer Bottom X : " << bufferInfo.srWindow.Right << L' ' << L"Buffer Bottom Y: " << bufferInfo.srWindow.Bottom << L'\n';
wcout << L"hello from clearConsole" << L'\n';
/* wcout stops working from within this function after FillConsoleOutputCharacter is
called. But for some odd reason it begins working again after the function ends.
*/
Sleep(1000);
return;
}
What could be the cause for this?
I have experimented with moving the wcout lines around within the nesting function, and have seen that it works before the call to the API function, but not after. A strange malfunction. Flushing wcout (or the output stream) does not solve the issue, either.
Setting the cursor back to (0,0) does not seem to place the cursor back at the top left corner of the console, either. screen is a global variable set to STD_OUTPUT_HANDLE.
EDIT: Also, trying to set the cursor back to (0,0) using a global COORD object cursorHome in the call to SetConsoleCursorPosition() before writing to output does not seem to work, either.
EDIT: Setting the cursor's position after the call to clearConsole() works as well. What could be the cause of this strange behavior?
After multiple tests. It is caused by a very minor error - the ; after FillConsoleOutputCharacter().
/* Now we fill the entire screen with blanks. */
if(!FillConsoleOutputCharacter(
screen,
L' ',
dwConsoleSz,
cursorHome,
&cCharsWritten
)); // <-- HERE
{
return;
}
It cuts off the front and back connection and destroys the logic. It means that whatever value is returned by FillConsoleOutputCharacter() has nothing to do with the content in { }.
Just delete it.

Atomically write colored text to console in Windows

I need to print to console some output with color content. Is it possible to do in windows atomically? In Linux there is ansi colors support and it is really very convenient to do complex colored sentences. What about windows? I can do the following:
HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE);
printf(" this is how it starts ");
SetConsoleTextAttribute(hConsole, 10);
printf("YES, it should be green ");
SetConsoleTextAttribute(hConsole, 0);
printf("back to standard color\n");
It seems to me that in asynchronous app this 3 printf will not print text at the same line in console. Here comes 2 solutions in my mind:
1) Use mutex for syncing all console output so as all messages appear sequentially. Seems an overkill solution for such problem.
2) Use some method to stop console output for a while, print colored line and then start output again.
So, my concern is getting colored line without breaks made by other asynchronous output. Is it possible in windows and what is the best approach?
As #eryksun said, use WriteConsoleOutput instead of printf/std::cout.
This is the same as any graphical application. Only one thread does all the writing. It has a queue which contains a list of strings and attributes. When a thread wishes to print something, it pushes the string and the relevant attribute into the queue. Before printing the writing thread sets the attribute and then prints the string.
You will need to implement your own thread-safe queue. Mine are normally low volume outputs so I use an array of 256 with a uint8_t counter and atomic markers. There is no boundary checking: uint8_t wraps back to 0 after 255. Circular queues work quite well.
You can create a very simple class to do the writing. I normally use something like this. Scribbler is the class that does the writing to the screen
class COut : public std::ostringstream
{
Scribbler* writer;
WORD attr;
public:
COut(WORD in_attr)
{
attr = in_attr;
writer = Scribbler::Me();
}
COut& operator << (std::ostream&(*f)(std::ostream&))
{
if (f == std::endl)
{
*this << "\n";
writer->Push(attr, str());
str("");
}
else
{
*this << f;
}
return *this;
}
template <typename TT>
inline COut& operator << (const TT& t)
{
(*(std::ostringstream*) this) << t;
return *this;
}
};
This can be used like std::cout and it will do everything you can do with std::cout. Alternatively, you can write a variant of printf but it isn't that simple when you get into the depths of passing std::arg all over the place.
The thread wanting yellow output would do something like
COut yout(FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_INTENSITY);
...
yout << "Yellow, yellow dirty fellow" << std::hex << std::setfill('0') << std::setw(4) << 25 << std::endl;
The thread wanting magenta output would do
COut mout(FOREGROUND_RED | FOREGROUND_BLUE | FOREGROUND_INTENSITY);
...
mout << ... << std::endl;
Nothing gets printed until a std::endl is issued. You can get quite creative with this with different threads writing to different scrollable parts of the screen using SetConsoleWindowInfo. It will work as long as there is only one thread that does the writing. All the other threads just tell it where to write the output and its colour attributes.

Repeating loop until enter is pressed

For anybody else finding this question, this can be accomplished with the kbhit() function in the conio.h library. Just insert !kbhit() where I put SOMETHING and it will loop correctly, I am looking for a way to do this without a library, however.
I'm a beginner trying to create a simple animation in the console. The animation would have the word UP going up the right hand of the console and the word DOWN going down the right hand side. So far I have gotten the animation to complete one iteration of this, but I'm trying to make it so that it repeats and it looks like the texts wraps back to the top or bottom and does it again until the user presses the ENTER key.
My book (I'm self teaching from a textbook) makes it seem that its possible without any specific libraries except for iostream and windows.h but help that includes library functions is welcome too, it is a learning experience after all. Thanks a ton!
A little explanation of the code would be that I set the coordinates of the UP and DOWN starting positions and then move the cursor, delete the previous line it was on with a space and then increment two and put a new word. I would guess that I could use a second while loop to somehow check if the ENTER key has been pressed.
#include <iostream>
#include <windows.h>
using namespace std;
int main()
{
HANDLE screen = GetStdHandle(STD_OUTPUT_HANDLE);
COORD upPos = {20,28};
COORD downPos = {50, 0};
char endState;
while ( SOMETHING )
{
COORD upPos = {20,28};
COORD downPos = {50, 0};
while (upPos.Y >=0)
{
SetConsoleCursorPosition(screen,upPos);
cout << "UP" << endl;
upPos.Y++;
SetConsoleCursorPosition(screen,upPos);
cout << " " << endl;
upPos.Y -=2;
SetConsoleCursorPosition(screen,downPos);
cout << "DOWN" << endl;
downPos.Y--;
SetConsoleCursorPosition(screen,downPos);
cout << " " << endl;
downPos.Y+=2;
Sleep(100);
}
}
}
Your best bet is to create a custom "GetAsyncKeyState" function that will use #IFDEF for windows and linux to choose the appropriate GetAsyncKeyState() or equivalent. For ex
if (GetAsyncKeyState(VK_RETURN))
{
exit = true;
}

loop to discard spurious variable input from stdin, Linux C++

I am trying to write a c++ program for my linux machine that can interact with some instrumentation that responds to simple ascii commands. The problem I'm running into, I would think, would be a fairly common request but my searches of various forums came up with nothing quite the same.
My problem is this: When I connect to the instrument, due to some communication issues, it often pukes up a bunch of data of varying length that I don't want. The data the machine prints has line endings with '\r'. I have been trying to write a simple loop what will keep reading and ignoring data until the machine is quiet for two seconds, then carry on to perform some data requests once the storm is over.
When searching forums, I found gobs and gobs of threads about cin.ignore, cin.sync, getline and cin.getline. These all seemed quite useful but when I attempted to implement them in a way that should be simple, they never behaved quite as I expected them to.
I apologize in advance if this is a duplicate post as I would have thought I wasn't the first person to want to throw away garbage input but I have found no such post.
The code I have been trying a few different arrangements of looks something like this:
sleep(2);
cin.clear();
while ( cin.peek() != char_traits<char>::eof()) {
//cin.sync();
//cin.ignore(numeric_limits<streamsize>::max(),char_traits<char>::eof());
cin.clear();
char tmp[1];
while ( cin.getline(tmp,80,'\r') ) {}
cin.clear();
sleep(2);
}
I understand from my searches that doing some sort of while(!cin.eof()) is bad practice but tried it anyway for grins as well as while(getline(cin,str,'\r')) and while(cin.ignore()). I am at a loss here as there is clearly something I'm missing.
Thoughts?
EDIT: --final code--
Alright! This did it! Thanks for point me to termios #MatsPetersson! I wound up stealing quite a lot of your code, but I'm glad I had the opportunity to figure out what was going on. This website helped me make sense of the tcassert manual page: http://en.wikibooks.org/wiki/Serial_Programming/termios
#include <cstdlib>
#include <iostream>
#include <stdio.h>
#include <unistd.h>
#include <limits>
#include <termios.h>
#include <errno.h>
#include <cassert>
using namespace std;
const int STDIN_HANDLE=fileno(stdin);
int main()
{
string str;
//Configuring terminal behavior
termios tios, original;
assert( tcgetattr(STDIN_HANDLE, &tios)==0 );
original = tios;
tios.c_lflag &= ~ICANON; // Don't read a whole line at a time.
tios.c_cc[VTIME] = 20; // 0.5 second timeout.
tios.c_cc[VMIN] = 0; // Read single character at a time.
assert( tcsetattr(STDIN_HANDLE, TCSAFLUSH, &tios)==0 );
const int size=999; //numeric_limits<streamsize>::max() turns out to be too big.
char tmp[size];
int res;
cerr << "---------------STDIN_HANDLE=" << STDIN_HANDLE << endl;
cerr << "---------------enter loop" << endl;
while ( res=read(STDIN_HANDLE, tmp, sizeof(tmp)) ) {
cerr << "----read: " << tmp << endl;
}
cerr << "--------------exit loop" << endl;
cout << "END";
assert( tcsetattr(STDIN_HANDLE, TCSANOW, &original)==0 );
return 0;
}
That wasn't as bad as I began to fear it would be! Works perfectly! Obviously all the cerr << -- lines are not necessary. As well as some of the #include's but I'll use them in the full program so I left them in for my own purposes.
Well... It mostly works anyway. It works fine so long as I don't redirect the stdio for the program to a tcp-ip address using socat. Then it gives me a "Not a Typewriter" error which is what I guess happens when it attempts to control something that isn't a tty. That sounds like a different question though, so I'll have to leave it here and start again I guess.
Thanks folks!
Here's a quick sample of how to do console input (and can easily be adapted to do input from another input source, such as a serial port).
Note that it's hard to "type fast enough" for this to read more than one character at a time, but if you copy'n'paste, it will indeed read 256 characters at once, so assuming your machine that you are connecting to is indeed feeding out a large amount of stuff, it should work just fine to read large-ish chunks - I tested it by marking a region in one window, and middle-button-clicking in the window running this code.
I have added SOME comments, but for FULL details, you need to do man tcsetattr - there are a whole lot of settings that may or may not help you. This is configured to read data of "any" kind, and exit if you hit escape (it also exits if you hit an arrow-key or similar, because those translate to an ESC-something sequence, and thus will trigger the "exit" functionality. It's a good idea to not crash out of, or set up some handler to restore the terminal behaviour, as if you do accidentally exit before you've restored to original setting, the console will act a tad weird.
#include <termios.h>
#include <unistd.h>
#include <cassert>
#include <iostream>
const int STDIN_HANDLE = 0;
int main()
{
termios tios, original;
int status;
status = tcgetattr(STDIN_HANDLE, &tios);
assert(status >= 0);
original = tios;
// Set some input flags
tios.c_iflag &= ~IXOFF; // Turn off XON/XOFF...
tios.c_iflag &= ~INLCR; // Don't translate NL to CR.
// Set some output flags
// tios.c_oflag = ... // not needed, I think.
// Local modes flags.
tios.c_lflag &= ~ISIG; // Don't signal on CTRL-C, CTRL-Z, etc.
tios.c_lflag &= ~ICANON; // Don't read a whole line at a time.
tios.c_lflag &= ~(ECHO | ECHOE | ECHOK); // Don't show the input.
// Set some other parameters
tios.c_cc[VTIME] = 5; // 0.5 second timeout.
tios.c_cc[VMIN] = 0; // Read single character at a time.
status = tcsetattr(STDIN_HANDLE, TCSANOW, &tios);
assert(status >= 0);
char buffer[256];
int tocount = 0;
for(;;)
{
int count = read(STDIN_HANDLE, buffer, sizeof(buffer));
if (count < 0)
{
std::cout << "Error..." << std::endl;
break;
}
if (count == 0)
{
// No input for VTIME * 0.1s.
tocount++;
if (tocount > 5)
{
std::cout << "Hmmm. No input for a bit..." << std::endl;
tocount = 0;
}
}
else
{
tocount = 0;
if (buffer[0]== 27) // Escape
{
break;
}
for(int i = 0; i < count; i++)
{
std::cout << std::hex << (unsigned)buffer[i] << " ";
if (!(i % 16))
{
std::cout << std::endl;
}
}
std::cout << std::endl;
}
}
status = tcsetattr(STDIN_HANDLE, TCSANOW, &original);
return 0;
}
If your instrumentation offers a stream interface, and assuming that it would wait before returning whenever no input is available, I'd suggest to simply use :
cin.ignore(numeric_limits<streamsize>::max(),'\r'); // ignore everything until '\r'
Another alternative could be to use poll, which provides a mechanism for multiplexing (and waiting for) input/output over a set of file descriptors. This has the advantage of letting you read several instrumentation devices if you'd need.

clearing user input buffer in c / c++

I'd like to clear input buffer, but do not know how, heres the code please try for yourself:
#include <windows.h>
using namespace std;
int main()
{
do {
Sleep(500);
if (kbhit())
cout << (char) getch() << endl;
} while(1);
}
If I spam-press keyboard, letters would print one by one, each delayed by 500ms.
How do I clear whole input buffer and only one letter will appear even if I press multiple
So you are writing a Windows console app. Not DOS and not cross-platform compatible.
You could use the Windows Console functions. See http://msdn.microsoft.com/en-us/library/windows/desktop/ms682073%28v=vs.85%29.aspx
In particular you can get the handle with GetStdHandle, then WaitForSingleObject on the handle. Probably with a 500 ms timeout instead of your current Sleep.
Then you should be able to ReadConsole to read all of the input that has been buffered since the last time you read it. If you want the first character or the last character you would just take that one.
There are a lot of details you'd need to add in to all that to make it actually work.
This kind of depends on how exactly you want the behaviour to be. Since you haven't specified it in detail, here are two that I'll offer:
// ...
do {
Sleep( 500 );
if ( kbhit( ) ) {
cout << (char) getch( ) << endl;
while ( kbhit( ) )
getch( );
}
} while ( 1 );
// ...
The addition of the while loop inside there, clears the remaining keystrokes inside the buffer. It does that by checking for the condition if there is a remaining keystroke, in which case discarding it.
While this seems to be what you want from the way you've asked, I would like to suggest the following, which would feel much smoother in my opinion:
// ...
do {
cout << (char) getch( ) << endl;
Sleep( 500 );
while ( kbhit( ) )
getch( );
} while ( 1 );
// ...
The way it gets smoother won't get much recognized with a delay like 500, but raise it to 2500 and you may understand what I mean. On the first version, your keystrokes will appear delayed by 0 ~ 500/2500 milliseconds all the time; while on the second version, your keystrokes will appear immediately if they are to appear (i.e. were pressed out of the cooldown).