SlimDX DirectInput Initialization

8k views Asked by At

I've recently swapped from MDX 2.0 to SlimDX, using Direct3D 11, but I'm struggling to implement keyboard and mouse controls.

In MDX you can use

keyb = new Microsoft.DirectX.DirectInput.Device(SystemGuid.Keyboard);
keyb.SetCooperativeLevel(this, CooperativeLevelFlags.Background | CooperativeLevelFlags.NonExclusive);
keyb.Acquire();

to set up a keyboard interface, however SlimDX has a different method. In SlimDX the Device is an abstract class, instead there is a Keyboard class that must be initialized by passing in a DirectInput object, but I can't for the life of me work out how to create a DirectInput object or what it's for.

As far as I can find documentation is pretty slim for SlimDX, if anybody knows of any good resources for learning its particular quirks that would be fantastic, thanks.

2

There are 2 answers

0
hitzi On BEST ANSWER

I used it in this way. The mouse handling is the same.

using SlimDX.DirectInput;

private DirectInput directInput;
private Keyboard keyboard;

[...]

//init
directInput = new DirectInput();
keyboard = new Keyboard(directInput);
keyboard.SetCooperativeLevel(form, CooperativeLevel.Nonexclusive | CooperativeLevel.Background);
keyboard.Acquire();

[...]

//read
KeyboardState keys = keyboard.GetCurrentState();

But you should use SlimDX.RawInput because Microsoft recommends it:

While DirectInput forms a part of the DirectX library, it has not been significantly revised since DirectX 8 (2001-2002). Microsoft recommends that new applications make use of the Windows message loop for keyboard and mouse input instead of DirectInput (as indicated in the Meltdown 2005 slideshow[1]), and to use XInput instead of DirectInput for Xbox 360 controllers.

(http://en.wikipedia.org/wiki/DirectInput)

A rawinput mouse sample (keyboard is nearly the same):

SlimDX.RawInput.Device.RegisterDevice(UsagePage.Generic, UsageId.Mouse, SlimDX.RawInput.DeviceFlags.None);
            SlimDX.RawInput.Device.MouseInput += new System.EventHandler<MouseInputEventArgs>(Device_MouseInput);

Now you can react on the events.

0
bvrwoo On

Use the SlimDX.RawInput To actually get the cursor from the hWnd (the control's/form's handle), you need to extern functions from the "user32.dll"

  1. BOOL GetCursorPos(LPOINT lpPoint)

using the System.Runtime.Interlop and System.Drawing.Point (unless you decide to create a POINT struct instead).

[DllImport("user32.dll",CallingConvention=CallingConvention.StdCall)]
[return: MarshalAs(UnmanagedType.Bool)]
internal unsafe static extern bool GetCursorPos(Point* lpPoint);

This will get you the actual position of the cursor on desktop screen Next you will take lpPoint address and pass it into the ScreenToClient(HWND hWnd, LPPOINT lpPoint) which also return a BOOL.

[DllImport("user32.dll",CallingConvention=CallingConvention.StdCall,SetLastError=true)]
internal static extern int ScreenToClient(IntPtr hWnd, Point* p);

Let's just get the Point from it like this then:

public unsafe Point GetClientCurorPos(IntPtr hWnd, Point*p)
{
    Point p = new Point();
    if (GetCursorPos(&p))
    {
       ScreenToClient(hWnd, &p);
    }
    return p;
}

You can use the SlimDX.RawInput.Device.MouseInput handler in you want or you can just do some coding in override for WndProc which is preferred in you are using to handling message which all of us WINAPI programmers are just used to and the tedious writing with it. However, the lower you go the more control you got. Like I said you get all the info back but the mouse position from the handler's MouseInputEventArgs. I find it better to check the processed messages via WndProc callback.