Mouse and console

I've got this code for mouse clicking, getting x,y...
now when I put this in:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
for(;;)
{
if(_kbhit())
{
//do something
}
else if(MouseClick())
{
//do something else
}
}
//...
bool MouseClick()
{
	GetNumberOfConsoleInputEvents(rHnd, &num_events);
	if(num_events!=0)
	{
		INPUT_RECORD *eventBuffer = new INPUT_RECORD[num_events];
		ReadConsoleInput(rHnd, eventBuffer, num_events, &num_events_read);
		for (DWORD i = 0; i < num_events_read; ++i)
		{
			if(eventBuffer[i].EventType == MOUSE_EVENT)
			{
				if (eventBuffer[i].Event.MouseEvent.dwButtonState==FROM_LEFT_1ST_BUTTON_PRESSED)
				{
					X=eventBuffer[i].Event.MouseEvent.dwMousePosition.X;
					Y=eventBuffer[i].Event.MouseEvent.dwMousePosition.Y;
					num_events=0;
					num_events_read=0;
					return true;
				}
            }
          }
	delete[] eventBuffer;
	}
	return false;
}

It always works with detecting click, but even if you don't use the mouse the keyboard input doesn't detect every keypress...anyone got an idea why this happens?
It is my understanding that _kbhit() is a function that asynchronously tells you if a key has been hit and it doesn't intend to be in synchrony with every single key press. In other words, you are not guaranteed to get one true for every key hit.

What you need is a different function, but don't ask me as I don't know which one. Google up a bit.
Last edited on
the funny thing is, that if I remove the mouse part of code, it works...
ReadConsoleInput() reads all selected console events, including key events. Your mouse code ignores all events not 'mouse'. Also, you are probably experiencing conflicts between the native API and the conio.h _getch() function.

What you should be doing is using ReadConsoleInput() in your main loop and switching off of the event type to the appropriate event handler.

Hope this helps.
so I should use ReadConsoleInput() to get the keys also?
Yes. Your loop should be:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
// pseudocode //

SetConsoleMode( unbuffered + get_mouse_events );

while (!done)
  {
  ReadConsoleInput( user_input );
  switch (user_input.EventType)
    {
    case KEY_EVENT:
      done = handle_key_event( user_input.Event.KeyEvent );
      break;

    case MOUSE_EVENT:
      done = handle_mouse_event( user_input.Event.MouseEvent );
      break;

    case WINDOW_BUFFER_SIZE_EVENT:
      handle_size_event( user_input.Event.WindowBufferSizeEvent );
      break;

    ...
    }
  }

SetConsoleMode( restore );

[edit] Where handle_foo_event() are functions you have elsewhere in your code.

Hope this helps.
Last edited on
thanks! just curious, what does SetConsoleMode() do? the microsoft page is kinda cheap with explanations...
I don't know what you mean by "cheap". It is very extensive and explicit.

Since you are trying to get unbuffered, no-echo input, you need to set the console input mode to not wait until the user presses ENTER to send input to the user. Also, you want to tell the console to give you mouse events.

Your startup code should look something like this:

1
2
3
4
5
6
7
8
9
10
11
HANDLE hInput = GetStdHandle( STD_INPUT_HANDLE );
DWORD original_console_mode;
if (!GetConsoleMode( hInput, &original_console_mode ))
  {
  cerr << "You must be a human to use this program.\n";
  return 1;
  }
SetConsoleMode( hInput, ENABLE_MOUSE_INPUT
  // | ENABLE_PROCESSED_INPUT    // Uncomment if you want the user to be able to press ^C to terminate
  // | ENABLE_WINDOW_INPUT       // Uncomment for window size events
  );

Your cleanup code should look something like this:

 
SetConsoleMode( hInput, original_console_mode );

Good luck!
ok, thanks, that's what I wanted to know :)
Topic archived. No new replies allowed.