Search code examples
winformson-screen-keyboard

Use custom on-screen keyboard form with OpenFileDialog and SaveFileDialog


We have a custom on-screen keyboard (OSK) form as part of our .NET Windows Forms Application. This keyboard is useful to enter data into a DataGridView and some other textboxes. We want to be able to use it to enter a file name into an OpenFileDialog or SaveFileDialog.

However, when either Dialog shows up, the form containing the OSK stops responding to input. I tried creating a new Form that is used as the OSK's owner. I use the new form and call keyboard.Show(owner). This still doesn't prevent the keyboard from being unable to be used while an OpenFileDialog or SaveFileDialog is in their ShowDialog method.

How can we use an on-screen keyboard form on top of an OpenFileDialog or SaveFileDialog without having the keyboard be hosted in a separate process?


Solution

  • Well, running the OSK window in another process is a fine idea. You get it for free by running osk.exe, provided by Windows. You could technically run it another STA thread but that's a fairly advanced technique, too many ways where the SystemEvents class can seriously ruin your life.

    But you can solve the problem with a sliver of code, you just need to re-enable the OSK window right after the dialog is displayed. Elegantly done with the BeginInvoke() method:

        private void OpenButton_Click(object sender, EventArgs e) {
            this.BeginInvoke(new Action(() => EnableWindow(osk.Handle, true)));
            if (openFileDialog1.ShowDialog(this) == DialogResult.OK) {
                // etc...
            }
        }
    
        [System.Runtime.InteropServices.DllImport("user32.dll")]
        private static extern bool EnableWindow(IntPtr hWnd, bool enable);
    

    With the assumption that the osk variable stores a reference to your OSK form.