Creating a user definable hotkey (.NET1.1/VS2k3/WinForms)

R

Rune Jacobsen

Hi all,

I have some often-performed tasks in my applications that I want users
to be able to specify hotkeys for. However, I don't want to hard code
these hotkeys, as sooner or later some other app is bound to use the
same thing, causing end user frustration. So I want the end user to be
able to specify the hot key to use for task X in the configuration window.

Now receiving and handling the hotkey is no problem. I do that easily
enough trough the magic of the Win32 RegisterHotKey() function and
friends, and then overriding my WndProc handler checking for an m.Msg of
WM_HOTKEY (0x0312).

However, I also want the part of the application where the user defines
what hotkey to use to be friendly. There are of course several
approaches to this. One is the GUI one with a checkbox for Ctrl, Alt and
Shift (optionally the Win button), and then a dropdown with the keys.
However, I like the one that is in the start menu properties a lot
better, for many reasons. (To check it out, go to Start -> (All)
Programs -> Accessories, and right click Calculator, then choose
Properties). The procedure there is as simple as can be - activate the
"Shortcut key" field, press your hotkey, and voila - instant hotkey
definition.

I have struggled quite a bit with figuring out which is the correct way
to handle this. I've tried doing it via events on the textbox itself
(handling KeyPress, KeyDown, KeyUp and then reading ModifierKeys or just
the passed data), and I've tried to do it overriding the forms own
ProcessDialogKey. The latter seems to make me have to check against
every possible key that has been pressed, while the former makes me jump
trough a lot of loops to get what I want (require a modifier key, react
properly when keys are let go of in every possible order etc).

Thus I am turning to the experts; What way would you go about to handle
this? Or would you go in a completely different direction, possibly
meeting and getting to know new and interesting people along the way?

My requirements are simple; I want my users to easily specify the
hotkeys to use for a number of common operations. I want to require the
use of modifier keys (any number of modifiers higher than 0), as this
will be a system wide hotkey. And if possible (practical), I would
really like it if my users could use the Win key as a modifier in
additional to Ctrl/Alt/Shift. Also, since I have international users,
the solution should be open for any character that is not a modifier to
be used as "the" key).

If anyone could help shed some light on The Right Thing here, I would
highly appreciate it!

Thanks and best regards,

Rune Jacobsen
 
R

Rune Jacobsen

Hi again,

Since my first post got no responses, I've been moving on to try to
figure this one out myself. I'm trying to use a combination of KeyDown
and ProcessDialogKey to read a users' wanted hotkey combination. The
reason I am doing it this way is that I want my users to have the option
of using the Windows key as a modifier in addition to Shift, Alt and Ctrl.

The strange thing, however, is that there seems to be a bug in my logic
when using ProcessDialogKey to get the modifiers pressed. The actual key
is handled in the KeyDown event, but I am using an override of
ProcessDialogKey for the window to set modifier flags so that I can
capture something precise when the user does his thing. What I am doing
in the override is to check the keyData for Keys.Control, Keys.Alt,
Keys.Shift and Keys.LWin. All the others work as expected, but LWin
seems to be always pressed. The simple way I check for this is something
along these lines:

if( (keyData & Keys.Control) != 0 )
modifiers |= Keys.Control;

etc. - but the LWin one always hits.

To test if this is me going mental or something else, I made a very
simple WinForm app in VS2003. One form only, added two textboxes to it,
and inserted the following code for the override:

protected override bool ProcessDialogKey(Keys keyData)
{
textBox1.Text = keyData.ToString();
if( (keyData & Keys.LWin) != 0 )
textBox2.Text = "LWin has been pressed!";
else
textBox2.Text = "";
return base.ProcessDialogKey (keyData);
}

As you will hopefully agree, textBox1 simply shows you which keys are
being pressed right now, while textBox2 should only contain text when
the left Windows key is pressed.

Well, try it. When I try it here (English WinXP Sp2, .NET1.1, VS2003),
the only key that DOESN'T cause LWin to seem pressed, is the space bar!
Every other key on the keyboard results in "LWin has been pressed!"
appearing in textBox2.

Could someone please explain this to me, as the size of the headache it
is causing is not proportional to the fun of trying to figure it out..

Thanks for any help!

Best regards,

Rune Jacobsen
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top