0

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.

Ron
  • 14,674
  • 4
  • 34
  • 47
luke
  • 29
  • 6
  • I have left an update to this in the answers section, editing my post doesn't seem to work. – luke Oct 14 '17 at 09:33
  • you should put updates in the question, not as an answer. The answer box is for answers. – M.M Oct 14 '17 at 09:36
  • Maybe it's just your system's way of telling you, that it's time to read the documentation for [SendInput](https://msdn.microsoft.com/en-us/library/windows/desktop/ms646310.aspx). Passing `1` as the first argument would be a bug already. Passing `true`, on the other hand, requires actively refusing to comprehend the documentation. And then you have undefined behavior due to using uninitialized variables. Start [here](https://stackoverflow.com/q/388242/1889329). – IInspectable Oct 14 '17 at 10:26
  • 1
    @IInspectable Passing `1` would be correct according to that documentation, and `true` is equivalent because there is implicit conversion from bool to int, with true mapping to 1 – M.M Oct 14 '17 at 11:25
  • @M.M: The API call is *technically* correct, even if it fails to properly convey the intent. There's still a bug in the code, and `SendInput` was invented to allow developers to address a bug pertinent to using [mouse_event](https://msdn.microsoft.com/en-us/library/windows/desktop/ms646260.aspx). Passing `1` in this case uses the correct API in a way that allows it to miss out on the bugfix it implements. The documentation for [SendInput](https://msdn.microsoft.com/en-us/library/windows/desktop/ms646310.aspx) explains that. You'll have to read all of it, though. – IInspectable Oct 14 '17 at 11:44
  • 1
    @IInspectable I read the whole page and don't see the bug you are talking about. Apparently OP doesn't either. Perhaps you could try being helpful instead of arrogant with your comments; or write an answer that covers the topic? – M.M Oct 14 '17 at 11:56
  • @M.M: [SendInput](https://msdn.microsoft.com/en-us/library/windows/desktop/ms646310.aspx): *"The SendInput function inserts the events in the INPUT structures serially into the keyboard or mouse input stream. **These events are not interspersed with other keyboard or mouse input events** inserted either by the user (with the keyboard or mouse) or by calls to keybd_event, mouse_event, or other calls to SendInput."* That is indeed the whole point for `SendInput`. Otherwise `mouse_event` would be just as effective. – IInspectable Oct 14 '17 at 11:58
  • Can you explain what part of that quote says sending 1 event is bugged but 2 events is not? – M.M Oct 14 '17 at 11:59
  • @M.M: I'm going to have to leave that as an exercise to yourself to envision a scenario, where repeatedly inserting *individual* input events has different observable behavior from injecting input in a single batch operation. You might also want to consider, why databases commonly implement transactions. Besides, I never claimed that passing `1` were unconditionally wrong. It just happens to be wrong *in this example*. – IInspectable Oct 14 '17 at 12:02
  • @IInspectable I don't doubt that inserting 2 single events might have different behaviour from inserting 2 events atomically, but how does that lead to OP's situation? Also, you originally claimed "Passing 1 as the first argument would be a bug already"; but now you seem to have changed your tune to say that the bug only arises from doing that twice ? Changing `true` to any value greater than `1` in OP's code (without making any other changes) would still be bugged – M.M Oct 14 '17 at 12:10
  • @M.M: You have been a member of this site long enough to know the rules. An answer should try to address the issue. A comment doesn't necessarily have to. My comment didn't try to explain, how *that* particular bug causes the behavior the OP observed, because I do not think it does, nor have I communicated any such relation. At any rate, if you need a better tool to right the wrong, I'm going to jot up a Q&A about this issue. Feel free to down-vote for whatever reason, or without any reason at all. – IInspectable Oct 14 '17 at 12:15
  • It seems to me you were trying to answer in comments in the first place (and one of the reason the site has rules that answers should not go in comments, is that if someone needs clarification about the answer, then the place for that is in comments under that answer, instead of comment chains like this) – M.M Oct 14 '17 at 12:18
  • @M.M: I cannot answer a question to a problem I cannot reproduce. As it stands, it is still unclear, whether or not the [accepted answer](https://stackoverflow.com/a/46742701/1889329) does indeed address the issue. Since I have no more insight into the problem than you do, what particular reason would there be for me to submit an answer? A comment is the right place to point out issues, that are not known to be a solution to a problem. If indeed it does solve the issue, the OP can either post an answer themselves, or report back so that someone else can. – IInspectable Oct 14 '17 at 13:27
  • Related: [Is it a bug to pass 1 as the first argument to SendInput?](https://stackoverflow.com/q/46744894/1889329) – IInspectable Oct 14 '17 at 14:45

2 Answers2

-1

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));
Ron
  • 14,674
  • 4
  • 34
  • 47
  • Hey, thanks for the reply. I've tried it with my cursor being on Visual Studio, and Google Chrome. – luke Oct 14 '17 at 09:03
  • *"Nothing in your code suggests the cause of such behavior unless you are invoking undefined behaviour."* - The code clearly illustrates undefined behavior. `INPUT Input;` certainly doesn't initialize the variable. Using that (which the code does) triggers undefined behavior. – IInspectable Oct 14 '17 at 10:30
  • @luke did making the change suggested in this answer actually fix your problem? – M.M Oct 14 '17 at 12:13
-1

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;
user7860670
  • 35,849
  • 4
  • 58
  • 84
  • Thanks for the info, but it doesn't seem to have fixed it. – luke Oct 14 '17 at 09:27
  • 5
    Start with `INPUT Input = {};` instead . As opposed to your approach, this guarantees all fields are actually zeroed – M.M Oct 14 '17 at 09:33