Câu trả lời được chấp nhận sử dụng keybd_event
không được dùng nữa. API chính thức hiện là SendInput
. Ngoài ra còn có một wrapper tốt đẹp cho nó tại http://inputsimulator.codeplex.com.
Không có trường hợp nào ở trên, hoàn toàn phục vụ cho trường hợp "giữ phím". Điều này là do việc giữ chìa khóa sẽ tạo ra nhiều thông báo WM_KEYDOWN
, theo sau là một thông báo WM_KEYUP
duy nhất khi được phát hành (bạn có thể kiểm tra điều này bằng Spy ++).
Tần suất của các tin nhắn WM_KEYDOWN
phụ thuộc vào phần cứng, cài đặt BIOS và một vài cài đặt Windows: KeyboardDelay
và KeyboardSpeed
. Sau này có thể truy cập từ Windows Forms (SystemInformation.KeyboardDelay
, SystemInformation.KeyboardSpeed
).
Sử dụng thư viện Trình mô phỏng đầu vào nói trên, tôi đã triển khai phương pháp giữ phím bắt chước hành vi thực tế. Đó là await/async
đã sẵn sàng và hỗ trợ hủy.
static Task SimulateKeyHold(VirtualKeyCode key, int holdDurationMs,
int repeatDelayMs, int repeatRateMs, CancellationToken token)
{
var tcs = new TaskCompletionSource<object>();
var ctr = new CancellationTokenRegistration();
var startCount = Environment.TickCount;
Timer timer = null;
timer = new Timer(s =>
{
lock (timer)
{
if (Environment.TickCount - startCount <= holdDurationMs)
InputSimulator.SimulateKeyDown(key);
else if (startCount != -1)
{
startCount = -1;
timer.Dispose();
ctr.Dispose();
InputSimulator.SimulateKeyUp(key);
tcs.TrySetResult(null);
}
}
});
timer.Change(repeatDelayMs, repeatRateMs);
if (token.CanBeCanceled)
ctr = token.Register(() =>
{
timer.Dispose();
tcs.TrySetCanceled();
});
return tcs.Task;
}
Nguồn
2012-03-01 02:01:10
Tốt! Làm việc tốt với tôi. Cảm ơn nhiều ! – Larry