Allowing users to escape from long operations in AutoCAD .NET

By Stephen Preston

In a long operation, you may want to give your user the option to hit escape to cancel the operation and regain control. Here is some code from a DevNote originally written for AutoCAD 2007-2009, which still works today.

[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;
  }
}

Update 7/30/12:

And here is the VB.NET translation (mostly through automatic translation using DeveloperFusion):

 

Public Shared Sub qqq()
      Dim dm As DocumentCollection =
        Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager
      Dim ed As Editor = dm.MdiActiveDocument.Editor
      ' Create and add our message filter
      Dim filter As 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 Then
          ed.WriteMessage(vbLf & "Loop cancelled.")
          Exit While
        End If
        ed.WriteMessage(vbLf & "Inside while loop...")
      End While
      ' We're done - remove the message filter
      System.Windows.Forms.Application.RemoveMessageFilter(filter)
    End Sub
    ' Our message filter class
    Public Class MyMessageFilter
      Implements IMessageFilter
      Public Const WM_KEYDOWN As Integer = &H100
      Public bCanceled As Boolean = False
 
      Public Function PreFilterMessage1(
      ByRef m As System.Windows.Forms.Message) As Boolean _
      Implements System.Windows.Forms.IMessageFilter.PreFilterMessage
        If m.Msg = WM_KEYDOWN Then
          ' Check for the Escape keypress
          Dim kc As Keys = DirectCast(CInt(m.WParam), Keys) And Keys.KeyCode
          If m.Msg = WM_KEYDOWN AndAlso kc = Keys.Escape Then
            bCanceled = True
          End If
          ' Return true to filter all keypresses
          Return True
        End If
        ' Return false to let other messages through
        Return False
      End Function
    End Class

Comments

3 responses to “Allowing users to escape from long operations in AutoCAD .NET”

  1. Hello Stephen
    I don’t think the code works in 2012/ 64 bit.
    I had to change it to vb of course. Could you please take a look what is wrong ? Thanks
    Public Class LoopCommands
    <CommandMethod(“loop”)> _
    Public Shared Sub Loop
    Dim dm As DocumentCollection = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager
    Dim ed As Editor = dm.MdiActiveDocument.Editor
    ‘ Create and add our message filter
    Dim filter As New MyMessageFilter()
    System.Windows.Forms.Application.AddMessageFilter(CType(filter, System.Windows.Forms.IMessageFilter))
    ‘ 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 Then
    ed.WriteMessage(vbLf & “Loop cancelled.”)
    Exit While
    End If
    ed.WriteMessage(vbLf & “Inside while loop…”)
    End While
    ‘ We’re done – remove the message filter
    System.Windows.Forms.Application.RemoveMessageFilter(CType(filter, System.Windows.Forms.IMessageFilter))
    End Sub
    ‘ Our message filter class
    Public Class MyMessageFilter
    Implements IMessageFilter
    Public Const WM_KEYDOWN As Integer = &H100
    Public bCanceled As Boolean = False
    Public Function PreFilterMessage(ByRef m As Message) As Boolean
    If m.Msg = WM_KEYDOWN Then
    ‘ Check for the Escape keypress
    Dim kc As Keys = DirectCast(CInt(m.WParam), Keys) And Keys.KeyCode
    If m.Msg = WM_KEYDOWN AndAlso kc = Keys.Escape Then
    bCanceled = True
    End If
    ‘ Return true to filter all keypresses
    Return True
    End If
    ‘ Return false to let other messages through
    Return False
    End Function
    Public Function PreFilterMessage1(ByRef m As System.Windows.Forms.Message) As Boolean Implements System.Windows.Forms.IMessageFilter.PreFilterMessage
    End Function
    End Class
    End Class

  2. I’ve updated the post with a VB.NET translation. VB.NET and C# versions work fine for me on AutoCAD 2012 64-bit.

  3. hello, I’ve been using the same principle in trying to block number input in ACAD, but for unknown reason, messagefilter keeps letting first 2 keys “leak through” to the application.
    I’m suspecting it could have something to do with paletteset/acad focus(since I’m using a button to enable/disable the feature), but I’ve exhausted all other options but to ask you for a tip. (been at autodesk forum and stackoverflow).
    http://forums.autodesk.com/t5/net/paletteset-keepfocus-and-keyboard-override/m-p/6069569#M47738
    http://stackoverflow.com/questions/35977925/c-sharp-message-filter-keeps-leaks-first-2-keys-pressed

Leave a Reply

Discover more from Autodesk Developer Blog

Subscribe now to keep reading and get access to the full archive.

Continue reading