Catch Windows KeyPress Events?
-
is there anyway to get my C# winforms app to handle a keyboard keypress event in windows, whether or not the form is the active window? i want to be able to detect caps lock, num lock and scroll lock presses without out polling the keyboard state
-
is there anyway to get my C# winforms app to handle a keyboard keypress event in windows, whether or not the form is the active window? i want to be able to detect caps lock, num lock and scroll lock presses without out polling the keyboard state
You would not be able to do this at any form level. I would imagine you'd have to write a service and have it hook into the OS (if NT even allows that type of hook) ___________________ Forgoing antagonism and separation, one enters into the harmonious oneness of all things. Lao Tzu
-
is there anyway to get my C# winforms app to handle a keyboard keypress event in windows, whether or not the form is the active window? i want to be able to detect caps lock, num lock and scroll lock presses without out polling the keyboard state
There are basically three types of hooks you can use. One is that you override
WndProc
and handle all messages sent to your form whether its active or not. In the case of keyboard events, your application must be active to recieve them (except when using the other two hooks to be mentioned...). You can use anIMessageFilter
along withApplication.AddMessageFilter
andApplication.RemoveMessageFilter
to add a message filter that applies to all windows (that includes controls) in your application so that you can handle keyboard events (or any other events) no matter which form is active. Finally, there's system hooks. These should be used as little as often as they hook every message of a certain type in the OS. Inefficient or buggy code can degrade performance of the OS and all applications seriously, or even cause crashes if you don't handle errors correctly. You can find more information about using system hooks in C# by reading Using Hooks from C#[^]. In any case, you'll be using Windows messaging and catching notification messages likeNM_KEYDOWN
, which you can find the constants for in winuser.h in the Platform SDK. Experience with Windows messaging will be helpful.Microsoft MVP, Visual C# My Articles
-
There are basically three types of hooks you can use. One is that you override
WndProc
and handle all messages sent to your form whether its active or not. In the case of keyboard events, your application must be active to recieve them (except when using the other two hooks to be mentioned...). You can use anIMessageFilter
along withApplication.AddMessageFilter
andApplication.RemoveMessageFilter
to add a message filter that applies to all windows (that includes controls) in your application so that you can handle keyboard events (or any other events) no matter which form is active. Finally, there's system hooks. These should be used as little as often as they hook every message of a certain type in the OS. Inefficient or buggy code can degrade performance of the OS and all applications seriously, or even cause crashes if you don't handle errors correctly. You can find more information about using system hooks in C# by reading Using Hooks from C#[^]. In any case, you'll be using Windows messaging and catching notification messages likeNM_KEYDOWN
, which you can find the constants for in winuser.h in the Platform SDK. Experience with Windows messaging will be helpful.Microsoft MVP, Visual C# My Articles
many thanks i think i will try the IMessageFilter interface method. for now i guess i will leave it polling every few seconds
-
many thanks i think i will try the IMessageFilter interface method. for now i guess i will leave it polling every few seconds
Verdant123 wrote: for now i guess i will leave it polling every few seconds :confused: Why are you polling? Every message posted to the message queue for your application is filtered through the
IMessageFilter
implementation you added to your application usingApplication.AddMessageFilter
. There's no polling necessary. For example, lets say I want to write a message to the console every time a key is pressed anywhere in my application:public class KeyboardFilter : IMessageFilter
{
public bool PreFilterMessage(ref Message m)
{
if (m.Msg == 0x0100) // WM_KEYDOWN
Console.WriteLine("Key down: " + m.WParam.ToString());
return false;
}
}Microsoft MVP, Visual C# My Articles
-
Verdant123 wrote: for now i guess i will leave it polling every few seconds :confused: Why are you polling? Every message posted to the message queue for your application is filtered through the
IMessageFilter
implementation you added to your application usingApplication.AddMessageFilter
. There's no polling necessary. For example, lets say I want to write a message to the console every time a key is pressed anywhere in my application:public class KeyboardFilter : IMessageFilter
{
public bool PreFilterMessage(ref Message m)
{
if (m.Msg == 0x0100) // WM_KEYDOWN
Console.WriteLine("Key down: " + m.WParam.ToString());
return false;
}
}Microsoft MVP, Visual C# My Articles
after re-reading the thread i guess i need a system hook... the application need to catch changes to the cap/num/scroll locks from anywhere within windows currently i poll the keyboard state every few seconds... to verify their values