Archived

This topic is now archived and is closed to further replies.

Apoztel

Managed direct input - mouse cause crash when loosing focus

Recommended Posts

Hi. I am having a problem with managed direct input. I use the mouse in exclusive | foreground in a separate thread (I began with the mouse example from the SDK). However when I ALT-TAB it takes 2-3 seconds and then it crashes with a Lost input -error. I have no idea why, but I think I am missing something in the event chain of losing focus and so on. The most noteworthy thing that I have changed from the SDK's tutorial is that I don't use Application.Run but instead have a Application.doEvents in the mainloop. Here's some of my code: ---------------------------------------------------------------- CREATING:
public dxSimpleMouse(System.Windows.Forms.Form owner)
  {
   OwnerForm=owner;
   OwnerForm.Activated += new System.EventHandler(this.RestoreMouse);
   OwnerForm.Deactivate += new
System.EventHandler(this.PutMouseOnHold);
   OwnerForm.Focus();
   gotFocus=true;

   maxX=OwnerForm.Size.Width;
   maxY=OwnerForm.Size.Height;

   MouseThread = new Thread(new ThreadStart(this.MouseCheckerThread));
   MouseThread.Start();

   eventFire = new AutoResetEvent(false);
            
   MouseDevice = new
Microsoft.DirectX.DirectInput.Device(SystemGuid.Mouse);
   MouseDevice.SetCooperativeLevel(OwnerForm,
CooperativeLevelFlags.Exclusive | CooperativeLevelFlags.Foreground);
   MouseDevice.SetEventNotification(eventFire);
   MouseDevice.Properties.AxisModeAbsolute=false;
   MouseDevice.Acquire(); 
  }
----------------------------------------------------------- THE POLLING THREAD + CALLED METHOD(error occurs here on BeginInvoke row)
  
public void MouseCheckerThread()
  {
    while(OwnerForm.Created)                
   {
    eventFire.WaitOne(-1, false);
    
     MouseDevice.Poll();
     OwnerForm.BeginInvoke(new UIDelegate(UpdateMouse));
    
   }
  }

  public void UpdateMouse()
  {
   if (gotFocus==true)  
   {
    MouseState CurrentState = new MouseState();
    CurrentState = MouseDevice.CurrentMouseState;
   
    X+=CurrentState.X;
    Y+=CurrentState.Y;
    if (X<0) X=0;
    if (Y<0) Y=0;
    if (X>maxX-1) X=maxX-1;
    if (Y>maxY-1) Y=maxY-1;
   }
  }
---------------------------------------------------------- THE ACTIVATED AND DEACTIVE EVENT HANDLERS
  
public void RestoreMouse (object sender, System.EventArgs e)
  {
   gotFocus=true;
   MouseDevice.SetEventNotification(eventFire);
   if (null != MouseDevice)
   {
    try{MouseDevice.Acquire();}
    catch{}
   }
  }

  public void PutMouseOnHold (object sender, System.EventArgs e)
  {
   gotFocus=false;
   MouseDevice.SetEventNotification(null);
   MouseDevice.Unacquire();
   
  }
---------------------------------------------------------------- THE MAIN LOOP IN ANOTHER APP USING THE LIB ABOVE:
  [MTAThread]
  static void Main() 
  {
   TestForm bobo = new TestForm();

   dxSimpleMouse m = new dxSimpleMouse(bobo);;
   while (bobo.Created)
   {
    ShowMouseAt( m.X, m.Y );
    Application.DoEvents();
   } 
  }
So. If anyone would have any ideas to what I am doing wrong I'd love to hear about it. Thanks in advance /Apoztel [edited by - Apoztel on November 16, 2003 7:18:59 AM]

Share this post


Link to post
Share on other sites
I'm overwhelmed at the responses the non dear daddy approach gave. nice you could take your time to explain how not funny I am using AP, but not to help me. Anyways, here is how i solved it at last. There is still something left thats a bit too active after a while unfocused, the mouse gets sligtly jerky. No errors though, and you should probably use NonExclusive if you plan on being out of focus a lot anyway.


public class dxSimpleMouse
{
private Microsoft.DirectX.DirectInput.Device MouseDevice = null;
private Thread MouseThread = null;
private AutoResetEvent eventFire = null;
public int X;
public int Y;
delegate void UIDelegate();
public System.Windows.Forms.Form OwnerForm;
private int maxX;
private int maxY;

public dxSimpleMouse(System.Windows.Forms.Form owner)
{
OwnerForm=owner;
OwnerForm.Activated += new System.EventHandler(this.RestoreMouse);
OwnerForm.Deactivate += new System.EventHandler(this.PutMouseOnHold);

maxX=OwnerForm.Size.Width;
maxY=OwnerForm.Size.Height;

MouseThread = new Thread(new ThreadStart(this.MouseCheckerThread));
MouseThread.Start();

eventFire = new AutoResetEvent(false);

MouseDevice = new Microsoft.DirectX.DirectInput.Device(SystemGuid.Mouse);
MouseDevice.SetCooperativeLevel(OwnerForm, CooperativeLevelFlags.Exclusive | CooperativeLevelFlags.Foreground);
MouseDevice.SetEventNotification(eventFire);
MouseDevice.Properties.AxisModeAbsolute=false;
MouseDevice.Acquire();
}

public void Dispose()
{
MouseThread.Abort();
eventFire.Set();
}


public void MouseCheckerThread()
{
while(OwnerForm.Created)
{
eventFire.WaitOne(-1, false);

try
{
MouseDevice.Poll();
OwnerForm.BeginInvoke(new UIDelegate(UpdateMouse));
}
catch (InputLostException)
{
continue;
}
}
}

public void UpdateMouse()
{
MouseState CurrentState = new MouseState();
CurrentState = MouseDevice.CurrentMouseState;

X+=CurrentState.X;
Y+=CurrentState.Y;
if (X<0) X=0;
if (Y<0) Y=0;
if (X>maxX-1) X=maxX-1;
if (Y>maxY-1) Y=maxY-1;
}

public void RestoreMouse (object sender, System.EventArgs e)
{
MouseThread = new Thread(new ThreadStart(this.MouseCheckerThread));
MouseThread.Start();
if (null != MouseDevice)
{
try{MouseDevice.Acquire();}
catch{}
}
}

public void PutMouseOnHold (object sender, System.EventArgs e)
{
MouseThread.Abort();
MouseDevice.Unacquire();
}

}


[/Code]


/Apoztel


[edited by - Apoztel on November 19, 2003 5:41:56 AM]

Share this post


Link to post
Share on other sites