鼠标在Winforms中不使用Monogame

时间:2015-11-19 19:23:24

标签: c# .net winforms monogame

我使用以下代码将Monogame嵌入到Windows窗体中:

    private IntPtr drawSurface;
    private Control gameForm;

    public MapEditor(MainWindow window)
    {
        graphics = new GraphicsDeviceManager(this);
        Content.RootDirectory = "Content";

        this.drawSurface = window.pcbViewport.Handle;
        graphics.PreparingDeviceSettings += new EventHandler<PreparingDeviceSettingsEventArgs>(graphics_PreparingDeviceSettings);
        Mouse.WindowHandle = drawSurface;
        gameForm = Control.FromHandle(this.Window.Handle);
        gameForm.VisibleChanged += new EventHandler(gameForm_VisibleChanged);
    }  

    private void gameForm_VisibleChanged(object sender, EventArgs e)
    {
        if (gameForm.Visible)
        {
            gameForm.Visible = false;
        }
    }

    private void graphics_PreparingDeviceSettings(object sender, PreparingDeviceSettingsEventArgs e)
    {
        e.GraphicsDeviceInformation.PresentationParameters.DeviceWindowHandle = drawSurface;
    }

现在,这段代码曾经工作......我想。已经有一段时间了,代码在另一台带有旧版本的计算机上,所以我似乎记得以前使用Monogame工作。无论如何,问题是鼠标输入不起作用!键盘和游戏手柄输入工作正常,但鼠标输入根本没有注册。我已经进行了实验,发现如果我拿出VisibleChanged事件,它可以工作,但它也会显示GameWindow以及表单(它不需要在PictureBox中绘制。

我知道我可以把GameWindow放在一个Control中,如果需要那么我会这样做但是我试图看看是否有解决方案让现有代码再次运行。

1 个答案:

答案 0 :(得分:1)

您的方法存在的问题是,在Mouse.WindowHandle中设置MonoGame不会做任何事情(如果您look at the source code,此属性的setter为空。) 1

这意味着您的Game始终绑定到其默认窗口(您隐藏的窗口),并忽略该窗口外的所有鼠标输入。如果您不隐藏它,您将看到单击原始窗口会正确创建鼠标事件。另一方面,绘图正确地完成到图片框。键盘事件不会按屏幕区域进行过滤,因此它们可以正常工作。

我的观点是,这不是你应该如何在Windows窗体中托管XNA / MonoGame,而是研究如何实现一个GraphicsDeviceControl类,它应该继承自System.Windows.Forms.Control并提供能力通过使用XNA框架GraphicsDevice来绘制自己。该方法在this article(XNA 4,但可以轻松移植到MonoGame)中进行了解释。

如果您确实想要使用您现在使用的方法,那么您可以做的唯一事情就是检查MonoGame源代码,并找到Windows窗体GameWindow的实现(也就是说,WinFormsGameWindow,这是一个内部类。由于Mouse.GetState()仅返回GameWindow.MouseState,因此可以实例化您自己的GameWindow,这样您就可以通过 窗口获取事件。

或者,如果你正在改变MonoGame代码,那么你也可以添加一个Game构造函数重载,从一开始就接受Control句柄。

<小时/> 1 具有讽刺意味的是,内部有一条评论说这个setter只是为了XNA兼容性而且#34;就像抛出一个编译时错误相比,人们将失去的时间是一个大问题调试这个。 :-D