bonskijr

Hi,
It seems that the following key combo are not raising any key events:
CTRL+L, CTRL+E, CTRL+R, CTRL+J

Testing it using the following codes:

        public Form1()

        {

            InitializeComponent();

 

            this.KeyDown+=new KeyEventHandler(this.OnFormKeyDown);

            this.fileToolStripMenuItem.Click+=new EventHandler(this.FileMenuClicked);

 

        }

 

        private void FileMenuClicked(object sender, EventArgs e)

        {

            Console.WriteLine("Menu pressed");

        }

 

        private void OnFormKeyDown(object sender, KeyEventArgs e)

        {

            this.txtKeyCode.Text = e.KeyCode.ToString();

            this.txtKeyData.Text = e.KeyData.ToString();

            this.txtKeyModifiers.Text = e.Modifiers.ToString();

            this.txtKeyValue.Text = e.KeyValue.ToString();

 

            if (e.Control && ((e.KeyCode == Keys.E)

                              || (e.KeyCode == Keys.L)

                              || (e.KeyCode == Keys.R)

                              || (e.KeyCode == Keys.J)

 

                ))

            {

                // of course it won't go here.

                Console.WriteLine("either CTRL+J,E,R,L were pressed");

            }

        }

 



Reveals that the while other key combinations are displayed in the KeyData property, the above combo displays(in the KeyData textbox) "ControlKey, Control", meaning there was no data being returned to the KeyEventArgs. It's basically the same as pressing the CTRL key alone.

Btw: I tried also the creating a menuStripItem and one of the shortcut of the above keys and still didn't raised the Clicked event.

It this a bug or are those keys reserved internally

Thanks, hopefully I've clarified my query.



Re: Windows Forms General The following CTRL+keys doesn't get the correct KeyEventArgs during KeyDown events

bonskijr

It appears that those key combinations only gets their proper KeyEventArgs during OnKeyUp event., weird.

Add'l: And it seems this only happens in the KeyBoard EventHandler of the Windows Forms, if the focused control is a textbox the KeyDown eventhandler is being raised in the following order:

Form.OnKeyDown
TextBox.OnKeyDown

Any comments from the Windows Forms team





Re: Windows Forms General The following CTRL+keys doesn't get the correct KeyEventArgs during KeyDown events

Dennis Dietrich - MSFT

Keyboard events are sent to the window (i.e. a form or its active control) that has the focus. So, unless you change the configuration in your InitializeComponent() method the default behavior is that the first TextBox on your Form will receive the focus and thus also receive the keyboard input. If you want to handle all input in the form's KeyDown event you need to activate the key preview for that form.

public partial class Form1 : Form

{

public Form1()

{

InitializeComponent();

this.KeyDown += new KeyEventHandler(this.Form1_KeyDown);

this.KeyPreview = true;

}

private void Form1_KeyDown(object sender, KeyEventArgs e)

{

this.txtKeyCode.Text = e.KeyCode.ToString();

this.txtKeyData.Text = e.KeyData.ToString();

this.txtKeyModifiers.Text = e.Modifiers.ToString();

this.txtKeyValue.Text = e.KeyValue.ToString();

if (e.Control && ((e.KeyCode == Keys.E) || (e.KeyCode == Keys.L) || (e.KeyCode == Keys.R) || (e.KeyCode == Keys.J)))

Console.WriteLine("either CTRL+J,E,R,L were pressed");

}

}

Best regards
Dennis Dietrich
Developer Division
Microsoft Corporation

This posting is provided "AS IS" with no warranties, and confers no rights.





Re: Windows Forms General The following CTRL+keys doesn't get the correct KeyEventArgs during KeyDown events

bonskijr

Hi Dennis,

I did set KeyPreview property of the Form to True, that's why I was able to hook up with the form's KeyDown event. This only occurs if the current Active Control is not Readonly, if the active control(eg. TextBox) isn't read only the EventArgs captures the above keystrokes.

The wierdness however is that the given the following situations:
1.) I have set the Forms KeyPreview to True
2.) I have a short cut key mapped with either of the ff(CTRL+L, CTRL+J, CTRL+E, CTRL+R)
3.) I have a single TextBox on a form, the ReadOnly property is set to True
4.) I subscribed to the Form's KeyDown event

#2 won't be captured, other key combinations will be. Subscribing to the Form's KeyUp event will capture #2 but won't capture the rest. I mean what's so special with those key combinations that it requires them to be capture "only" during Form's KeyUp event.

hope that clarifies it more..

Thanks







Re: Windows Forms General The following CTRL+keys doesn't get the correct KeyEventArgs during KeyDown events

efbiaiinzinz

heh, try overriding the ProcessCmdKey

protected override bool ProcessCmdKey( ref Message msg, Keys keyData ) {
MessageBox.Show( "cmdkey: "+keyData.ToString() );
return base.ProcessCmdKey( ref msg, keyData );
}

no need to set keypreview to true or anything, this function basically captures all keypresses and you can use it in either a form or in a control or in a usercontrol or wherever you can possibly override it

Return true when your code catched and processed the keypress, otherwise return base.ProcessCmdKey no to break anything ;)

I wonder why the microsoft person didn't know that :P





Re: Windows Forms General The following CTRL+keys doesn't get the correct KeyEventArgs during KeyDown events

Dennis Dietrich - MSFT

Yeah, it does. I was finally able to reproduce the issue. I don't know what exactly causes this behavior; but I do know that setting TextBoxBase.ReadOnly to false actually triggers a couple of things to happen under the hood. You could possibly work around this by tapping directly into the applications message queue whenever the form that is supposed to handle these shortcut keys is the active window.

public partial class Form1 : Form, IMessageFilter

{

private const int WM_KEYDOWN = 0x100;

public Form1()

{

InitializeComponent();

}

bool IMessageFilter.PreFilterMessage(ref Message m)

{

if (m.Msg == WM_KEYDOWN &&

(int)m.WParam == (int)Keys.L &&

Control.ModifierKeys == Keys.Control)

{

Console.WriteLine(DateTime.Now +

" - Ctrl + L pressed [PreFilterMessage(ref Message)]");

return true;

}

return false;

}

private void Form1_Activated(object sender, EventArgs e)

{

Application.AddMessageFilter(this);

}

private void Form1_Deactivate(object sender, EventArgs e)

{

Application.RemoveMessageFilter(this);

}

}

Best regards
Dennis Dietrich
Developer Division
Microsoft Corporation

This posting is provided "AS IS" with no warranties, and confers no rights.





Re: Windows Forms General The following CTRL+keys doesn't get the correct KeyEventArgs during KeyDown events

bonskijr

efbiaiinzinz wrote:

heh, try overriding the ProcessCmdKey

protected override bool ProcessCmdKey( ref Message msg, Keys keyData ) {
MessageBox.Show( "cmdkey: "+keyData.ToString() );
return base.ProcessCmdKey( ref msg, keyData );
}

no need to set keypreview to true or anything, this function basically captures all keypresses and you can use it in either a form or in a control or in a usercontrol or wherever you can possibly override it

Return true when your code catched and processed the keypress, otherwise return base.ProcessCmdKey no to break anything ;)

I wonder why the microsoft person didn't know that :P



hi efbiaiizinz,

thanks I tried that also, unfortunately it works only if the ActiveControl is not Read-Only, if it is then the same behavior occurs.






Re: Windows Forms General The following CTRL+keys doesn't get the correct KeyEventArgs during KeyDown events

bonskijr

Hi Dennis,

Thanks for the work around, although a little bit hacky but it works.




Re: Windows Forms General The following CTRL+keys doesn't get the correct KeyEventArgs during KeyDown events

JeroGrav

I notice that your code makes reference to a menu. In my experience, the main reason your form doesn't get a key press is because that key combination is used as a shortcut to a particular menu item. eg if you implement the default edit menu, Ctrl-C, ctrl-X etc are shortcuts to the edit menu items.

Having said that, I wouldn't expect you to get the keypress on the textbox either if this was the case.

I thought I'd mention it though, just in case.






Re: Windows Forms General The following CTRL+keys doesn't get the correct KeyEventArgs during KeyDown events

bonskijr

Hi JeroGrav,

The menu is another proof of concept, in cases where a short-cut were either one the mentioned combinations, it won't fire off if the ActiveControl is read-only. Ok if it was having the same behavior with all combinations but only on those said combo.








Re: Windows Forms General The following CTRL+keys doesn't get the correct KeyEventArgs during KeyDown events

Mr.Burns

Me too facing the same problem,

The IMessageFilter Implementation doesn't seems to be working.

Again I just want to make sure:

#1. Create a Windows Form project and make the KeyPreview property of the form to "True"

#2. Add a TextBox and set the ReadOnly property to "True"

#3. Now capture the Key_Down Event of the form

Alas! the event is not getting fired.

#4. Implement the IMessageFilter interface as suggested above by dennis, Still the Key_Down event is not getting fired.

Logically, when we set the KeyPreview, what we expect is that the key strokes are handled by the form then it gets passed to the controls on the form, am i correct .

The problem is why the Key_down event is not getting fired, but the Key_up event works fine, is this a bug .

I tried subclassing the TextBox, then override the methods ProcessCmdKey/KeyDown, and tried the ProcessCmdKey of the Form, but found nothing works.

When we set the textbox as readonly somewhere this Key combinations are getting suppressed, regardless of what we do.

In my application Ctrl+R is a global shortcut, I can't go for someother shortcut,can somebody please help me out .





Re: Windows Forms General The following CTRL+keys doesn't get the correct KeyEventArgs during KeyDown events

May Ji

I have worked around the problem by handling the readonlyTextBox's PreviewKeyDown and then forward the keyData to ProcessCmdKey of its parent which is the form. For example:

private void textBox_PreviewKeyDown(object sender, PreviewKeyDownEventArgs e)

{

Message m = new Message();

m.Msg = 0x100; //WM_KEYDOWN

switch (e.KeyData)

{

case Keys.Control | Keys.E:

Debug.WriteLine("TextBox received Ctrl + E - forward to its parent");

this.ProcessCmdKey(ref m, e.KeyData);

break;

case Keys.Control | Keys.L:

this.ProcessCmdKey(ref m, e.KeyData);

Debug.WriteLine("TextBox received Ctrl + L - forward to its parent");

break;

case Keys.Control | Keys.R:

Debug.WriteLine("TextBox received Ctrl + R - forward to its parent");

this.ProcessCmdKey(ref m, e.KeyData);

break;

default:

break;

}

}