Jump to content
Xtreme .Net Talk

Recommended Posts

Posted

I'm having trouble getting the correct coordinates from a mouse device. It displays mostly 0s and a few negative numbers when I move the mouse around. :confused:

 

Here's my mouse initialization;

 

	/// <summary>
	/// Instantiates a new Mouse for the specified window.
	/// </summary>
	/// <param name="window">Window to obtain mouse input for.</param>
	public Mouse(Control window)
	{
		// Store window.
		_window = window;

		// Get mouse device.
		_device = new Device(SystemGuid.Mouse);

		_device.SetDataFormat(DeviceDataFormat.Mouse);
		_device.SetCooperativeLevel(_window, CooperativeLevelFlags.NonExclusive | CooperativeLevelFlags.Foreground);

		// Try to acquire mouse access.
		_acquireMouse();
	}

 

And this is the method where I retrieve mouse coordinate info (note MouseAxis is just an enum that describes X, Y and Z);

 

	/// <summary>
	/// Gets mouse coordinates for the specified axis.
	/// </summary>
	/// <param name="axis">Axis to retrieve coordinates for.</param></param>
	/// <returns>Coordinates for the specified axis, or 0 on failure.</returns>
	private int _getMouseCoordinates(MouseAxis axis) 
	{
		try {
			// Get mouse state.
			MouseState state = _device.CurrentMouseState;
			
			// Retrieve mouse coordinate info.
			switch(axis) {
				case MouseAxis.X:
					return state.X;

				case MouseAxis.Y:
					return state.Y;

				case MouseAxis.Z:
					return state.Z;

				default:
					// No other axis.
					break;
			}
		}
		catch {
			// Lost access to mouse.
			_acquireMouse();
		}

		// Couldn't retrieve mouse information, return error.
		return 0;
	}

 

I'm totally baffled by this. :(

Gamer extraordinaire. Programmer wannabe.
Posted

I found out that the X, Y and Z are related to how far the mouse has moved since the last call to CurrentMouseState. Now isn't that convenient? (Note: Sarcasm).

 

I've got it semi-working I guess. I keep track of the X, Y and Z via int variables and just increment them based on what the CurrentMouseState returns.

 

The problem now is;

- Z still isn't working.

- Y still isn't working.

- How can I get or set the initial coordinates of the mouse or the ACTUAL x,y position?

 

EDIT:

Nevermind, I know why Y and Z aren't working. I guess the only thing I need to know now is how to set the initial mouse position or get the actual x,y coordinates.

Gamer extraordinaire. Programmer wannabe.
Posted

I was thinking of just using the Cursor object to retrieve the exact position of the cursor over the screen or window (in windowed mode). It's certainly make my life a lot easier... but then I wouldn't be able to keep track of the wheel.

 

Thoughts?

Gamer extraordinaire. Programmer wannabe.
Posted (edited)

WOOT! Finally. Yeesh.

 

I tried doing it by updating myself with the X and Y from the mouse (every little bit of efficiency helps), but it was majorly flawed and writing code to check accuracy would of been a waste of time. So in the end I ended up using the Cursor object to retrieve the mouse coordinates.

 

I also needed a way to get the wheel info, which proved a task in itself, because once you call GetMouseState, it resets the wheel info.. so if I retrieved button information, then wheel information, wheel would always return 0. :(

 

I thought about using a thread which would just update the mouse info by itself, and then call events when a button is clicked, etc. But at that point I might as well be using the provided mouse handling events inside .NET.

 

After much debate and banging my head against the wall, I decided to make a MouseInfo property, which returns a MouseInfo object that contains the information I need. If the mouse isn't acquired, it returns null. I've done quite a few tests, and so far it works.

 

*pats self on back* I have yet to see a tutorial which covers mouse handling of the wheel and screen coordinates, so I'm quite happy that I figured all this out.

 

For those who may have similar troubles, here's the code;

 

MouseEnums

using System;

namespace GameUtil
{
public enum DIWheelDirections { Up, Down, Idle }
public enum DIMouseButtons { Left, Right, Wheel }
public enum DIMouseClicked { False }
}

 

Mouse

using System;
using System.Windows.Forms;
using System.Drawing;
using Microsoft.DirectX.DirectInput;

namespace GameUtil
{
/// <summary>
/// Responsible for mouse device.
/// </summary>
public class Mouse
	: IDisposable
{
	#region Member Variables

	Device _device = null;
	Control _window = null;

	private bool _disposed = false;

	#endregion

	#region Constructor

	/// <summary>
	/// Instantiates a new Mouse for the specified window.
	/// </summary>
	/// <param name="window">Window to obtain mouse input for.</param>
	public Mouse(Control window)
	{
		// Store window.
		_window = window;

		// Get mouse device.
		_device = new Device(SystemGuid.Mouse);

		_device.SetDataFormat(DeviceDataFormat.Mouse);
		_device.SetCooperativeLevel(_window, 
			CooperativeLevelFlags.NonExclusive | CooperativeLevelFlags.Foreground);

		// Try to acquire mouse access.
		_acquireMouse();
	}

	#endregion

	#region Dispose And Destructor

	/// <summary>
	/// Dispose of this Mouse.
	/// </summary>
	public void Dispose() 
	{
		this.Dispose(true);
		GC.SuppressFinalize(this);
	}

	/// <summary>
	/// Dispose of this Mouse.
	/// </summary>
	/// <param name="disposing">Set to true if disposing.</param>
	protected void Dispose(bool disposing) 
	{
		// Check if already disposed.
		if (_disposed) {
			return;
		}

		if (disposing) {
			// Cleanup managed resources.
			_device.Unacquire();
			_device.Dispose();
		}

		// Mouse is now disposed of.
		_disposed = true;
	}

	/// <summary>
	/// Destroys this Mouse.
	/// </summary>
	~Mouse() 
	{
		this.Dispose(false);
	}

	#endregion

	#region Helper Methods

	/// <summary>
	/// Attempts to acquire access to the mouse.
	/// </summary>
	private void _acquireMouse() 
	{
		try {
			_device.Acquire();
		}
		catch (Exception) {
			// Ignore errors.
		}
	}

	#endregion

	#region Properties

	/// <summary>
	/// Gets the information of this Mouses current state.
	/// </summary>
	public MouseInfo MouseInfo 
	{
		get {
			try {
				return new MouseInfo(this);
			}
			catch (Exception) {
				// Lost access to mouse.
				_acquireMouse();
			}

			// No info found.
			return null;
		}
	}

	/// <summary>
	/// Gets the Device for this Mouse.
	/// </summary>
	public Device Device 
	{
		get {
			return _device;
		}
	}

	/// <summary>
	/// Gets the control this Mouse is accessing input for.
	/// </summary>
	public Control Window 
	{
		get {
			return _window;
		}
	}

	#endregion
}
}

 

MouseInfo

using System;
using System.Windows.Forms;
using System.Drawing;
using Microsoft.DirectX.DirectInput;

namespace GameUtil
{
/// <summary>
/// Mouse information.
/// </summary>
internal class MouseInfo
{
	#region Member Variables

	private bool[] _buttons = { false, false, false };

	private Point _position = Point.Empty;
	private int _wheelMovement = 0;
	private DIWheelDirections _wheelDirection = DIWheelDirections.Idle;

	#endregion

	#region Constructors

	/// <summary>
	/// Instantiates a new MouseInfo object based off of a Mouse.
	/// </summary>
	/// <param name="mouse">Mouse to get information from.</param>
	internal MouseInfo(Mouse mouse) 
	{
		// Get mouse state.
		MouseState state = mouse.Device.CurrentMouseState;	

		_setButtons(state.GetMouseButtons());
		_position = mouse.Window.PointToClient(Cursor.Position);
		_setWheel(state.Z);
	}

	#endregion

	#region Helper Methods

	/// <summary>
	/// Sets mouse button information.
	/// </summary>
	/// <param name="buttonState">Array of button states.</param>
	private void _setButtons(byte[] buttonState) 
	{
		// Set each button based off its state.
		for (DIMouseButtons button = DIMouseButtons.Left; button <= DIMouseButtons.Wheel; button = button + 1) {
			if (buttonState[(int) button] == (int) DIMouseClicked.False) {
				_buttons[(int) button] = false;
			}
			else {
				_buttons[(int) button] = true;
			}
		}
	}

	/// <summary>
	/// Sets the wheel direction and movement.
	/// </summary>
	/// <param name="amount">Amount the wheel has moved.</param>
	private void _setWheel(int amount) 
	{
		// Set amount moved.
		_wheelMovement = amount;

		// Check if wheel was moved up.
		if (_wheelMovement > 0) {
			_wheelDirection = DIWheelDirections.Up;
		}
			// Check if wheel was moved down.
		else if (_wheelMovement < 0) {
			_wheelDirection = DIWheelDirections.Down;
		}
			// Wheel is idle.
		else {
			_wheelDirection = DIWheelDirections.Idle;
		}
	}

	#endregion

	#region Properties

	/// <summary>
	/// Gets or sets whether the left button is clicked.
	/// </summary>
	public bool LeftClick 
	{
		get {
			return _buttons[(int) DIMouseButtons.Left];
		}
	}

	/// <summary>
	/// Gets or sets whether the right button is clicked.
	/// </summary>
	public bool RightClick 
	{
		get {
			return _buttons[(int) DIMouseButtons.Right];
		}
	}

	/// <summary>
	/// Gets whether the wheel button is clicked.
	/// </summary>
	public bool WheelClick 
	{
		get {
			return _buttons[(int) DIMouseButtons.Wheel];
		}
	}

	/// <summary>
	/// Gets XCoordinates of mouses cursor.
	/// </summary>
	public int X 
	{
		get {
			return _position.X;
		}
	}

	/// <summary>
	/// Gets or sets YCoordinates of mouses cursor.
	/// </summary>
	public int Y 
	{
		get {
			return _position.Y;
		}
	}

	/// <summary>
	/// Gets the amount the mouse wheel was moved.
	/// </summary>
	public int WheelMovement 
	{
		get {
			return _wheelMovement;
		}
	}

	/// <summary>
	/// Gets the direction the mouse wheel was moved in.
	/// </summary>
	public DIWheelDirections WheelDirection 
	{
		get {
			return _wheelDirection;
		}
	}

	#endregion
}
}

 

Example:

Mouse mouse = new Mouse(this);
MouseInfo mouseInfo = null;

// Game loop.
while (_running) {
  mouseInfo = mouse.MouseInfo;
  if (mouseInfo != null) {
     // mouseInfo.LeftClick etc...
     // ...
  }
}

Edited by wyrd
Gamer extraordinaire. Programmer wannabe.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...