Mouse not working with Monogame in Winforms

血红的双手。 提交于 2021-02-08 06:10:46

问题


I've embedded Monogame into a Windows Form using this code:

    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;
    }

Now, this code used to work... I think. It's been a while and the code is on another computer with an older version so I seem to remember this working before now with Monogame. Anyway, the problem is that Mouse input doesn't work! Keyboard and Gamepad input work fine, but Mouse input doesn't register at all. I've experimented and found that if I take out the VisibleChanged event, it works but it also shows the GameWindow as well as the form (which it doesn't need to as it's being drawn in the PictureBox.

I'm aware that I can put the GameWindow in a Control, and if need be then I'll do that but I'm trying to see if there is a solution to making the existing code work again.


回答1:


The issue with your approach is that setting Mouse.WindowHandle in MonoGame does nothing (the setter for this property is empty, if you look at the source code).1

This means that your Game is always bound to its default window (the one that you are hiding), and that all mouse input outside that window is ignored. If you don't hide it, you will see that clicking into the original window creates mouse events correctly. Draws, on the other hand, are done to the picture box correctly. Keyboard events are not filtered by screen area, so they work without issues.

My opinion is that this is not how you should be hosting XNA/MonoGame inside Windows Forms, but instead look into how to implement a GraphicsDeviceControl class, which should inherit from System.Windows.Forms.Control and provide the ability to draw itself by using an XNA Framework GraphicsDevice. The approach is explained in this article (XNA 4, but can be easily ported to MonoGame).

If you do want to use the approach you are using right now, the only thing you can do is checkout MonoGame source code, and find the implementation of GameWindow for windows forms (that is, WinFormsGameWindow, which is an internal class). Since Mouse.GetState() merely returns GameWindow.MouseState, a possibility to instantiate your own GameWindow would allow you to get the events filtered by your window.

Or, if you are changing MonoGame code anyway, then you might as well add a Game constructor overload which would accept the Control handle from the start.


1 Ironically, there is a comment inside that this setter was left "only for XNA compatibility", like throwing a compile-time error is a big deal compared to the time people will lose debugging this. :-D

来源:https://stackoverflow.com/questions/33812634/mouse-not-working-with-monogame-in-winforms

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!