September 2014

Sun Mon Tue Wed Thu Fri Sat
  1 2 3 4 5 6
7 8 9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30        








« Using the COM interface for AutoCAD objects from .NET | Main | Replacing AutoCAD's OPEN command using .NET »

February 28, 2007

Allowing users to escape from long operations in AutoCAD .NET

The bulk of this code was donated by Virupaksha Aithal, a member of our DevTech team in India.

It's fairly common for developers to want to check for user input from time to time during long operations, especially to see whether the user wants to cancel the current activity. In VB you'd use DoEvents() to enable messages to be processed by the application's message loop and in ObjectARX you'd use acedUsrBrk().

So how to do this in .NET?

The answer is to use a message filter. This allows us to check on user-input events... we still call DoEvents, as with previous versions of VB, which allows user input events (such as keystrokes) to flow into our message filter function. We can then detect the events we care about, and filter them out, if necessary.

This C# code filters all keystrokes during a loop operation, and allows the application to respond in its own way to the user hitting the Escape key:

using Autodesk.AutoCAD.ApplicationServices;

using Autodesk.AutoCAD.EditorInput;

using Autodesk.AutoCAD.Runtime;

using System;

using System.Windows.Forms;


namespace LoopTest

{

  public class LoopCommands

  {

    [CommandMethod("loop")]

    static public void Loop()

    {

      DocumentCollection dm =

        Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager;

      Editor ed =

        dm.MdiActiveDocument.Editor;


      // Create and add our message filter

      MyMessageFilter filter = new MyMessageFilter();

      System.Windows.Forms.Application.AddMessageFilter(filter);


      // Start the loop

      while (true)

      {

        // Check for user input events

        System.Windows.Forms.Application.DoEvents();


        // Check whether the filter has set the flag

        if (filter.bCanceled == true)

        {

          ed.WriteMessage("\nLoop cancelled.");

          break;

        }

        ed.WriteMessage("\nInside while loop...");

      }

      // We're done - remove the message filter

      System.Windows.Forms.Application.RemoveMessageFilter(filter);

    }


    // Our message filter class


    public class MyMessageFilter : IMessageFilter

    {

      public const int WM_KEYDOWN = 0x0100;


      public bool bCanceled = false;


      public bool PreFilterMessage(ref Message m)

      {

        if (m.Msg == WM_KEYDOWN)

        {

          // Check for the Escape keypress

          Keys kc = (Keys)(int)m.WParam & Keys.KeyCode;

          if (m.Msg == WM_KEYDOWN && kc == Keys.Escape)

          {

            bCanceled = true;

          }

          // Return true to filter all keypresses

          return true;

        }

        // Return false to let other messages through

        return false;

      }

    }

  }

}

TrackBack

TrackBack URL for this entry:
http://www.typepad.com/services/trackback/6a00d83452464869e200d8351e2c6c69e2

Listed below are links to weblogs that reference Allowing users to escape from long operations in AutoCAD .NET:

blog comments powered by Disqus

Feed/Share

10 Random Posts