views:

827

answers:

4

I want to be able to intercept (and do arbitrary processing on) auto-repeating key presses on Windows. I'd like to know how keyboard auto-repeat is implemented so that I know what options I have. i.e. can I intercept at the:

  • application,
  • device driver and/or
  • hardware level

?

Update: It looks like auto-repeat is (poorly?) generated at the hardware level and then overridden by device drivers (see here).

A: 

I suggest that you might want to edit your question... your actual question is "How to suppress auto-repeat on Windows in ${yourLangauge}"...

To which my response is, I haven't got a clue, I've only ever done it in assembler (MASM 80286)... and even then I found a solution on a BBS (does anyone remember them) and just used it. From memory, the intercept has to be done at the device-driver level.

The implementation of autorepeat ($100 says it's assembler) problably won't shed any light on supressing it... that and Microsoft plays those cards very close to it's chest.

Cheers. Keith.

EDIT: I've just thought... techniques may now differ between versions of windows and the plethora of various devices... Oh goodie!

corlettk
No, I really do want to know how it's implemented. The bit about suppression is for background info. My suspicion was that it might be at the hardware level (which, if true, gives me more options for interception).
Matthew Murdoch
A: 

Sounds likes this is "Not programming related", however. Go to "Accessibility Options" in control panel. Select "Settings" under "Filter Keys" group, in here, you can switch off repeating keys for that user on that machine.

Hope this is what your looking for.

P.S. Above instructions given for Windows XP.

Binary Worrier
I want to be able to suppress this programmatically but I'm happy that I'll be able to work out how to do this once I understand how/where auto-repeat is implemented.
Matthew Murdoch
A: 

From what information I can find, the autorepeat implemented in the keyboard device driver.

This forum topic explains how to enable FilterKeys programatically (on Windows XP or later). The sample code (which I haven't tested) is as follows:

using System.Runtime.InteropServices; 

public partial class Form1 : Form 
{ 
int SPI_GETFILTERKEYS = 0x32; 
int SPI_SETFILTERKEYS = 0x33; 
int FKF_FILTERKEYSON = 1; 

[DllImport("user32.dll")] 
static extern bool SystemParametersInfo(int uiAction, int uiParam, 
ref FilterKeys pvParam, uint fwinIni); 

public struct FilterKeys 
{ 
public UInt16 cbSize; 
public int dwFlags; 
public int iWaitMSec; 
public int iDelayMSec; 
public int iRepeatMSec; 
public int iBounceMSec; 
} 

FilterKeys oldfilterkeys = new FilterKeys(); 
private void Form1_Load(object sender, EventArgs e) 
{ 
oldfilterkeys.cbSize = 
(UInt16)Marshal.SizeOf(typeof(FilterKeys)); 
bool result = SystemParametersInfo(SPI_GETFILTERKEYS, 
Marshal.SizeOf(typeof(FilterKeys)), ref oldfilterkeys, 0); 
FilterKeys newfilterkeys = oldfilterkeys; 
newfilterkeys.dwFlags |= FKF_FILTERKEYSON; 
newfilterkeys.iWaitMSec = 0; 
newfilterkeys.iBounceMSec = 0; 
newfilterkeys.iDelayMSec = 0; 
newfilterkeys.iDelayMSec = 0; 
// turn on the FilterKeys feature to disable keyboard 
repeat 
result = SystemParametersInfo(SPI_SETFILTERKEYS, 
Marshal.SizeOf(typeof(FilterKeys)), ref newfilterkeys, 0); 
} 

void Form1_FormClosed(object sender, FormClosedEventArgs e) 
{ 
// restore the original Filter Keys setting 
SystemParametersInfo(SPI_SETFILTERKEYS, 
Marshal.SizeOf(typeof(FilterKeys)), ref oldfilterkeys, 0); 
} 
}
Patrick McDonald
Thank you. Do you know if the implementation of auto-repeat is at the driver or hardware level?
Matthew Murdoch
+2  A: 

To modify or filter behavior, you can intercept keys using a hook:

SetWindowsHookEx using WH_KEYBOARD

The hook procedure receives, among others, the repeat count (due to holding down the key)

Note that the low level keyboard hook (WH_KEYBOARD_LL) does not receive the repeat count.

If all your windows are created in the same trhead, you can use a thread-specific hook, and avoid moving the hook procedure to a DLL.


I dimly remember that repeat counts are generated by the keyboard itself and the LL hook sends repeated keydown events - I may be mistaken, though. Under DOS, the key repeat rate and time that was set in BIOS or through a BIOS call did return to default values when a DIN or PS/2 keyboard was unplugged and replugged. I am not sure WHY you need to know exactly.

peterchen