MOIS Nonexclusive mode- keep the cursor in the window

geekay

27-09-2011 22:13:45

I dont like to use 'software cursors' (so every frame a picture is re-positioned and redrawn), so I am currently using 'non exclusive' mode so that the mouse cursor is unlocked and can move around managed by the host windowsOS computer (then I just change the cursors picture).

However, I would like to lock the mouse's position to be within the bounds of the window, so that if you are using a duel screen set up you don't accidentally click outside of the game.

Is there any type of 'set position of cursor' methods in MOIS that can accomplish this? or what do you recommend is the best way to accomplish this task.


Thank you so very kindly for your time, and any help is very much appreciated!

smiley80

27-09-2011 23:50:11

[DllImport("user32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
static extern bool GetClientRect(IntPtr hWnd, out RECT lpRect);

[DllImport("user32.dll")]
static extern int MapWindowPoints(IntPtr hwndFrom, IntPtr hwndTo, ref POINT lpPoints, [MarshalAs(UnmanagedType.U4)] int cPoints);

[StructLayout(LayoutKind.Sequential)]
public struct POINT
{
public int X;
public int Y;
}

[StructLayout(LayoutKind.Sequential)]
public struct RECT
{
public int Left;
public int Top;
public int Right;
public int Bottom;
}


Usage:
RECT clientRec;
GetClientRect(windowHnd, out clientRec);
POINT p = new POINT();
MapWindowPoints(windowHnd, IntPtr.Zero, ref p, 1);
System.Windows.Forms.Cursor.Clip = new System.Drawing.Rectangle(p.X, p.Y, clientRec.Right, clientRec.Bottom);

The above has to be redone when the window loses/regains focus.

I dont like to use 'software cursors' (so every frame a picture is re-positioned and redrawn)
So you only call 'RenderOneFrame' when anything relevant changes?

geekay

28-09-2011 06:49:08

Works perfectly.

I would hate to be any more of a bother, but just one last question: how can I listen for the ogre created window losing focus, and react to it?



geekay wrote:
I dont like to use 'software cursors' (so every frame a picture is re-positioned and redrawn)
smiley80 wrote:
So you only call 'RenderOneFrame' when anything relevant changes?


Honestly I am not in this case; I just have a custom render loop. What I have done in the past is create a frame listener that simply places a overlay to where the mouse is/should-be per frame, however because the mouses location was only updated per frame- and where the mouse 'has been', it created a subtle but noticeable lag (for me at least- and knowing me, I am sure that I was simply doing it incorrectly). So in this case, I am just using windows mouse cursor and replacing how it is being displayed with a custom mouse .cur file. From the looks of it, because windows is dealing with it, it seems to move about perfectly.


I am very happy with your advice it has worked 100% for me so far! (Now I just need to figure out how to listen for window losing/gaining focus bit). Thanks so very much again for your help!

smiley80

29-09-2011 16:37:25

Derive from WindowEventListener:
public class MyWindowEventListener : WindowEventListener
{
public override void WindowFocusChange(RenderWindow rw)
{
//set clip
}
}

After you create the window:
WindowEventUtilities.AddWindowEventListener(window, new MyWindowEventListener());

geekay

29-09-2011 18:11:33

many many many thanks Smiley80!! You are my hero!

-GK