Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Ignoring queued mouse events

I have an application written in C# targeting .NET Compact Framework 3.5, running on Windows CE. From time to time, operations lasting for a second or so are being performed on the UI thread. I currently set the Cursor.Current property to indicate that the application is busy, but this does not prevent mouse events from eager users to queue up. This sometimes leads to unintended clicks.

What is the best way to ignore queued mouse messages on the .NET Compact Framework platform? Sadly, the code has to run on the UI thread.

like image 235
Tormod Fjeldskår Avatar asked Mar 23 '09 08:03

Tormod Fjeldskår


1 Answers

Disabling the controls won't help you, as I've found from my POS application that the users can sneak in another click in about 50ms, especially when using a touch screen that is not calibrated.

One of the problems this creates is when producing an invoice, you can't have a duplicate click produce another invoice, just because there's a 50ms delay before clearing the current invoice.

In cases like this, I use a pattern similar to this:

    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
    }

In case you need to reenable the screen, do this:

            this.Enabled = true;

            ApprovalLockCount = 0;

            DialogResult = DialogResult.None;
like image 157
Miki Watts Avatar answered Sep 22 '22 20:09

Miki Watts