Link to home
Start Free TrialLog in
Avatar of lynx2sw1
lynx2sw1

asked on

How do I capture the keyboard cursor up/down/left/right event?

How do I capture thekeyboard  cursor up/down/keft/right events?  THese can be from the number pad or the little cursor buttons nexxt to it.  The closest I have come is turning on num lock and capturing the NumPad8/2/4/6 events.  But I want to leave num lock off and I really want to capture the 4 cursor keys on my keyboard.

My application is a c# windows form.
Avatar of drichards
drichards

Do you want all events or just the ones from a particular control?  And how are you capturing the keys now?
Avatar of lynx2sw1

ASKER


I am capturing some events now by handling the KeyDown event in the main form.  But it seems only to work for the main keyboard, not the cursor, and not all of the numeric keypad.  This seems to be working fine with the other events.  When the other controls get the focus I dont want their events anyway.
Strange, it works for all keys on my keyboard including the cursor keys on the keypad.  It reports key values of Left, Right, etc. which are part of the System.Windows.Forms.Keys enumeration.  Do you have some fancy keyboard that needs a driver or something?
Its an IBM Net Vista.  I didn't install a driver the last time I installed Win2K on it.
I tried downloading the program to my IBM T30 laptop which has no numeric key pad.


When I hit any key excpet the cursor keys.  Even "Browser Forward".

Do I have to set some property differenty?

Here is the code setting up my handlers.  I tried it with and without the Key Preview with the same result.
                  //
                  // MainForm
                  //
                  this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);
                  this.ClientSize = new System.Drawing.Size(1016, 730);
                  this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon")));
                  this.Menu = this.mainMenu;
                  this.Name = "MainForm";
                  this.Text = "itcouldbe";
                  this.KeyPreview=true;
                  this.KeyDown += new System.Windows.Forms.KeyEventHandler(this.MainForm_KeyDown);
                  this.KeyPress+= new KeyPressEventHandler(MainForm_KeyPress);

But isince it works for you I did what I should have done in the first place.  I wrote a simple program form scratch.

This one *does* capture my cursor keys.  So I have to figure out what strange thing in my real application is capturing my cursor keys but nothing else.
I looked in my misbehaving application.  It had one control that handles key down events (not cursor) and I commented this out.  It didn't fix my problem.  
I added a text box and a button to my new clean application.

Now I don't capture the cursor keys anymore.  

The reason seems to be that clickng the cursor key changes the focus to another control.  So the event is getting handled in that way.

So how can I get around that?  Or can I?  Do I just have to glue little arrows to soome keys that do work and call them my cursors for this app?
You'll need to find a real .NET GUI expert for that one.  Once you put controls on the form (other than labels, it seems), the controls handle the key events and the form does not get them any more because the form itself does not get the focus.  There must be a way to bubble the events up to the main form, but I don't know what it is.
OK, turns out to be really easy.  I just set the KeyPreview property of teh form to true after the call to InitializeComponents in the for constructor and I get all the key events again.
Oops, you are correct - no cursor keys.  Everything but that.
Have you check MS knowledge base for bug reports of this?  Seems like a bug.
I am getting there!

I added an implementation of the interface IMessageFilter and it is capturing events when the cursors or anytthing else are triggered.

ASKER CERTIFIED SOLUTION
Avatar of drichards
drichards

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
     
I added an implementation of IMessage Filter

to my application I did this:
                        Application.AddMessageFilter(new MessageFilterer(this));

and hereis the application.

public class MessageFilterer: IMessageFilter
      {
            private MainForm _mainForm;

            public KeyBoardHandler(MainForm mainForm)
            {
                  _mainForm=mainForm;
            }

            public bool PreFilterMessage(ref Message m)
            {

                  if(m.Msg==256)//WM_KEYDOWN
                  {
                        
                        switch(m.WParam.ToInt32())
                        {
                              case 38:      //VK_UP                                                               break;
                                                                 }


                  }

                  return false;
            }
Thanks d. Sorry for the wild ride.  I am sure I wouldnt have gotten there without someone to bounce ideas off of.  You ought to get some points for that since the aim was to get this darn thing working so I can go forward.
Looks good.  I'll have to remember that.

And here's the story with the event handler.  It turns out that if the form decides to handle the key itself, it does not generate an event at all.  So, when you put controls on the form, the form handles KeyDown on the cursor keys to effect navigation.  You therefore do not get events for these keys because the form does not generate them any more.  If the focus is in a control from which you cannot navigate with the cursor keys (like the textbox) you DO get the events.  So although it seems strange, it is really quite logical in a Microsoft sort of way.

So if you absolutely need the KeyDown events, the message filter is the way to go.

Whew...  who'd have thunk it would be that hard.