C#PeekMessage
でのメソッドの使用法について質問があります。
これが私の場合です。キー (たとえば、Enter または F8) をしばらく押し続けます。キーが押されている間、コードは何かを実行し続けます。
キーを離した直後にそれらを停止するコードを作成しようとしていましたが、少し苦労しました。
私がしたことはProcessKeyPreview
、複数のキーダウンおよび/またはキープレスイベントを生成するためにキーがしばらく押されたかどうかを確認するメソッドを上書きすることでした。その場合、キーが PeekMessage
離されると、次の保留中のメッセージを削除するために使用していましたが、それらの蓄積されたキーダウン/キープレスメッセージの処理を停止することを望んでいましたが、機能しませんでした.
- WM_CHAR
- WM_SYSCHAR
- WM_IME_CHAR
- WM_KEYDOWN
- WM_SYSKEYDOWN
どんな助けでも大歓迎です。
一部のコード スニペットを以下に示します。
[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))
{
}
}
}