我还是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
键盘消息以及我是否可以纠正这些消息?