How to get the mouse position ?

I love this forum : people is usually very nice here.

  1. To get the position of the mouse, I use “GetCursorPos”, of “Windows.h”, but the position that it gives to me seems to be “late” compared to the real position of the mouse, although the frame rate of my program is 85. Do you know another way with Windows to get the cursor position? I use Visual C++.
  2. I use glut too, but I only know “glutMouseFunc” and “glutMotionFunc”, and these functions are called only if a button is pressed!!! Do you know a way, by using glut, to get the position of the mouse when I want, for exemple, a callback function that would be called EACH TIME THE MOUSE MOVES?

THANK YOU VERY MUCH!

Hey FredonMouse! Yup i agree with ya…people are pretty nice on this forum…that’s why i love posting here. Now about your problem:

I can help with with your first issue. I don’t know glut so i don’t know how to answer your second question.

Ok in the WndProc procedure when you are handling each and every message you need to (like WM_CREATE, WM_QUIT, etc.), add in WM_MOUSEMOVE. Whenever your mouse is moved, that message gets pushed on the stack. Ok, the wParam is going to contain the state of the mouse buttons. It can be set to any of the following:

  • [li]MK_CONTROL Set if the ctrl key is down. []MK_LBUTTON Set if the left mouse button is down. []MK_MBUTTON Set if the middle mouse button is down. []MK_RBUTTON Set if the right mouse button is down. []MK_SHIFT Set if the shift key is down.

And now if you want to know where the coordinates for the cursor are, you would get them like this:

The x-position of the cursor is retrieved by:

LOWORD(lParam)

The y-position of the cursor is retrieved by:

HIWORD(lParam)

So for your purposes, the code might look like this:

//This is inside the switch statement to handle messages

case WM_MOUSEMOVE:
// Set the x-coord variable
xPos = LOWORD(lParam)
// Set the y-coord variable
yPos = HIWORD(lParam)

//finish the case
break;

Ok to wrap things up, you check for the WM_MOUSEMOVE message and then use LOWORD and HIWORD on the lParam to get the x and y coordinates. The wParam stuff is just if you need it. And actually i THINK that GetCursorPos is supposed to give you the current coordinate…but as to why it isn’t i don’t know. I hope all this helps. If you have any more questions ask away!

Happy Holidays!

  • Halcyon

Hi.
As with your second question about Glut…
I think that GlutMouseFunc callback works fine and it does not require any mouse button to be pressed.
What exactly do u mean ?

Ok again… i don’t know much about glut. The following was gleaned from the red book. Ok it says that glutMouseFunc only checks for mouse button presses and releases. Also glutMotionFunc looks for movement of the mouse WHILE a key is pressed!! So i have no idea how you would check to see if the mouse is in motion without a key being pressed. I wouldnt’ mind knowing either if anyone knows.

Have a good New Years

  • Halcyon

Halcyon stated in his post that to check for mouse movement regardless if a key is being pressed our not, check for the WM_MOUSEMOVE message in your WndProc procedures case statement. The LOWORD & HIWORD of lParam contains the current X & Y position of the mouse respectively.

If U’re using the mouse capture routine and want to use a fast interface
just use DirectX by the following steps:

1.- Include the <dinput.h> header file
2.- Declare DirectInput variables
Including a nice struct of data that will keep up to date
the current mouse position and Button status
3.- Declaring DirectInput functions that do the job
or transform the appropiate behavior of your program vars
4.- Take into account the logical order of call to these functions
1.- Call CreateDInput upon Window creation prior to initialize
OpenGL.
2.- Call UpdateDirectInputState before rendering the scene, so
when you draw the mouse pointer every frame it’ll be already
in the right place (see below example ***)
3.- Call DestroyDInput upon Window destruction
5.- Accomodate the UpdateDirectInputState function to change
6.- Enjoy the fastest way of acquire mouse status!

(***)
UpdateDirectInputState(); // Take a look at the mouse status
if (DrawGLScene())
SwapBuffers(hDC); // Swap Buffers (Double Buffering)
else
done=TRUE;

NOTE: acquiring the mouse status via Windows Message Queue is slower than
acquiring it directly from the input device every time you redraw
the scene!

/////////////////////////////////////////////////////////////////////////////

#include <windows.h>
#include <dinput.h>
#include <GL/gl.h>
#include <GL/glu.h>
#include <stdlib.h>
#include <stdio.h>

////////////////////////////////////////////////////
// Global variables related to the app window //
/////////////////////////////////////////////////////

HDC hDC=NULL; // Private GDI Device Context
HGLRC hRC=NULL; // Permanent Rendering Context
HWND hWnd=NULL; // Holds Our Window Handle
HINSTANCE hInstance; // Holds The Instance Of The Application
LPDIRECTINPUT g_pDI; // DirectInput Object
LPDIRECTINPUTDEVICE g_pdidMouse; // DirectInput Device interface
int winH, winW; // Screen or window width and height

struct GL_MOUSE_STATUS
{
int x, y, z;
bool button1, button2, button3;
}MyMouseStatus;

//////////////////////////////// Function Declarations ////////////////////////////////

BOOL CreateDInput(HWND hWnd);
VOID DestroyDInput(void);
void UpdateDirectInputState(void);

//////////////////////////////// Function Definitions ////////////////////////////////

//-----------------------------------------------------------------------------
// Name: CreateDInput()
// Desc: Initialize the DirectInput variables using:
// DirectInputCreate
// IDirectInput::CreateDevice
// IDirectInputDevice::SetDataFormat
// IDirectInputDevice::SetCooperativeLevel
//-----------------------------------------------------------------------------
BOOL CreateDInput( HWND hWnd )
{
HINSTANCE hInst = (HINSTANCE)GetWindowLong( hWnd, GWL_HINSTANCE );
HRESULT hr;
// Register with the DirectInput subsystem and get a pointer
// to a IDirectInput interface we can use
if( FAILED( hr = DirectInputCreate( hInst, DIRECTINPUT_VERSION, &g_pDI, NULL) ) )
return hr;
// Obtain an interface to the system mouse device
if( FAILED( hr = g_pDI->CreateDevice( GUID_SysMouse, &g_pdidMouse, NULL ) ) )
return hr;
// Set the data format to “mouse format”. A data format specifies which
// controls on a device we are interested in, and how they should be
// reported. This tells DirectInput that we will be passing a
// DIMOUSESTATE structure to IDirectInputDevice::GetDeviceState.
if( FAILED( hr = g_pdidMouse->SetDataFormat( &c_dfDIMouse ) ) )
return hr;
// Set the cooperativity level to let DirectInput know how this device
// should interact with the system and with other DirectInput applications.
// Use DISCL_NONEXCLUSIVE to Retrieve mouse data when acquired, not
// interfering with any other applications which are reading mouse data.
// Use DISCL_FOREGROUND so that if the user switches away from our app,
// automatically release the mouse back to the system.
if( FAILED( hr = g_pdidMouse->SetCooperativeLevel( hWnd, DISCL_EXCLUSIVE | DISCL_FOREGROUND ) ) )
return hr;
return S_OK;
}

//-----------------------------------------------------------------------------
// Name: DestroyDInput()
// Desc: Terminate our usage of DirectInput
//-----------------------------------------------------------------------------
VOID DestroyDInput(void)
{
// Destroy the mouse object
if( g_pdidMouse )
{
g_pdidMouse->Unacquire(); // Unacquire the device (just in case) before exitting.
g_pdidMouse->Release();
g_pdidMouse = NULL;
}
// Destroy the DInput object
if( g_pDI )
{
g_pDI->Release();
g_pDI = NULL;
}
}

//-----------------------------------------------------------------------------
// Name: UpdateDirectInputState()
// Desc: The game plays here. Read mouse data and displaying it.
//-----------------------------------------------------------------------------
VOID UpdateDirectInputState(void)
{
if( g_pdidMouse )
{
DIMOUSESTATE dims; /* DirectInput mouse state structure */
HRESULT hr;

hr = g_pdidMouse-&gt;GetDeviceState( sizeof(DIMOUSESTATE), &dims );

if( hr == DIERR_INPUTLOST )
{
  // DInput is telling us that the input stream has been interrupted.
  // We aren't tracking any state between polls, so just re-acquire
  // and try again.
  hr = g_pdidMouse-&gt;Acquire();
  if( SUCCEEDED(hr) )
    UpdateDirectInputState();
}

if( SUCCEEDED(hr) )
{
  // Get x
  MyMouseStatus.x += dims.lX;
  // force mouse x to be inside 0 and winW
  if (MyMouseStatus.x&gt;winW)
    MyMouseStatus.x=winW;
  if (MyMouseStatus.x&lt;0)
    MyMouseStatus.x=0;
  // Get y
  MyMouseStatus.y -= dims.lY;
  // force mouse y to be inside 0 and winH
  if (MyMouseStatus.y&gt;winH)
    MyMouseStatus.y=winH;
  if (MyMouseStatus.y&lt;0)
    MyMouseStatus.y=0;
  if (dims.rgbButtons[0] & 0x80)  // Button1 pressed????
    MyMouseStatus.button1 = true;
  else                            // Button1 released is (!dims.rgbButtons[0] & 0x80)
    MyMouseStatus.button1 = false;
  if (dims.rgbButtons[1] & 0x80)  // Button2 pressed????
    MyMouseStatus.button2 = true;
  else                            // Button2 released is (!dims.rgbButtons[1] & 0x80)
    MyMouseStatus.button2 = false;
  if (dims.rgbButtons[2] & 0x80)  // Button3 pressed????
    MyMouseStatus.button3 = true;
  else                            // Button3 released is (!dims.rgbButtons[2] & 0x80)
    MyMouseStatus.button3 = false;

  // In this case i change what i want by pressing Button1 and Button2
  // ***** YOU CHANGE WHAT YOU WANT *****

  if (MyMouseStatus.button1)
    eye[2]+=dims.lY;
  if (MyMouseStatus.button2)
  {
    eye[0]+=dims.lX;
    eye[1]-=dims.lY;
  }
}

}
}

Have nice programming!

Or use GLFW :


int x, y;
glfwGetMousePos( &x, &y );

To make the mouse behave as if you read the coordinates directly from the mouse (not from the cursor position relative to the window coordinates), just do:


glfwDisable( GLFW_MOUSE_CURSOR );

Simple? Yes! Powerful? Yes! Fast mouse response? Yes! Portable? Yes!

Hi,
Regarding GLUT, there is a passive mouse function that you are looking for. It is called this way…

glutPassiveMotionFunc(MousePassiveMotion);

The function begins something like…

void MousePassiveMotion(int x, int y){
//do something here
}

It works very well,
Regards,
ChuckB