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:
public class LoopCommands
static public void Loop()
DocumentCollection dm =
Editor ed =
// Create and add our message filter
MyMessageFilter filter = new MyMessageFilter();
// Start the loop
// Check for user input events
// Check whether the filter has set the flag
if (filter.bCanceled == true)
ed.WriteMessage("\nInside while loop...");
// We're done - remove the message 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 false to let other messages through