views:

52

answers:

2

ANSWER: There isn't a natively managed equivalent for this method. However, a good example managed code API can be found over at pinvoke.net.

Hi all

I have an application that accepts a flag for 'trace mode'. Trace mode turns on a form containing a text box. The text box displays output via a custom TraceListener object. If there is a -t present on the command-line, the trace window will be opened from within its own low-priority thread. It's handy for consultants that are trying to diagnose the application when something goes wrong.

A few consultants have requested that pressing some obscure key combination during startup should turn on trace mode so they don't have to go to the command line to activate it every time. It's a reasonable request.

I don't want to give them a button or menu item for this because a lot of the critical information that the consultants will care about is displayed to Trace at startup before the main form is created as the various components are instantiated and initialized.

I thought it should have been simple enough to detect the current keyboard state in .NET - but it seems that everywhere I look, the advice is to use [DllImport("user32.dll", EntryPoint = "GetKeyboardState", SetLastError = true)] as the method to detect what's going on.

That's all well and good - I'm comfortable with that. However, as a general rule of thumb I try to make sure I use native .NET managed code for Windows functions before I go trying to roll my own.

Is there a native .NET method or equivalent to user32.dll's GetKeyboardState?

+1  A: 

Control.ModiferKeys is a static property of Control which, if any, modifier keys are currently pressed. I'm not aware of anything to get general keyboard state, seems like most code P/Invoke with either GetKeyboardState or GetKeyState for checking specific keys.

Donnie
Thanks Donnie. Control.ModifierKeys will give me the control/shift/alt keys, but not any letter key that may or may not be pressed. I think you're right about having to p/invoke GetKeyboardState or GetKeyState. Confirms my suspicions - thanks.
Daniel Schealler
A: 

Are you sure that PreviewKeyDownEventArgs does not have what you need? If it does, then you can use the PreviewKeyDown event.

Another option might be accelerator keys. A Windows API function can use an accelerator table in the application's resources to map keyboard sequences to commands, where a command is the same thing that a menu item does; you know, a WM_COMMAND message. I know it is easy to do in MFC using C++ but when I tried to find the C# way to do it, I got lost. If you can figure out how to do accelerator keys using C# then it could be a flexible solution.

Sam Hobbs
Hi Sam. I don't think that PreviewKeyDown will be able to help me out here. I'm trying to get the keyboard state from inside Program.Main, before any forms have been instantiated. To my knowledge, I don't actually have a PreviewKeyDown event to bind against. Advice on accelerator keys is appreciated, but I think I'll go with p/invoking user32.dll - which I already know how to do - as opposed to wrestling with accelerator keys, which is a new concept to me.
Daniel Schealler
The GetKeyboardState documentation says that the "status changes as a thread removes keyboard messages from its message queue". Note that it sasy that the keyboard message must be removed and it says message queue. GetKeyboardState requires that a message queue exists. Your comment "before any forms have been instantiated" is another way of saying that there is not yet a message queue, but if GetKeyboardState works, then there is a message queue. If GetKeyboardState works, then there is also a message loop that is reading keyboard messages.
Sam Hobbs
Wew! I did not know there was a limit to the size of comments here.So the documented way to do what you want to do is to do it in a message handler.You can use Spy++ to determine what processes the keyboard message that you get the GetKeyboardState from.
Sam Hobbs