The Form has a DataGridView (it shows one line) and a WebBrowser .

The Form on the Event keyDown has a handler that is triggered by pressing F2 , which writes the word to a specific cell. The same handler is bound to a DataGridView .

 private: System::Void CSV_WViewForm_KeyDown( System::Object^ sender, System::Windows::Forms::KeyEventArgs^ e) { if (e->KeyCode == Keys::F2) /*Do something*/; } 

It is necessary that pressing F2 works always and immediately (the first time). For this, I used the property KeyPreview = false; (I tried to set it to true - it did not help).

 protected: virtual bool ProcessCmdKey(Message% msg, Keys keyData) override { if (keyData == Keys::F2) { this->dataGridView1->Focus(); return Form::ProcessCmdKey(msg, keyData); } return Form::ProcessCmdKey(msg, keyData); } 

But when Focus is in WebBrowser , F2 does not always work (sometimes you have to press F2 twice). How to win it?

Windows Forms project (C ++, Visual Studio 2015)

    2 answers 2

    If you are intercepting user input at the form level, then process it there. A simple test project with equivalent C # code showed the following:

    1. If the element is in focus, everything works as it should.
    2. If the element is out of focus and we switch focus to another element at the form level, then the event of the pressed key goes to the element that was in focus while pressing the key, which is logical in principle. Hence the need for a second key press, because The first press fulfills only the transfer of focus and leaves the previous owner of the focus.

    What to do?

    Transfer all key processing that is intercepted at the form level into the interception code (in ProcessCmdKey ), in order not to clutter the code, do this in the form of calling separate methods for each intercepted key.

    You can change your code like this:

     virtual bool ProcessCmdKey(Message% msg, Keys keyData) override { if (keyData == Keys::F2) { this->dataGridView1->Focus(); //do somthing for F2-key return true; } return Form::ProcessCmdKey(msg, keyData); } 

    or via switch - case if there are many keys. And do not forget to remove unnecessary handlers or exclude from them the handling of keys intercepted at the form level.

    • Thank you, I did. Everything is working. - Andrey Simurzin

    You can do the following.

    Add to the menu form (if it is not already) - MenuStrip . If the menu itself is not needed in the application, then hide it: Visible = false . Add an item with any name to the menu, assign a click handler to it (it performs the actions you need) and, most importantly, set the ShortcutKeys property to the desired value: the F2 button.

    Now pressing F2 will work in any case, whatever component is in focus.

    Checked in C #.