I'm wondering how to accept keyboard and mouse input in C++, using Visual Studio 2010, for Windows 7 32-bit.
--EDIT: I forgot to mention that I need keyboard / mouse input without interrupting the flow of the program. Something like a listener. I don't want to have to pause the program and ask for input, and then have the user type it out and press enter. What I'm looking for is more like:
If user presses W, S, A, D -> something happens.
Or: If user presses leftmousebutton in -> something happens.
I have to mention that I'm still very new to programming as a whole. I know basic OOP programming but that's about it. I'm definitely sure that this will involve things I don't know about yet, and I don't mind, I just ask that you explain it thoroughly, and possibly give an example so I know how to use it.
Thanks.
keyboard / mouse input without interrupting the flow
#include <windows.h>
#include <iostream>
using namespace std;
int main()
{
HANDLE hIn;
HANDLE hOut;
COORD KeyWhere;
COORD MouseWhere;
COORD EndWhere;
bool Continue = TRUE;
int KeyEvents = 0;
int MouseEvents = 0;
INPUT_RECORD InRec;
DWORD NumRead;
hIn = GetStdHandle(STD_INPUT_HANDLE);
hOut = GetStdHandle(STD_OUTPUT_HANDLE);
cout << "Key Events : " << endl;
cout << "Mouse Events : " << flush;
KeyWhere.X = 15;
KeyWhere.Y = 0;
MouseWhere.X = 15;
MouseWhere.Y = 1;
EndWhere.X = 0;
EndWhere.Y = 3;
while (Continue)
{
ReadConsoleInput(hIn,
&InRec,
1,
&NumRead);
switch (InRec.EventType)
{
case KEY_EVENT:
++KeyEvents;
SetConsoleCursorPosition(hOut,
KeyWhere);
cout << KeyEvents << flush;
if (InRec.Event.KeyEvent.uChar.AsciiChar == 'x')
{
SetConsoleCursorPosition(hOut,
EndWhere);
cout << "Exiting..." << endl;
Continue = FALSE;
}
break;
case MOUSE_EVENT:
++MouseEvents;
SetConsoleCursorPosition(hOut,
MouseWhere);
cout << MouseEvents << flush;
break;
}
}
return 0;
}
There are a number of related concepts behind this.
At the very low level, the keyboard and the mouse are hardware devices that generates some "interrupts" (in the form of electric signals) to the CPU.
The operating system provides some drivers that handle such interrupts by decoding the device communication specific protocol, and "standardizing" (at OS level) those signals in the form of events.
With "console applications", the operating system handles those events (the keyboard in particular) by filling up an input buffer (essentially a char[]) that is made accessible as a "virtually infinite sequence of characters" (complicated name for "file") named "CON", thus mimicking the "infinite teletype model" of the early days computers.
In a C++ program, the standard library -at program startup- associates to that "file" the std::cin and std::cout stream objects, so you can read the input character sequence using the std::istream functions and operators.
With "graphical applications", unfortunately, there is no "early days model" to mimic, and "events" are left available as the operating system native structure.
Different operating system differs in the way such events are represented and handled, but certain similitude can be seen.
For Windows (since your question is about), a typical program retrieves those events in sequence with a "message loop" in which calling certain OS APIs.
In that loop, the typical program will also give call another OS API to dispatch those event to appropriate "call-back" procedure, associated to a previously created "window".
That callback procedure has to detect the event code, cast the parameter as appropriate and manage them doing the action required.
A more precise detail can be seen with a WIN32 programming tutorial like http://www.winprog.org/tutorial/.
The most of the code is essentially C, since C is the language the API are formalized.
For C++, a number of libraries have then been written to represent OS objects is the form of C++ classes, and mapping the OS APIs to those classes members.
These libraries can be either OS specific (like MFC, WTL ...) or "multi-platform" (they exist in different version, mapping the API of various OSs into a same C++ interface) like WxWidget, Qt, Gtk, Fltk ...
Hope this can give you more hints to think about.
If you're writing a console application, you can use scanf or cin to get keyboard input. Console applications don't have any support for the mouse.
If you're writing a GUI application, you'll build the app out of standard windows controls that have built-in behaviors for mouse and keyboard input. You can use these re-usable controls as is, or you can augment them to make them behave exactly how you want for your application.
For example, in a GUI application, there's a standard edit control you can use that the user can type into. Your program receives messages when the user enters text into it, and based on those messages, or on other events, you can retrieve the text and do things with it as required by your program.
Windows or Console?
If console, use:
std::cin >> myVar;
Related
I have transcribed a c++ console app to GUI using wxWidgets. Most of my functions were written for the commandline flow. I am creating handles and additional code to interface GUI with the functions. I have emulated a console for output stream, which works good (using wxStreamToTextRedirector). However, I can't find a simple solution to take user input from a textcontrol and substitute the std::cin command in cases like the code below. Event handlers and GUI controls for my frame are in MainFrame.cpp and object data and functions in another Data.cpp
I have a function in Data.cpp which will be called on a button press event from MainFrame.cpp:
bool Data::run_yn_prompt()
{ //Run Y or N input prompt
do {
std::string input = "";
std::cout << "\n Input Y/y to proceed, N/n to cancel:"; **//OUTPUT TO DISPLAY CONSOLE**
std::getline(std::cin, input); **//Need to fetch wxTextCtrl input at this point only**
std::cout << input;
if ( (input=="Y") || (input=="y") ) return true;
if ( (input=="N") || (input=="n") ) return false;
} while(1==1);
}
The problem is I need the input to be fetched only after:
the previous std::cout is run and
the user enters the input and presses ENTER (to be signaled by wxEVT_TEXT_ENTER event handler)
The only way I guess I could do it is by adding a lot of conditionals and boolean flags to watch for user input and enter press. Is there any simple strategy to make this work? My goal is not to publish this app, but learn to get wxWidgets elements to work as per my need. I have so many std::cin in the middle of my code like this. This problem has stopped me from moving forward with wxWidgets. And I would like to keep everything in a single frame without additional dialogs.
The only way to preserve the code using std::cin in a GUI program is to use modal dialogs for text entry (e.g. wxGetTextFromUser()) instead. This is not going to be nearly as convenient for the user as using a text control inside the main program window, but it's the only way to preserve the existing control flow.
original code
#include<iostream>
#include<fstream>
using namespace std;
int main()
{
ofstream arduino_output("/dev/ttyACM0");
ifstream arduino_input("/dev/ttyACM0");
int value;
string txt;
while(cin >> value){
arduino_output << value << endl;
arduino_input >> txt;//I never recieve the "OK" (Which I should get)
cout << txt;
}
arduino_input.close();
arduino_output.close();
return(0);
}
Here is the problem:
cin >> value;
arduino_output << value << endl;
arduino_input >> txt;//I never recieve the "OK" (Which I should get)
cout << txt;
but if I do this instead it works:
cin >> value;
arduino_output << value << endl;
for(int i=0;i<10000;++i)
for(int j=0;j<10000;++j){ //Waste a lot of time
++value;
--value;
}
arduino_input >> txt; //I always recieve the "OK"
cout << txt; //I can see the "OK"
So how do I make my fast computer able to read the slow output from the arduino? (Without using for-loops to waste time)
Here it says some things about callback http://www.cplusplus.com/reference/ios/ios_base/register_callback/ but I could never get it to work. It says it supports 3 events, and none of them are: "If input buffer is not empty, call this function".
Because the ultimate solution would be a callback function for whenever the input buffer is not empty.
An acceptable solution would be a c++ equivalent version of the arduino version "Serial.available()".
Another acceptable solution would be anything that forces me to not rely on two for-loops. 3 for-loops is not acceptable if that's what you're thinking.
EDIT1: Showed the original code
EDIT2: I am using linux(lubuntu)
EDIT3: Someone got confused where the code was written. Strange.
If your arduino board is connected -e.g. by some cable- to a Linux laptop and your C++
program is on the Linux side (so not running on the Arduino microcontroller, which you did program in free-standing C), you'll better use directly syscalls(2) and low-level IO (not C++ ifstream which adds some buffering) such as open(2) & read(2) & write(2) & close(2).
Read Advanced Linux Programming. Consider using termios(3) to perhaps set your tty (demystified here) in raw mode. Use poll(2) to multiplex (and wait for) input (or ability to output), e.g. like Serial.available() does inside the Arduino.
Some event loop libraries (e.g. libevent or libev) provide callbacks, but you can make your own event loop around poll.
To make some delay, use perhaps usleep(3) (but very probably, you need to poll instead).
PS. If your Linux application is a graphical one using some GUI toolkit like Qt or GTK, you should use the event loop provided by that toolkit (that loop is calling poll or select, etc...). BTW, your question is not really Arduino related, but serial port related (any other device plugged on the same serial port would give the same issues).
Your problem is weird. In general, the problem is that the slower party can't read what the faster party sends. So, it seems you have a more fundamental problem here.
If arduino_output is a representation of a serial port (UART), I suggest to use a platform specific way of accessing it. On Windows, there are UART functions, and on Linux there's termios (probably on most other POSIX-like, too). This will give you a way to control the parameters of communication, and get information and/or notification about events (including parity/framing errors).
First, to clarify, I am not asking how to drag-and-drop a file onto an exe's icon. I want to know how to handle drag and drop onto an already running win32 console application. I'm also not asking how to handle drag and drop inside of WinMain based applications through the Windows message pump. I want to do this inside of a program with the entry point int main() that doesn't have a WndProc (yet) or anything.
That said, I'm wondering if my goal is achievable (and hoping that it is).
I have a server application that is running within a console window. Due to a large codebase and a lot of weird coupling, it is an 'output only' console for all intensive purposes. Within it though, I can still handle things like key presses, as I have an update loop ticking. I'd like to be able to drag and drop files full of commands (which use a custom syntax) onto my running application and have it process them.
Is this possible to do? I was thinking that potentially I could get a pointer to the HWND of the console (which hopefully is a thing?), and then maybe subclass that window to use a custom WndProc to listen for the WM_DROPFILES message.
I've never really tried to set up handling of windows messages in an int main() program instead of a WinMain program, but I'm hoping it's somehow possible.
Any help would be greatly appreciated!
Weird solutions are fine.
AFAIK, a console window does not support drag&drop by default. You can always create your own separate popup window with its own message loop so the user has something to drag items onto.
To use drag&drop on the console window itself, try using GetConsoleWindow() to get the console HWND, then either:
subclass the HWND using SetWindowLong/Ptr() or SetWindowSubClass(), then register the HWND using DragAcceptFiles() to start receiving WM_DROPFILES messages. Be sure to call DragAcceptFiles() again to stop receiving the messages and then unhook your subclass before exiting the app.
implement the IDropTarget interface and then register the HWND using RegisterDragDrop() to start receiving notifications. Be sure to call RevokeDragDrop() before exiting the app.
WM_DROPFILES is easier to code for, but IDropTarget is more flexible as it handles virtual items as well as physical files.
#include <vector>
#include <string>
#include <iostream>
#include <conio.h>
int main()
{
std::cout << "Please drop files and press [Enter] when done ...\n";
std::vector< std::string > files;
for( int ch = _getch(); ch != '\r'; ch = _getch() ) {
std::string file_name;
if( ch == '\"' ) { // path containing spaces. read til next '"' ...
while( ( ch = _getch() ) != '\"' )
file_name += ch;
} else { // path not containing spaces. read as long as chars are coming rapidly.
file_name += ch;
while( _kbhit() )
file_name += _getch();
}
files.push_back( file_name );
}
std::cout << "You dropped these files:\n";
for( auto & i : files )
std::cout << i << '\n';
}
I am currently experimenting with xdotool to send keys to a process (I understand that it may not work for all processes that does not set _NET_WM_PID). I have trouble sending keystrokes to windows other from the focus. It does work if you are sending keystrokes to the CURRENTWINDOW. Below is the snippet that I used to test xdotool's functionality.
extern "C"{
#include <xdo.h>
}
//extern "C" xdo_window_search
#include <iostream>
#include <string.h>
using namespace std;
int main(){
xdo_t* p_xdo = xdo_new(NULL);
// Allocate memory for search query.
xdo_search_t s;
// Clear the allocated memory.
memset(&s, 0, sizeof(xdo_search_t));
// Set the search query.
s.pid = 1916;
s.max_depth = -1;
s.searchmask = SEARCH_PID;
s.require = xdo_search::SEARCH_ANY;
// Allocate memory for output
Window* windows;
int no_windows;
xdo_window_search(p_xdo,&s,&windows,&no_windows);
cout << no_windows << endl;
// Prints all windows' names with matching criteria
for( int i=0;i<no_windows;i++ ){
unsigned char * name;
int size;
int type;
xdo_get_window_name(p_xdo,windows[i],&name,&size,&type);
cout << i << ":" << name << endl;
}
for( int i=0;i<no_windows;i++ ){
xdo_type(p_xdo,windows[i],"Hello World",0);
}
//xdo_type(p_xdo,CURRENTWINDOW,"Hello World",0); // This does work.
return 0;
}
In additional to testing xdotool's functionality, I've looked into xdotool's source code. Interestingly, I found that they are using Xtest to send keystrokes to the focused window (CURRENTWINDOW) and X11's XSendEvent for other windows. I turned to xdotool because I couldn't get XSendEvent to work and Xtest cannot send keys to any other windows than the focused window.
Am I not using the xdotool correctly? Does xdotool not work with all *nix OS with X11?
[I am running this on Ubuntu 13.04.]
EDIT
So, it looks like that does work but not for all windows that it finds. For example, it works for firefox but not gedit and gnome-terminal although it found gedit and gnome-terminal by its pid. It behaves differently if I used CURRENTWINDOW.
So, it would be great if someone can explain why is this so. Like, is it related the force send flag in an XEvent?
Directly from the xdotool manual:
SENDEVENT NOTES
If you are trying to send key input to a specific window, and it does
not appear to be working, then it's likely your application is ignoring
the events xdotool is generating. This is fairly common.
Sending keystrokes to a specific window uses a different API than
simply typing to the active window. If you specify 'xdotool type
--window 12345 hello' xdotool will generate key events and send them
directly to window 12345. However, X11 servers will set a special flag
on all events generated in this way (see XEvent.xany.send_event in
X11's manual). Many programs observe this flag and reject these events.
It is important to note that for key and mouse events, we only use
XSendEvent when a specific window is targeted. Otherwise, we use XTEST.
Some programs can be configured to accept events even if they are
generated by xdotool. Seek the documentation of your application for
help.
Specific application notes (from the author's testing): * Firefox 3
seems to ignore all input when it does not have focus. * xterm can be
configured while running with ctrl+leftclick, 'Allow SendEvents' *
gnome-terminal appears to accept generated input by default.
I am writing a small program to let me switch my resolution back and forth because my projector cannot handle the same resolution as my screen. I already know how to set the screen resolution using the windows API. As well as read the current resolution using the windows API or the QT4 toolkit. My problem is I want a menu of all of the different resolutions supported by the screen and graphics card. This program will be distributed so I need the program to actually communicate to the graphics card to find out what it supports. The only API I want to use is the windows API, or the QT4 toolkit, but I don't think QT4 does that unless you are using the graphics widgets in odd ways.
I am pretty sure this is possible with the WINDOWS API. I just don't know how to do it.
Oh and please cut me some slack, I am familiar with QT4 and C++ but I am typically a Linux programmer, I am writing this for someone else. The only thing I have ever done with the windows API is make a message box, set the background, and used system variables. So please explain the process simply. Please don't just post a link to the msdn, I hate their documentation, and I hate Microsoft. I use windows maybe twice a year.
The following should probably work for you in the general case
DEVMODE dm = { 0 };
dm.dmSize = sizeof(dm);
for( int iModeNum = 0; EnumDisplaySettings( NULL, iModeNum, &dm ) != 0; iModeNum++ ) {
cout << "Mode #" << iModeNum << " = " << dm.dmPelsWidth << "x" << dm.dmPelsHeight << endl;
}
This should print out all the supported resolutions on the current display that the .exe is running on. Assuming you're not dealing with a multi-display graphics card this should work. Otherwise you'd have to use EnumDisplayDevices loop over each display.
Once you figure out what resolution you want you can use 'ChangeDisplaySettingsEx' to change the display to the mode you want.
Using DirectX is possible but I wouldn't recommend it as the code is alot more complicated (having to initialize DirectX and using COM pointers) unless you plan to actually use DirectX for more than just determining display resolutions.
EnumDisplaySettings :)
From MSDN:
"To obtain the current display settings, pass the ENUM_CURRENT_SETTINGS constant in the iModeNum parameter to the EnumDisplaySettings API, as illustrated by the following C++ code."
DEVMODE dm;
// initialize the DEVMODE structure
ZeroMemory(&dm, sizeof(dm));
dm.dmSize = sizeof(dm);
if (0 != EnumDisplaySettings(NULL, ENUM_CURRENT_SETTINGS, &dm))
{
// inspect the DEVMODE structure to obtain details
// about the display settings such as
// - Orientation
// - Width and Height
// - Frequency
// - etc.
}