Reputation: 43
#include <Windows.h>
#include <vector>
using std::vector;
class event_handler{
private:
DWORD n_evnts_read=0,n_evnts=0,evnt_type=0,mode=0;
public:
int rec_indx = 0;
vector<INPUT_RECORD> inrec;
KEY_EVENT_RECORD kev;
MOUSE_EVENT_RECORD mev;
HANDLE hndlin = GetStdHandle(STD_INPUT_HANDLE);
HANDLE hndlout = GetStdHandle(STD_OUTPUT_HANDLE);
int cap_evnt_key(){
n_evnts_read = n_evnts = evnt_type = 0;
GetNumberOfConsoleInputEvents(hndlin, &n_evnts_read);
if (n_evnts_read){
inrec.resize(n_evnts_read);
ReadConsoleInput(hndlin, &inrec[0], inrec.size(), &n_evnts);
for(DWORD m = 0; m < n_evnts; m++)
if (inrec[m].EventType == KEY_EVENT)
{
kev = inrec[m].Event.KeyEvent;
fflush(stdin);
return 5;
}
}
return -1;
}
int cap_evnt_mouse(){
n_evnts_read = n_evnts = evnt_type = mode = 0;
GetNumberOfConsoleInputEvents(hndlin, &n_evnts_read);
if (n_evnts_read){
inrec.resize(n_evnts_read);
ReadConsoleInput(hndlin, &inrec[0], inrec.size(), &n_evnts);
for(DWORD m = 0; m < n_evnts; m++)
if (inrec[m].EventType == MOUSE_EVENT)
{
mev = inrec[m].Event.MouseEvent;
fflush(stdin);
return 5;
}
}
return -1;
}
DWORD key(){
if (!kev.bKeyDown)
return kev.wVirtualKeyCode;
else
return 0;
}
bool left_click(){
if (mev.dwButtonState == FROM_LEFT_1ST_BUTTON_PRESSED)
return 1;
else
return 0;
}
} evnt_hndlr;
void test()
{
short n = 0;
COORD pos;
while (1)
{
if (evnt_hndlr.cap_evnt_key() == 5)
{
if (evnt_hndlr.key() == VK_RIGHT)
//do something
else if (evnt_hndlr.key() == VK_LEFT)
//do something
}
else if (evnt_hndlr.cap_evnt_mouse() == 5)
{
if (evnt_hndlr.left_click() == 1)
//do something
}
}
exit(0);
}
Now, when I run test()
inside main()
and try to capture a mouse/keyboard event, sometimes it gives me the signal that the required event was captured, but sometimes it misses that event.
Kindly give me a reliable way of capturing input events (especially when both mouse and keyboard events need to be read simultaneously), because this procedure is hanging (if I'm not using the wrong word). Also, explain to me why this problem is happening. It's very bad for users indeed.
Upvotes: 0
Views: 294
Reputation: 596397
You are not processing every event that is read. Your code has the potential to throw away a lot of events. Each time you call cap_evnt_...()
, if there are any new events available to read, you throw away any events you have already read into the vector
that have not been processed yet.
Try something more like this instead:
#include <Windows.h>
#include <vector>
class event_handler{
private:
std::vector<INPUT_RECORD> evnts;
INPUT_RECORD inrec;
HANDLE hndlin = GetStdHandle(STD_INPUT_HANDLE);
HANDLE hndlout = GetStdHandle(STD_OUTPUT_HANDLE);
public:
int cap_evnt_read() {
if (evnts.empty()) {
DWORD n_evnts = 0;
GetNumberOfConsoleInputEvents(hndlin, &n_evnts);
if (n_evnts == 0) return -1;
evnts.resize(n_evnts);
ReadConsoleInput(hndlin, &evnts[0], n_evnts, &n_evnts);
}
inrec = evnts.front();
evnts.erase(events.begin());
return inrec.EventType;
}
DWORD key() const {
if (!inrec.Event.KeyEvent.bKeyDown)
return inrec.Event.KeyEvent.wVirtualKeyCode;
else
return 0;
}
bool left_click() const {
return (inrec.Event.MouseEvent.dwButtonState == FROM_LEFT_1ST_BUTTON_PRESSED);
}
}
evnt_hndlr;
void test()
{
while (true)
{
switch (evnt_hndlr.cap_evnt_read())
{
case KEY_EVENT:
{
if (evnt_hndlr.key() == VK_RIGHT)
// do something
else if (evnt_hndlr.key() == VK_LEFT)
// do something
break;
}
case MOUSE_EVENT:
{
if (evnt_hndlr.left_click())
// do something
break;
}
}
}
exit(0);
}
Upvotes: 1