Capturing mouse clicks and keyboard activity

Hello, I am a student trying to incorporate mouse clicks into a program. The main portion of my program is below.

main()
{
vector<int> world;
ACTION action = NONE;
char filename[MAX_FILENAME_LEN];
int position;
int choice;
HANDLE hin, hout;
INPUT_RECORD inrec;
DWORD counter;
COORD new_position;

hout = GetStdHandle(STD_OUTPUT_HANDLE);
hin = GetStdHandle(STD_INPUT_HANDLE);
initializeConsole(hout);
initializeApp(filename, position);//get initial values
loadFile(world, filename);//load world from initial file
printScreen(world, filename);//print world from initial file
goToCoordinate(position);//go to initial position
do
{
ReadConsoleInput(hin, &inrec, 1, &counter);
if (inrec.EventType == KEY_EVENT && inrec.Event.KeyEvent.bKeyDown)
{
choice = inrec.Event.KeyEvent.wVirtualScanCode;
getAction(action, choice);//gets valid user input
performAction(world, filename, action, position);
}
else if (inrec.EventType == MOUSE_EVENT &&
inrec.Event.MouseEvent.dwEventFlags == 0 &&
inrec.Event.MouseEvent.dwButtonState & 0x01)
{
new_position = inrec.Event.MouseEvent.dwMousePosition;
SetConsoleCursorPosition(hout, new_position);
}
} while (action != EXIT);
getch();
}

My program loads successfully, and I make it into my do-while loop. However, once there, I am not able to detect mouse clicks. However, I can still enter keyboard actions. I'm a bit lost, as I've gone through my code and can't find anyplace that the activity would freeze or pend user action, other than my ReadConsoleInput call.

Any ideas what might be happening?
I couldn't answer the question, but it has come up before.
http://www.cplusplus.com/forum/general/16748/
try this...

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
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
#include <windows.h>
#include <stdio.h>

int main(void)
{
 HANDLE hStdInput,hStdOutput,hEvent;                         //WAIT_ABANDONED   = 128
 INPUT_RECORD ir[128];                                       //WAIT_OBJECT_0    = 0
 DWORD nRead;                                                //WAIT_TIMEOUT     = 258
 COORD xy;
 UINT i;

 hStdInput=GetStdHandle(STD_INPUT_HANDLE);
 hStdOutput=GetStdHandle(STD_OUTPUT_HANDLE);
 FlushConsoleInputBuffer(hStdInput);
 hEvent=CreateEvent(NULL,FALSE,FALSE,NULL);                  //Event is created non-signaled (3rd param).
 HANDLE handles[2] = {hEvent, hStdInput};                    //Program loops monitoring two handles.  The
 while(WaitForMultipleObjects(2,handles,FALSE,INFINITE))     //1st handle ( handles(0) ) is an event which
 {                                                           //is initially set to non-signaled.  The 2nd
  ReadConsoleInput(hStdInput,ir,128,&nRead);                 //handle monitored by WaitForMultipleObjects()
  for(i=0;i<nRead;i++)                                       //is the standard input handle set up to
  {                                                          //allow access to mouse/keyboard input.  As
      switch(ir[i].EventType)                                //long as neither handle is in a signaled
      {                                                      //state, WaitForMultipleObjects() will block
       case KEY_EVENT:                                       //in an efficient wait state.  If any keypress
         if(ir[i].Event.KeyEvent.wVirtualKeyCode==VK_ESCAPE) //or mouse movement occurs, WaitForMultiple
            SetEvent(hEvent);                                //Objects will return TRUE and the input will
         else                                                //be read by ReadConsolInput().  If the [ESCAPE]
         {                                                   //key is pressed the event object represented
            xy.X=0;xy.Y=0;                                   //by hEvent will be set to a signaled state by
            SetConsoleCursorPosition(hStdOutput,xy);         //the SetEvent() Api function.  This will be
            printf                                           //picked up by the next WaitForMultipleObjects()
            (                                                //call, and the function will return FALSE and
             "AsciiCode = %d: symbol = %c\n",                //execution will drop out of the while loop
             ir[i].Event.KeyEvent.uChar.AsciiChar,           //and program termination will occur.
             ir[i].Event.KeyEvent.uChar.AsciiChar
            );                                               //It is important to note that if the 3rd
         }                                                   //parameter to WaitForMultipleObjects() is
         break;                                              //set to FALSE, the function will return if
       case MOUSE_EVENT:                                     //either of the handles in the HANDLE array
         xy.X=0, xy.Y=1;                                     //represented by handles is signaled.
         SetConsoleCursorPosition(hStdOutput,xy);
         printf
         (
          "%.3d\t%.3d\t%.3d",
          ir[i].Event.MouseEvent.dwMousePosition.X,
          ir[i].Event.MouseEvent.dwMousePosition.Y,
          (int)ir[i].Event.MouseEvent.dwButtonState & 0x07   //mask out scroll wheel, which screws up
         );                                                  //output
         break;
      }
  }
 };

 return 0;
}
Thanks for the help. I tried using the above code, and the keyboard input works fine, but it's still not reading mouse events. I'll keep tinkering and see if I can't figure it out.

Thanks again for the input.
Last I knew of it worked perfectly. As you move the mouse about the screen it continuously updates the x/y coordinate position. Let me re-compile it once and see...
Just checked it with CodeBlocks on Win XP sp3. It works perfectly. Its a console program , you know. It prints details about the ascii code pressed on the 1st line, and on the 2nd line a continuous update of the mouse position as you move the mouse over the console window. In fact, it also catches and outputs left and right mouse button clicks. You tell me that is not what you are seeing? I've about a half dozen C++ compilers. Which one are you using? I'll compile on that one and see.

Just occurred to me. Are you using Win2000? With that 'Quick Edit' is usually enabled. It might not work until you change that setting in the console window properties!
Last edited on
closed account (z05DSL3A)
Just a thought:

Have you tried setting the console mode to enable mouse input?
1
2
3
4
5
HANDLE hStdin = GetStdHandle(STD_INPUT_HANDLE);

DWORD fdwMode = ENABLE_WINDOW_INPUT | ENABLE_MOUSE_INPUT; 

SetConsoleMode(hStdin, fdwMode) 


http://msdn.microsoft.com/en-us/library/ms686033(VS.85).aspx
Last edited on
The more I think about it, the more I'm sure that's the user's problem. I just went into 'Properties' >> Options for the console window for my program above (in XP ) and turned 'Quick Edit' mode on, and sure enough the program stops capturing mouse input. This whole issue caused me major problems back in Win2000 times, as it affected DOS programs that used a mouse too.

Your SetConsoleMode() function above appears to be a way to programatically turn 'Quick Edit' mode off. Wish I'd have known that 10 years ago. Would've helped.
Today I spent a few minutes reviewing this issue, and here is what I determined. Grey Wolf's suggestion is a good one; however, here is what must be used to turn off that blasted, no good, rotten 'Quick Edit' mode

SetConsoleMode(hStdInput,ENABLE_MOUSE_INPUT|ENABLE_EXTENDED_FLAGS);

As far as I know, this issue only affects Windows 2000 machines. This problem didn't occur with Win95/98, but it struck with a vengence in Windows 2000. I believe Microsoft got so much flack about it that they turned it off in Win XP. I don't know anything about Vista/Windows 7 as I've only seen it in stores.

Today I compiled the above code I posted on a Windows 2000 machine and made a shortcut to the executable. Then I right clicked the shortcut >> Properties >> Options, and made sure 'Quick Edit' was on. Then I ran this program...

ues WaitForSingleObject() instead...
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
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
#include <windows.h>
#include <stdio.h>

int main(void)
{
 HANDLE hStdInput,hStdOutput;
 INPUT_RECORD ir[128];
 bool blnLoop=true;
 DWORD nRead;
 COORD xy;
 UINT i;

 hStdInput=GetStdHandle(STD_INPUT_HANDLE);
 hStdOutput=GetStdHandle(STD_OUTPUT_HANDLE);
 SetConsoleMode(hStdInput,ENABLE_MOUSE_INPUT|ENABLE_EXTENDED_FLAGS);   //<<<flags
 FlushConsoleInputBuffer(hStdInput);
 do
 {
   if(WaitForSingleObject(hStdInput,3000)==WAIT_TIMEOUT)
      break;
   else
   {
      ReadConsoleInput(hStdInput,ir,128,&nRead);
      for(i=0;i<nRead;i++)
      {
          switch(ir[i].EventType)
          {
           case KEY_EVENT:
             if(ir[i].Event.KeyEvent.wVirtualKeyCode==VK_ESCAPE)
                blnLoop=false;
             else
             {
                xy.X=0;xy.Y=0;
                SetConsoleCursorPosition(hStdOutput,xy);
                printf
                (
                 "AsciiCode = %d: symbol = %c\n",
                 ir[i].Event.KeyEvent.uChar.AsciiChar,
                 ir[i].Event.KeyEvent.uChar.AsciiChar
                );
             }
             break;
           case MOUSE_EVENT:
             xy.X=0, xy.Y=1;
             SetConsoleCursorPosition(hStdOutput,xy);
             printf
             (
              "%.3d\t%.3d\t%.3u",
              ir[i].Event.MouseEvent.dwMousePosition.X,
              ir[i].Event.MouseEvent.dwMousePosition.Y,
              (unsigned int)ir[i].Event.MouseEvent.dwButtonState & 0x07
             );
             break;
          }//end switch
      }//end for
   }//end if
 }//end do
 while(blnLoop==true);

 return 0;
}


Sure enough it worked due to the SetConsoleMode() call above with the flags set as indicated. However, if you recompile and comment out that line, it doesn't work on Win 2000.

Interestingly, it doesn't change the setting in 'Properties'. The blasted 'Quick Edit' mode will still be on; however, that call allows the mouse input to come through.

I have never seen a Window XP computer evince this problem. As I mentioned, Microsoft got a lot of flack about it.
Topic archived. No new replies allowed.