2009-03-23 12 views
8

Tengo una aplicación escrita en C# targeting .NET Compact Framework 3.5, que se ejecuta en Windows CE. De vez en cuando, las operaciones que duran alrededor de un segundo se realizan en el hilo de la interfaz de usuario. Actualmente configuro la propiedad Cursor.Current para indicar que la aplicación está ocupada, pero esto no evita que los eventos del mouse de los usuarios ansiosos hagan cola. Esto a veces conduce a clics involuntarios.Ignorar eventos de mouse en cola

¿Cuál es la mejor manera de ignorar los mensajes del mouse en cola en la plataforma .NET Compact Framework? Lamentablemente, el código tiene que ejecutarse en el hilo de la interfaz de usuario.

Respuesta

8

Desactivar los controles no te ayudará, ya que he encontrado desde mi aplicación POS que los usuarios pueden colarse en otro clic en unos 50 ms, especialmente cuando se utiliza una pantalla táctil que no está calibrada.

Uno de los problemas que esto crea es cuando se produce una factura, no se puede hacer que un clic duplicado produzca otra factura, simplemente porque hay un retraso de 50 ms antes de borrar la factura actual.

En casos como este, yo uso un patrón similar a esto:

public static void ClearMouseClickQueue() 
    { 
     Message message; 
     while (PeekMessage(out message,IntPtr.Zero, (uint) MessageCodes.WM_MOUSEFIRST,(uint) MessageCodes.WM_MOUSELAST,1) != 0) 
     {  
     } 
    } 

    private object approvalLockObject = new object(); 

    private void btnApproveTransaction_Click(object sender, EventArgs e) 
    { 
     ApproveTransactionAndLockForm(); 
    } 

    private void ApproveTransactionAndLockForm() 
    { 
     lock (approvalLockObject) 
     { 
      if (ApprovalLockCount == 0) 
      { 
       ApprovalLockCount++; 
       ApproveTransaction(); 
      } 
      else 
      { 
       CloseAndRetry(); 
      } 
     } 
    } 

    private void ApproveTransaction() 
    { 
     ClearMouseClickQueue(); 

     this.Enabled = false; 

     Logger.LogInfo("Before approve transaction"); 

     MouseHelper.SetCursorToWaitCursor(); 

     ... validate invoice and print 
    } 

En caso de que necesite volver a activar la pantalla, haga lo siguiente:

  this.Enabled = true; 

      ApprovalLockCount = 0; 

      DialogResult = DialogResult.None; 
+1

Para completar, he enumerado la definiciones necesarias para la p/invoke en http://pastebin.ca/1369082 –

0

Creo que la mejor solución es evitar que sucedan los eventos. Puede hacerlo deshabilitando todos los controles y volviéndolos a habilitar, cuando termine la operación prolongada.

Cuestiones relacionadas