C# 按住一把钥匙一段时间,无法';t释放钥匙后,删除挂起的按键/按键信息
我对C# 按住一把钥匙一段时间,无法';t释放钥匙后,删除挂起的按键/按键信息,c#,.net,C#,.net,我对PeekMessage在C中的方法用法有一个问题 这是我的情况:我按住一个键(例如回车键或F8键)一段时间。当按下键时,代码会继续执行某些操作 我试图创建代码,在释放密钥后立即停止执行这些操作,但遇到了一些困难 我所做的是覆盖ProcessKeyPreview方法,以确定一个键是否被按住一段时间以生成多个键按下和/或按键事件。如果是这样的话,一旦按键被释放,我就用PeekMessage删除了以下待处理的消息,并希望它能停止处理那些累积下来的按键/按键信息,但它不起作用 WM_CHAR WM_
PeekMessage
在C中的方法用法有一个问题
这是我的情况:我按住一个键(例如回车键或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))
{
}
}
}
[DllImport(“user32.dll”,CharSet=CharSet.Auto)]
私有静态外部布尔消息([In,Out]ref MSG MSG,HandleRef hwnd,int msgMin,int msgMax,int remove);
//----------------------------------------------
//定义PeekMessageAPI调用
//----------------------------------------------
[可序列化,StructLayout(LayoutKind.Sequential)]
私有结构消息
{
公共IntPtr hwnd;
公共信息;
公共IntPtr wParam;
公共IntPtr LPRAM;
公共整数时间;
公共int pt_x;
公共国际部;
}
///
///在子控件抓住任何按键之前,将其捕获
///
///Windows消息
///如果已处理按键,则为True
受保护的覆盖布尔ProcessKeyPreview(参考消息m)
{
常量int WM_KEYDOWN=0x100;
常量int WM_KEYUP=0x101;
常量int WM_CHAR=0x102;
常量int WM_SYSKEYDOWN=0x104;
常量int WM_SYSKEYUP=0x105;
常量int WM_SYSCHAR=0x106;
常量int WM_IME_CHAR=0x286;
KeyEventArgs e=null;
if((m.Msg!=WM\u CHAR)&&&(m.Msg!=WM\u SYSCHAR)&&&(m.Msg!=WM\u IME\u CHAR))
{
e=新的KeyEventArgs(((键)((int)((长)m.WParam)))| ModifierKeys);
if((m.Msg==WM_-KEYUP)| |(m.Msg==WM_-SYSKEYUP))
{
//如果按住键一段时间以生成多个WM_KEYDOWN消息
如果(mRepeatCount>1)
{
e、 已处理=正确;
e、 SuppressKeyPress=true;
}
mRepeatCount=0;
}
//如果SupersKeyPress为true,则删除任何WM_字符类型的消息。
如果(如按下按键)
{
这是一个.RemovePendingMessages(WM_KEYDOWN,WM_KEYDOWN);
这个.RemovePendingMessages(WM_SYSKEYDOWN,WM_SYSKEYDOWN);
这个.removependengmessages(WM_CHAR,WM_CHAR);
这个.removependengmessages(WM_SYSCHAR,WM_SYSCHAR);
这个.removependengmessages(WM_IME_CHAR,WM_IME_CHAR);
}
如果(如已处理)
{
返回true;
}
}
返回base.ProcessKeyPreview(参考m);
}
私有void RemovePendingMessages(int-msgMin,int-msgMax)
{
如果(!this.IsDisposed)
{
MSG=new MSG();
IntPtr handle=this.handle;
while(peek消息(ref msg,new HandleRef(this,handle),msgMin,msgMax,1))
{
}
}
}
没有代码就很难理解问题。请发布您到目前为止所做的事情。如果您只需要收到键盘事件的通知,Peek消息似乎非常复杂。既然您使用的是C#,为什么不简单地使用Control.KeyUp和Control KeyDown呢?控件太多了,在所有的keydup和KeyDown事件处理程序中添加逻辑是不可行的。这就是为什么我选择在stackoverflow中的其他一些线程上根据建议使用ProcessKeyPreview。但是您不必为每个控件使用单独的事件处理程序-如果需要,您可以为每个控件使用相同的事件处理程序。明白了吗。但我需要改变的是现有的代码,而不是全新的代码。我不得不用这种方法修改许多文件,这是不可行的。