WPF Winforms Interop eating keystroke

251 views Asked by At

I create a winform project with a single form with 4 textboxes and a button.

On button click, I perform the following:

Window1 w = new Window1();
ElementHost.EnableModelessKeyboardInterop(w);
w.Show();

Where window 1 is a Wpf window. Window1 has a single button on it and when that button is clicked the following occurs:

System.Windows.MessageBox.Show("HelloWOrld");

When you run the application the WinForm Form pops ups. If you hit tab it cycles through the 4 textboxes no problem. Then Click the button to open the WPF window. Click that button and popup the messagebox. Leave them open and then go back to the WinForm form you can no longer tab through the fields but you can type other characters. It appears as though the textboxes get the keystrokes but the form doesn't get them. I also get a system beep as though the model was getting the keystroke.

EDIT 9/9/2014 3:44PM

Hans responded in the comments and was correct. I tried describing a simpler case that would be easier for other people to reproduce that gave use the same symptoms. Our actual problem is that we have created a window base class that supports modal to parent capabilities. Here is the relevant code for our BaseWindow

public class BaseWindow: Window
{
    [DllImport("user32.dll")]
    static extern bool EnableWindow(IntPtr hWnd, bool bEnable);

    [DllImport("user32.dll")]
    [return: MarshalAs(UnmanagedType.Bool)]
    static extern bool SetForegroundWindow(IntPtr hWnd);

public void ShowModalToParent(Window frmParent, Action<bool?> callback = null)
{
    IntPtr myHandle = (new System.Windows.Interop.WindowInteropHelper(this)).Handle;
    EnableWindow(myHandle,         
    SetForegroundWindow(myHandle);
    this.Closing += Window_Closing;

    ShowInTaskbar = false;
    Owner = frmParent; // Keep on top of parent
    ClosedCallBack += callback ?? (p => { _modalDialogResult = p; });
    var parentHandle = (new System.Windows.Interop.WindowInteropHelper(frmParent)).Handle;
        EnableWindow(parentHandle, false); // Prevent events for parent
        new ShowAndWaitHelper(this).ShowAndWait();
}

internal class ShowAndWaitHelper
{
    private readonly Window _window;
    private DispatcherFrame _dispatcherFrame;
    internal ShowAndWaitHelper(Window window)
    {
        if (window == null)
        {
            throw new ArgumentNullException("panel");
        }
        this._window = window;
    }
    internal void ShowAndWait()
    {
        if (this._dispatcherFrame != null)
        {
            throw new InvalidOperationException("Cannot call ShowAndWait while waiting for a previous call to ShowAndWait to return.");
        }
        this._window.Closed += new EventHandler(this.OnPanelClosed);
        _window.Show();
        this._dispatcherFrame = new DispatcherFrame();
        Dispatcher.PushFrame(this._dispatcherFrame);
    }

    private void OnPanelClosed(object source, EventArgs eventArgs)
    {
        if (this._dispatcherFrame == null)
        {
            return;
        }
        this._window.Closed -= new EventHandler(this.OnPanelClosed);
        this._dispatcherFrame.Continue = false;
        this._dispatcherFrame = null;
    }
}
}

I'm sure this code was taken from a Blog/Forum post of some sort but am unable to find any reference to it in code. We want to keep the modal to parent but some how address the odd key press issue. To reproduce the issue replace the button_click in Window1 to call ShowModalToParent on a window that uses this as a base class.

0

There are 0 answers