2

我最近使用 Direct3D 11 从 MDX 2.0 切换到 SlimDX,但我在努力实现键盘和鼠标控制。

在 MDX 中,您可以使用

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

设置键盘界面,但是 SlimDX 有不同的方法。在 SlimDX 中,Device 是一个抽象类,取而代之的是一个必须通过传入 DirectInput 对象来初始化的 Keyboard 类,但我终其一生都无法弄清楚如何创建 DirectInput 对象或它的用途。

据我所知,SlimDX 的文档非常少,如果有人知道任何用于学习其特殊怪癖的好资源,那将是非常棒的,谢谢。

4

2 回答 2

4

我以这种方式使用它。鼠标处理是一样的。

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();

但是你应该使用 SlimDX.RawInput 因为微软推荐它:

尽管 DirectInput 是 DirectX 库的一部分,但自 DirectX 8 (2001-2002) 以来它没有进行过重大修订。Microsoft 建议新应用程序对键盘和鼠标输入使用 Windows 消息循环而不是 DirectInput(如 Meltdown 2005 幻灯片中所示[1]),并在 Xbox 360 控制器中使用 XInput 而不是 DirectInput。

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

一个 rawinput 鼠标示例(键盘几乎相同):

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

现在您可以对事件做出反应。

于 2011-02-08T11:17:30.320 回答
1

使用 SlimDX.RawInput 要从 hWnd(控件/表单的句柄)实际获取光标,您需要从“user32.dll”中外部函数

  1. BOOL GetCursorPos(LPOINT lpPoint)

使用 System.Runtime.Interlop 和 System.Drawing.Point(除非您决定改为创建 POINT 结构)。

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

这将为您提供光标在桌面屏幕上的实际位置接下来您将获取 lpPoint 地址并将其传递给 ScreenToClient(HWND hWnd, LPPOINT lpPoint),它也返回一个 BOOL。

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

让我们像这样从中获取点:

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

您可以根据需要使用 SlimDX.RawInput.Device.MouseInput 处理程序,或者您可以在覆盖 WndProc 时进行一些编码,这在您用来处理我们所有 WINAPI 程序员都习惯的消息和繁琐的写作中是首选用它。然而,你走得越低,你得到的控制就越多。就像我说的那样,您可以从处理程序的 MouseInputEventArgs 中获取所有信息,但鼠标位置除外。我发现最好通过 WndProc 回调检查已处理的消息。

于 2011-11-27T01:14:05.763 回答