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

Leave a Reply