我对 C#中的PeekMessage
方法用法有疑问。
这是我的情况:我按住一个键(例如Enter或F8)一段时间。当按键被按下时,代码会继续执行某些操作。
我试图创建代码以在释放密钥后立即停止执行这些操作,但我遇到了一些困难。
我所做的是覆盖ProcessKeyPreview
方法,以确定按键是否被暂停一段时间以生成多个按键按下和/或按键事件。如果是这种情况,一旦密钥被释放,我就会使用PeekMessage
删除以下待处理的消息,并希望它会停止处理那些累积的按键/按键消息,但它不起作用。
任何帮助都将不胜感激。
部分代码段如下所示:
[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;
}
/// <summary>
/// Trap any keypress before child controls get hold of them
/// </summary>
/// <param name="m">Windows message</param>
/// <returns>True if the keypress is handled</returns>
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) && (m.Msg != WM_SYSCHAR) && (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 > 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))
{
}
}
}