将WM_INPUT键盘消息发送到HWNDHOST应用程序

时间:2014-08-23 20:10:08

标签: c# wpf winapi hwndhost

我还是C#和WPF的新手,作为一个学习练习,我在一个非托管的win32 C ++应用程序中构建一个简单的WPF包装器。我目前在WPF控件中使用HWNDHOST托管了非托管应用程序,并且正在接收用于鼠标输入的WM_INPUT消息,但是当涉及键盘输入时,我只接收WM_KEYUP/DOWN消息键盘但没有WM_INPUT条消息。

托管应用程序不幸地专门使用RawInput,因此需要WM_INPUT消息才能使键盘输入系统正常运行。

托管应用程序的C#代码如下:

class EngineHost : HwndHost
{
    #region Win32
    private const int SWP_NOZORDER = 0x0004;
    private const int SWP_NOACTIVATE = 0x0010;
    private const int GWL_STYLE = -16;
    private const int WS_CAPTION = 0x00C00000;
    private const int WS_THICKFRAME = 0x00040000;
    private const int WS_CHILD = 0x40000000;

    [DllImport("user32.dll")]
    private static extern int SetWindowLong(IntPtr hWnd, int nIndex, int dwNewLong);

    [DllImport("user32.dll", SetLastError = true)]
    private static extern int GetWindowLong(IntPtr hWnd, int nIndex);

    [DllImport("user32")]
    private static extern IntPtr SetParent(IntPtr hWnd, IntPtr hWndParent);
    #endregion

    #region Members
    private Process _process;
    #endregion

    #region Implementation
    protected override HandleRef BuildWindowCore(HandleRef hwndParent)
    {
        ProcessStartInfo psi = new ProcessStartInfo("Kruger.exe");
        psi.WindowStyle = ProcessWindowStyle.Minimized;
        _process = Process.Start(psi);
        _process.WaitForInputIdle();

        // The main window handle may be unavailable for a while, just wait for it
        while (_process.MainWindowHandle == IntPtr.Zero)
        {
            Thread.Yield();
        }

        IntPtr engineHandle = _process.MainWindowHandle;

        int style = GetWindowLong(engineHandle, GWL_STYLE);
        style = style & ~((int)WS_CAPTION) & ~((int)WS_THICKFRAME); // Removes Caption bar and the sizing border
        style |= ((int)WS_CHILD); // Must be a child window to be hosted
        SetWindowLong(engineHandle, GWL_STYLE, style);

        SetParent(engineHandle, hwndParent.Handle);
        return new HandleRef(this, engineHandle);
    }

    protected override void DestroyWindowCore(HandleRef hwnd)
    {
        if (_process != null)
        {
            _process.CloseMainWindow();
            _process.WaitForExit(5000);

            if (_process.HasExited == false)
            {
                _process.Kill();
            }

            _process.Close();
            _process.Dispose();
            _process = null;
        }
    }
    #endregion
}

有人能告诉我为什么没有为托管应用程序生成WM_INPUT键盘消息以及我是否可以纠正这些消息?

0 个答案:

没有答案