C++ execution causes monitor to disconnect - c++

the issue I'm having is that upon executing this code, it clicks, and then my monitor turns blue and says "HDMI no cable connected", and either returns back to normal after 1 second, or stays on that screen until I perform an action (click, alt etc).
Anybody with any idea on why this is happening would be appreciated.
#include "stdafx.h"
#include <Windows.h>
using namespace std;
void function() {
INPUT Input;
Input.type = INPUT_MOUSE;
Input.mi.dwFlags = MOUSEEVENTF_LEFTDOWN;
SendInput(true, &Input, sizeof(Input));
Input.mi.dwFlags = MOUSEEVENTF_LEFTUP;
SendInput(true, &Input, sizeof(Input));
};
int main()
{
Sleep(3000);
function();
return 0;
}
Also, I'm using Visual Studio 2017 Community. This problem occurs when debugging the code, and when running the executable. There are no errors or warnings with my code.

You are not initializing the INPUT structure properly thus (probably) invoking undefined behavior. Initialize the structure fields to zeros using:
INPUT Input = {};
You can also go with an array of two elements:
INPUT Input[2] = {0};
followed by a:
Input[0].type = INPUT_MOUSE;
Input[0].mi.dwFlags = MOUSEEVENTF_LEFTDOWN;
Input[1].type = INPUT_MOUSE;
Input[1].mi.dwFlags = MOUSEEVENTF_LEFTUP;
and one call to SendInput:
SendInput(2, Input, sizeof(INPUT));

You are not initializing most of INPUT fields sending some garbage and potentially triggering Undefined Behavior. You should at least fill them with zeros:
Input.type = INPUT_MOUSE;
Input.mi.dx = 0;
Input.mi.dy = 0;
Input.mi.mouseData = 0;
Input.mi.dwFlags = MOUSEEVENTF_LEFTDOWN;
Input.mi.time = 0;
Input.mi.dwExtraInfo = 0;

Related

SendInput Coordinates Confusion

I am trying to understand how SendInput() works with mouse input. As an example, I have a dual monitor display. My 2160p monitor is "above" the 1440p primary monitor. I am trying to send mouse input to the bottom right corner of the above 2160 monitor. Unfortunately, the cursor just ends up in the bottom right corner of my 1440p primary monitor instead.
I know that the top left corner of my primary monitor is (0,0), and the bottom right is (2560,1440). From what I understand, all coordinates are in relation to the primary monitor. So shouldn't I just be able to subtract the resolution of the above monitor from the primary one to move to the exact same location on the above?
I have tried both adding and subtracting, but I keep ending up in the bottom corner of the primary monitor.
INPUT input;
input.type = INPUT_MOUSE;
input.mi.dx = (2560 - 3840) * (65536.f / (float)GetSystemMetrics(SM_CXSCREEN));
input.mi.dy = (1440 - 2160) * (65536.f / (float)GetSystemMetrics(SM_CYSCREEN));
input.mi.dwFlags = MOUSEEVENTF_ABSOLUTE | MOUSEEVENTF_MOVE;
input.mi.mouseData = 0;
input.mi.dwExtraInfo = NULL;
input.mi.time = 0;
SendInput(1, &input, sizeof(INPUT));
UPDATE: Here is one of my failed attempts using the RECT structure from GetMonitorInfo. I am probably making some sort of obvious mistake, but I can't figure it out.
DXGI_OUTPUT_DESC output_desc;
output->GetDesc(&output_desc);
MONITORINFOEX info;
info.cbSize = sizeof(info);
GetMonitorInfo(output_desc.Monitor, (LPMONITORINFO)&info);
INPUT input;
input.type = INPUT_MOUSE;
input.mi.dx = (info.rcMonitor.right) * (65536.f / (float)GetSystemMetrics(SM_CXVIRTUALSCREEN));
input.mi.dy = (info.rcMonitor.top) * (65536.f / (float)GetSystemMetrics(SM_CYVIRTUALSCREEN));
input.mi.dwFlags = MOUSEEVENTF_ABSOLUTE | MOUSEEVENTF_VIRTUALDESK| MOUSEEVENTF_MOVE;
input.mi.mouseData = 0;
input.mi.dwExtraInfo = NULL;
input.mi.time = 0;
SendInput(1, &input, sizeof(INPUT));

Failing to simulate mouse click via Windows API

I was dabbling with positioning of the mouse pointer which I had no trouble at all with, but trying to simulate a left click is giving me problems at the moment.
#include <Windows.h>
int main()
{
SetCursorPos(100, 450);
Sleep(3000);
SetCursorPos(1600, 450);
int n = 1;
while (n <= 10);
{
SetCursorPos(1600, 450);
LeftClick();
n++;
}
}
My LeftClick() function is as follows:
void LeftClick()
//down
INPUT Input = {0};
Input.type = INPUT_MOUSE;
Input.mi.dwFlags = MOUSEEVENTF_LEFTDOWN;
::SendInput(1, &Input, sizeof(INPUT));
//up
::ZeroMemory(&Input, sizeof(INPUT));
Input.type = INPUT_MOUSE;
Input.mi.dwFlags = MOUSEEVENTF_LEFTUP;
::SendInput(1, &Input, sizeof(INPUT));
I've looked around and so far everything I've seen hasn't worked for me.
Please give me any help with anything to do with my sloppy code, not just how I am trying to simulate clicking,

Loop repeated do statement with mouse left button variable click & hold

Hey, currently testing a autoclicker for a few games, I am quite new to C++
How can I use left mouse button to run a do statement for the mouse click function without it stopping the do statement
I've tried different flags including :
input.mi.dwFlags = (MOUSEEVENTF_ABSOLUTE | MOUSEEVENTF_MOVE | MOUSEEVENTF_LEFTDOWN | MOUSEEVENTF_LEFTUP);
with mouse_event(MOUSEEVENTF)
do {
if (GetAsyncKeyState(VK_LBUTTON) & 0x80000000) {
enabled = true;
while (GetAsyncKeyState(VK_LBUTTON) & 0x80000000) {
Sleep(1000 / cps);
INPUT input;
input.type = INPUT_MOUSE;
input.mi.dx = 0;
input.mi.dy = 0;
input.mi.dwFlags = (MOUSEEVENTF_ABSOLUTE | MOUSEEVENTF_MOVE | MOUSEEVENTF_LEFTDOWN | MOUSEEVENTF_LEFTUP);
input.mi.mouseData = 0;
input.mi.dwExtraInfo = NULL;
input.mi.time = 0;
SendInput(1, &input, sizeof(INPUT));
}
}
} while (true);
I am trying to make it so when you hold down left click, it runs the while statement containing the autoclicking function, without stopping the while statement due to repetitive clicking.
There is something you should notice in your code:
First, How to judge the return value of GetAsyncKeyState()
If the function succeeds, the return value specifies whether the key
was pressed since the last call to GetAsyncKeyState, and whether the
key is currently up or down. If the most significant bit is set, the
key is down, and if the least significant bit is set, the key was
pressed after the previous call to GetAsyncKeyState. However, you
should not rely on this last behavior; for more information, see the
Remarks.
the type of return value is SHORT which is 2 bytes. So try GetAsyncKeyState(VK_LBUTTON) & 0x8000 instead.
Second, How to use SendInput() to send different mouse state.
You should create a new INPUT data to save different action, but not just combine all of them.
Code Sample:
do {
if (GetAsyncKeyState(VK_LBUTTON) & 0x8000)
{
enabled = true;
while (GetAsyncKeyState(VK_LBUTTON) & 0x8000)
{
INPUT input[2];
input[0].type = input[1].type = INPUT_MOUSE;
input[0].mi.dx = 0;
input[0].mi.dy = 0;
input[0].mi.dwFlags = MOUSEEVENTF_ABSOLUTE | MOUSEEVENTF_LEFTDOWN;
input[1].mi.dx = 0;
input[1].mi.dy = 0;
input[1].mi.dwFlags = MOUSEEVENTF_ABSOLUTE | MOUSEEVENTF_LEFTUP;
SendInput(2, input, sizeof(INPUT) * 2);
}
}
} while (true);

How to print/press '#' using keybd_event function?

To press 'a' code is
keybd_event(VkKeyScan(64),0,0,0);
Releasing key code is
keybd_event(VkKeyScan(64),0,KEYEVENTF_KEYUP,0);
For pressing '#' i need combination of two key - SHIFT & 2 , but i don't know how.
keybd_event (https://msdn.microsoft.com/en-us/library/windows/desktop/ms646304(v=vs.85).aspx)
Try the following:
Press Shift
Press 2
Release 2
Release Shift
Addendum
I just checked my own code where I did the same thing... keybd_event is deprecated (as stated on the site you linked), you should use SendInput instead.
This are my two functions to send the key press and release:
void sendKeyDown(unsigned char keyCode)
{
INPUT input;
input.type = INPUT_KEYBOARD;
input.ki.wVk = keyCode;
input.ki.dwFlags = 0;
input.ki.time = 0;
input.ki.dwExtraInfo = 0;
SendInput(1, &input, sizeof(INPUT));
}
void sendKeyUp(unsigned char keyCode)
{
INPUT input;
input.type = INPUT_KEYBOARD;
input.ki.wVk = keyCode;
input.ki.dwFlags = KEYEVENTF_KEYUP;
input.ki.time = 0;
input.ki.dwExtraInfo = 0;
SendInput(1, &input, sizeof(INPUT));
}
And this should then give you an #:
sendKeyDown(VK_SHIFT);
sendKeyDown(0x32);
sendKeyUp(0x32);
sendKeyUp(VK_SHIFT);
Please check the 0x32, I can't reliably test it at the moment to be the key 2.

Breaking down a string and using keybd to send characters

I have searched the internet for a good system for emulating keypresses in C++.
I want to send a string to another program but as far as I can see the GenerateKey function can only send one at a time. I created code to break a string down and send each letter individually but sometimes the number of a specific letter in the alphabet is sent instead of the letter itself. (e.g. I enter "h" the computer spits out "8")
How can I fix this and is there a better way to do it? Thank you!
#include <windows.h>
#include<iostream>
#include <winable.h>
#include <fstream>
#include<time.h>
#include<string>
using namespace std;
void GenerateKey(int vk, BOOL bExtended) {
KEYBDINPUT kb = {0};
INPUT Input = {0};
/* Generate a "key down" */
if (bExtended) { kb.dwFlags = KEYEVENTF_EXTENDEDKEY; }
kb.wVk = vk;
Input.type = INPUT_KEYBOARD;
Input.ki = kb;
SendInput(1, &Input, sizeof(Input));
/* Generate a "key up" */
ZeroMemory(&kb, sizeof(KEYBDINPUT));
ZeroMemory(&Input, sizeof(INPUT));
kb.dwFlags = KEYEVENTF_KEYUP;
if (bExtended) { kb.dwFlags |= KEYEVENTF_EXTENDEDKEY; }
kb.wVk = vk;
Input.type = INPUT_KEYBOARD;
Input.ki = kb;
SendInput(1, &Input, sizeof(Input));
return;
}
int main() {
SetConsoleTitle( "sendkeys" );
string sentence;
while (1){
cin>>sentence;
char letter;
int track = 0;
while(sentence[track] != '\0') {
cout<<sentence[track];
letter = sentence[track];
GenerateKey(letter, FALSE);
track++;
}
}
}
This sort of approach is really complicated (you have to manage state of SHIFT, CONTROL, and ALT, convert special characters to ALT+0xyz combos) and if the user changes keyboard focus in the process, keys can go to the wrong window.
Using SendMessage(WM_SETTEXT) or SendMessage(EM_REPLACESEL) you could send a whole string at once to a particular window.
I'm not totally familiar with some of the API you're using, but I'm going to assume you're trying to send text to the stdin of some other process?
If it's a child process (i.e. one your process launched itself), you can use pipes and redirected I/O as explained in this article.