我还是 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
没有为托管应用程序生成键盘消息以及如何/如果我可以纠正它?