mm3Mountain Meadow 3

Technical reference

Notes On Keyboard glitches

Read-only textboxes eat certain control characters

In particular Ctrl-L and some other Ctrl-key combinations fire neither that read-only text box's KeyDown event nor the MainForm's KeyDown event.

All the fixes below this one are preserved for historical perspective, as we tried several fixes for this problem over the years.

Currently the only fix we use is to put a message filter in the main form that looks for keydown messages (WM_KEYDOWN) and filters out those Ctrl-character combinations that are used in our navigation bar.

The code comes from http://forums.microsoft.com/MSDN/ShowPost.aspx?PostID=2333282&SiteID=1.

Code Blockpublic partial class Form16 : Form,IMessageFilter 


    {



        public Form16()



        {



            InitializeComponent();



        }



 



        private const int WM_KEYDOWN = 0x100;



 



        #region IMessageFilter Members



 



        public bool PreFilterMessage(ref Message m)



        {



            if (m.Msg == WM_KEYDOWN )



            {



                if ((int)m.WParam == (int)Keys.L && Control.ModifierKeys == Keys.Control)



                {



                    MessageBox.Show("Ctrl+L entered!");



                    return true;



                }



            }



            return false;



        }



 



        #endregion



 



        protected override void OnActivated(EventArgs e)



        {



            Application.AddMessageFilter(this);



            base.OnActivated(e);



        }



 



        protected override void OnDeactivate(EventArgs e)



        {



            Application.RemoveMessageFilter(this);



            base.OnDeactivate(e);



        }



    }



The fixes below are no longer used:

A "key-up"handler fix:

Mountain Meadow 3 at one time had a routine called when connecting a ProgramPiece to the collection of ProgramPieces which looks for read-only text boxes. If found, it added a PreviewKeyDown event handler (called PreviewKeyDownHanndler() in MainForm.cs) which saves the KeyData temporarily. If MainForm's KeyDown handler handles that keystroke that temorary KeyData is reset to null. If not, MainForm's KeyUp handler finds it and acts on it.

Note KeyUp handlers sometimes catch ctrl-<char> combinations by itself, but it depends on the order in which the user releases the two keys.

A "save text" fix:

One reasonable workaround: Do not make textboxes "ReadOnly." Instead, make them act read-only by preventing text changes explicitly:
1. Save text on entry. Make an event handler for Enter which says <textBoxNam>.Tag = <textBoxName>.Text;
2. Restore it if changes are attempted: Make an event handler for TextChanged which says <textBoxName>Text = (string)<textBoxName>.Tag;
3. Consider indicating it is read-only by setting the background color to "Control" instead of "Window".

A "SuppressKeyPress" fix:

Make a KeyDown handler for the read-only text box that sets e.SuppressKeyPress = true, whether or not you set e.Handled = true;

Drawback: Can't cut and past using Ctrl-Insert and Shift-Insert, and mouse CAN change the text.

my notes:

since the 2005 version of .NET the textbox control eats certain Ctrl-character combinations including Ctrl-L for some reason. The form's KeyDown and KeyPress handlers miss the Ctrl-L and the form's KeyUp only gets it if the letter is released before the Ctrl is. One workaround I've found is to make the textbox ReadOnly=false but make it act like read only by setting a KeyDown handler for the text box that sets e.SuppressKeyPress = true (seems to work whether or not e.Handled = true), OR ELSE save the textbox's text value on entering the text box( can save it in textBox.Tag) and set the Text property back to that text on TextChanged() event. The second way is more complicated but allows keyboard pasting of text and also prevents mouse from deleting the text. Another workaround is to make the textbox's PreviewKeyDown event capture the Ctrl-L. Unfortunately the form's PreviewKeyDown event doesn't seem to ever fire. I suppose we could query each ProgramPiece to see if its usercontrol has any read-only text boxes and add PreviewKeyDown handlers for them, but that might slow down page changes. Or we could ask the PreviewKeyDown event to call a handler in MM3StateClass or ProgramPieceBase or somewhere that processes it... Or we could ask the textbox's PreviewKeyDown evnet to save PreviewKeyDownEventArgs in a local field or the textbox's tag or the form's local field or TAG (this.ParentForm.Tag) and ask the form's KeyUp event handler to check for such data every time it is called. I even tried putting the Ctrl-L in a shortcut for the form's menu strip. The read-only textbox even keeps that shortcut from working!