title: Hold down a key for a while and couldn't remove pending key down/key press messages after releasing the key
body: <p>I have a question about <code>PeekMessage</code> method usage in <strong>C#</strong>.</p>
  
  <p>Here is my case: I hold down a key (Enter or F8, for example) for a while. While the key is held down, the code keeps doing something. </p>
  
  <p>I was trying to create the code to stop doing those things immediately after releasing the key, but I had some difficulty.</p>
  
  <p>What I did was to overwrite <code>ProcessKeyPreview</code> method to figure out if a key was held down for a while to generate multiple key down and/or key press events. If that's the case, once the key is released, I was using  <code>PeekMessage</code> to remove the following pending messages and hoped it would stop processing those accumulated key down/key press messages, but it didn't work.</p>
  
  <ol>
  <li>WM_CHAR</li>
  <li>WM_SYSCHAR</li>
  <li>WM_IME_CHAR</li>
  <li>WM_KEYDOWN</li>
  <li>WM_SYSKEYDOWN </li>
  </ol>
  
  <p>Any help would be appreciated.</p>
  
  <p>Some code snippet is listed as follows:</p>
  
  <pre><code>[DllImport("user32.dll", CharSet = CharSet.Auto)]
  private static extern bool PeekMessage([In, Out] ref MSG msg, HandleRef hwnd, int msgMin, int msgMax, int remove);
  
  //----------------------------------------------
  // Define the PeekMessage API call
  //----------------------------------------------
  [Serializable, StructLayout(LayoutKind.Sequential)]
  private struct MSG
  {
      public IntPtr hwnd;
      public int message;
      public IntPtr wParam;
      public IntPtr lParam;
      public int time;
      public int pt_x;
      public int pt_y;
  }
  
  /// &lt;summary&gt; 
  /// Trap any keypress before child controls get hold of them
  /// &lt;/summary&gt;
  /// &lt;param name="m"&gt;Windows message&lt;/param&gt;
  /// &lt;returns&gt;True if the keypress is handled&lt;/returns&gt;
  protected override bool ProcessKeyPreview(ref Message m)
  {
      const int WM_KEYDOWN = 0x100;
      const int WM_KEYUP = 0x101;
      const int WM_CHAR = 0x102;
      const int WM_SYSKEYDOWN = 0x104;
      const int WM_SYSKEYUP = 0x105;
      const int WM_SYSCHAR = 0x106;
      const int WM_IME_CHAR = 0x286;
  
      KeyEventArgs e = null;
  
      if ((m.Msg != WM_CHAR) &amp;&amp; (m.Msg != WM_SYSCHAR) &amp;&amp; (m.Msg != WM_IME_CHAR))
      {
          e = new KeyEventArgs(((Keys)((int)((long)m.WParam))) | ModifierKeys);
  
          if ((m.Msg == WM_KEYUP) || (m.Msg == WM_SYSKEYUP))
          {
              //If the key is held down for a while to generate multiple WM_KEYDOWN messages
              if (mRepeatCount &gt; 1)
              {                        
                  e.Handled = true;
                  e.SuppressKeyPress = true;
              }
  
              mRepeatCount = 0;
          }
  
          // Remove any WM_CHAR type messages if supresskeypress is true.
          if (e.SuppressKeyPress)
          {
              this.RemovePendingMessages(WM_KEYDOWN, WM_KEYDOWN);
              this.RemovePendingMessages(WM_SYSKEYDOWN, WM_SYSKEYDOWN);
              this.RemovePendingMessages(WM_CHAR, WM_CHAR);
              this.RemovePendingMessages(WM_SYSCHAR, WM_SYSCHAR);
              this.RemovePendingMessages(WM_IME_CHAR, WM_IME_CHAR);
          }
  
          if (e.Handled)
          {
              return true;
          }
      }
  
      return base.ProcessKeyPreview(ref m);
  }
  
  private void RemovePendingMessages(int msgMin, int msgMax)
  {
      if (!this.IsDisposed)
      {
          MSG msg = new MSG();
          IntPtr handle = this.Handle;
          while (PeekMessage(ref msg, new HandleRef(this, handle), msgMin, msgMax, 1))
          {
          }
      }
  }
  </code></pre>