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
C#:
using System;
namespace GameUtil
{
public enum DIWheelDirections { Up, Down, Idle }
public enum DIMouseButtons { Left, Right, Wheel }
public enum DIMouseClicked { False }
}
Mouse
C#:
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
C#:
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:
C#:
Mouse mouse = new Mouse(this);
MouseInfo mouseInfo = null;
// Game loop.
while (_running) {
mouseInfo = mouse.MouseInfo;
if (mouseInfo != null) {
// mouseInfo.LeftClick etc...
// ...
}
}