0

我还是 C# 和 WPF 的新手,作为学习练习,我正在非托管 win32 C++ 应用程序的 WPF 中构建一个简单的包装器。HWNDHOST我目前在 WPF 控件中使用托管的非托管应用程序,并且正在接收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没有为托管应用程序生成键盘消息以及如何/如果我可以纠正它?

4

0 回答 0