Trapping keystrokes in .NET forms...

Posted by MBeynon on 14-Mar-2013 04:14

Hi,

I have a Progress .NET form with an embedded ABL window. The ABL window responds to keystrokes such as F3,F4 and F5.

However, this only occurs if the user is focused in a fill-in in the ABL window. If the user has focus in the .NET form then the ABL window does not respond to the keystrokes.

My question is, how do I trap keystrokes when focus is in the .NET form so as I can pass then onto the ABL window?

Many thanks,

Mark.

All Replies

Posted by Peter van Dam on 14-Mar-2013 04:20

Hi Mark,

I was just looking into this as well and I found that you have to set Form.KeyPreview first:

http://msdn.microsoft.com/en-us/library/system.windows.forms.form.keypreview.aspx

Then your KeyDown triggers will fire.

HTH

-peter

Posted by MBeynon on 14-Mar-2013 04:30

Thanks, that's just what I was looking for.

Mark.

Posted by Peter van Dam on 14-Mar-2013 04:45

Now my challenge (and maybe also yours...) is how to catch CTRL-R.

You would think that is easy, but not in .NET!

A collegue claims you need this to achieve it:

http://support.microsoft.com/kb/318804

If anyone has a better idea I would love to hear about it!

-peter

Posted by Stefan Marquardt on 14-Mar-2013 05:57

Q&D with VS2005 C#:

namespace

WindowsApplication1

{

public partial class Form1 : Form

{

  public Form1()

  {

   InitializeComponent();

  }

  private void Form1_KeyPress(object sender, KeyPressEventArgs e)

  {

   char c;

   c = e.KeyChar;

   if (Char.IsControl(c) && c == (char)18)

   {

    MessageBox.Show("Identfied CTRL-R");

   }

  }

}

}

private

void InitializeComponent()

{

this.SuspendLayout();

//

// Form1

//

this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);

this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;

this.ClientSize = new System.Drawing.Size(284, 262);

this.KeyPreview = true;

this.Name = "Form1";

this.Text = "Form1";

this.KeyPress += new System.Windows.Forms.KeyPressEventHandler(this.Form1_KeyPress);

this.ResumeLayout(false);

}

Posted by Peter van Dam on 14-Mar-2013 06:07

I have struggled with this in 11.1 and I am finding that no event fires for CTRL-R.

Events fire for CTRL.

Events fire for R.

But no event fires for CTRL-R.

I am beginning to suspect this is a bug.

Can you try this code in OpenEdge?

-peter

Posted by Stefan Marquardt on 14-Mar-2013 06:15

pdam schrieb:

I have struggled with this in 11.1 and I am finding that no event fires for CTRL-R.

Events fire for CTRL.

Events fire for R.

Keypress has no event for CTRL key (standalone), are you really using keypress and not keydown/up?

Posted by Peter van Dam on 14-Mar-2013 06:45

marquardt wrote:

pdam schrieb:

I have struggled with this in 11.1 and I am finding that no event fires for CTRL-R.

Events fire for CTRL.

Events fire for R.

Keypress has no event for CTRL key (standalone), are you really using keypress and not keydown/up?

IndeedI am finding that KeyPress does not fire when you press CTRL-R.

Have you tested otherwise in OpenEdge?

Posted by MBeynon on 14-Mar-2013 06:51

I can trap CTRL+R in Openedge 10.2B.05 using keydown

Posted by Peter van Dam on 14-Mar-2013 07:46

Can you share the code? Then I will test it and submit a bug if it does not work in 11.1.

Posted by MBeynon on 14-Mar-2013 07:58

Sure :-)


    /*------------------------------------------------------------------------------
            Purpose:                                                                       
            Notes:                                                                       
    ------------------------------------------------------------------------------*/
    @VisualDesigner.
    METHOD PRIVATE VOID BaseForm_KeyDown( INPUT sender AS System.Object, INPUT e AS System.Windows.Forms.KeyEventArgs ):
       

        IF e:CONTROL
           AND e:KEYCODE:ToString() = "R" THEN
           MESSAGE "Hello world! VIEW-AS ALERT-BOX.


        RETURN.

    END METHOD.

Posted by Peter van Dam on 14-Mar-2013 08:09

Thanks, this sheds some more light on my problem.

In my application this code does not fire, but when I try it in a separate window it works.

What could be the cause of that? There is a similar ON CRTL-R ANYWHERE trigger in my embedded GUI code, but I don't care which one fires as long as one of them does. However there seems to be some conflict that results in none fireing at all.

We will need to dig deeper.

-peter

Posted by Peter van Dam on 14-Mar-2013 08:24

BTW I also noticed that this does not work when a .NET input field has focus.

So we are still a long way from ON CTRL-R ANYWHERE....

Posted by jmls on 14-Mar-2013 08:31

Have anyone stopped to think that if this is such a problem in .net,

then it is not common behavior, and perhaps there is a "better way" of

achieving the same goal ?

Posted by Peter van Dam on 14-Mar-2013 08:37

Of course - and in order to convince the customer I need to have solid ammunition.

Posted by MBeynon on 14-Mar-2013 08:38

On a slightly different tack, does anyone know how to prevent ALT+F4 from closing my form?

ALT+F4 is use by the form's embedded ABL window (something I can't change) and I'd like the users to not have to re-open the form everytime ALT-F4 closes it!

Thanks,

Mark.

Posted by Admin on 14-Mar-2013 08:41

For certain keyboard events in the GUI for .NET Environment we have created IMessageFilter instances in C#. That's pretty much an EVERYWHERE event handler in .NET. But it should be written in C# for performance reasons.

http://msdn.microsoft.com/en-us//library/system.windows.forms.imessagefilter.aspx

One use case, is to redirect the F10 key, so that it does not always cause the Ribbon to start it's keyboard more, but allows us to continue to handle F10 as an application key.

Posted by Peter Judge on 14-Mar-2013 08:41

This is from memory: you could look at the Form_Closing event handler; I believe it has information about how the Close event was triggered. If that is ALT-F4 then e:Cancel = true?

-- peter

Posted by jmls on 14-Mar-2013 08:51

wire up ALT-F4 to a electric currrent ...

Posted by Admin on 14-Mar-2013 09:01

This is from memory: you could look at the Form_Closing event handler; I believe it has information about how the Close event was triggered. If that is ALT-F4 then e:Cancel = true?

 

The CloseReason makes no difference between ALT-F4 and the X on the window boarder. Both is UserClosing.

Makes sense.

Posted by MBeynon on 14-Mar-2013 09:09

Did it like this:

    /*------------------------------------------------------------------------------
            Purpose:                                                                       
            Notes:                                                                       
    ------------------------------------------------------------------------------*/
    @VisualDesigner.
    METHOD PRIVATE VOID BaseForm_KeyDown( INPUT sender AS System.Object, INPUT e AS System.Windows.Forms.KeyEventArgs ):
    SuppressKeyStroke("ALT-F4", sender, e).       
    END METHOD.


    METHOD PROTECTED VOID SuppressKeyStroke(INPUT lvcKeyStroke AS CHARACTER,
                                            INPUT sender AS System.Object,
                                            INPUT e AS System.Windows.Forms.KeyEventArgs ):
       
    DEFINE VARIABLE lvcModifier    AS CHARACTER NO-UNDO.
    DEFINE VARIABLE lvcKeyCode     AS CHARACTER NO-UNDO.
    DEFINE VARIABLE lvcEventString AS CHARACTER NO-UNDO.
 
    ASSIGN
      lvcKeyCode  = e:KEYCODE:ToString()
      lvcModifier = IF e:Control THEN
                    "CONTROL"
                  ELSE IF e:Shift THEN
                    "SHIFT"
                  ELSE IF e:Alt THEN
                    "ALT"
                  ELSE "".           
 
    lvcEventString = (IF lvcModifier <> "" THEN lvcModifier + "-" + lvcKeyCode ELSE lvcKeyCode).
   
    IF lvcEventString = lvcKeyStroke THEN
      e:SuppressKeyPress = TRUE.

    END METHOD.

This thread is closed