好的,经过一天的试验,我找到了一种稳定的方法来指示硬按钮按键的 SIP(InputPanel)按键。
使用PeekMessage
我们可以检查消息队列中的键值并检查LParam
来自 SIP(跨所有设备)时似乎总是为 1 的“1”。
下面的代码
public class InputHelper
{
#region Static Members
/// <summary>
/// Determines whether the key value pressed originated from the SIP
/// </summary>
/// <param name="keyValue">The key value.</param>
/// <param name="handle">The widget handle.</param>
/// <returns>
/// <c>true</c> if is sip key press; otherwise, <c>false</c>.
/// </returns>
public static bool IsSipKeyPress(int keyValue, IntPtr handle)
{
NativeMessage m;
if (PeekMessage(out m, handle, 0, 0, PM_NOREMOVE))
{
// All SIP inputs have LParam of 1, so ignore these
if (m.msg == WM_CHAR && m.wParam == (IntPtr)keyValue && m.lParam == (IntPtr)1)
{
return true;
}
}
return false;
}
#endregion
#region P-Invoke
const uint PM_NOREMOVE = 0x0000;
const uint WM_CHAR = 258;
[DllImport("coredll.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
static extern bool PeekMessage(out NativeMessage lpMsg, IntPtr hWnd, uint wMsgFilterMin, uint wMsgFilterMax, uint wRemoveMsg);
[StructLayout(LayoutKind.Sequential)]
public struct NativeMessage
{
public IntPtr handle;
public uint msg;
public IntPtr wParam;
public IntPtr lParam;
public uint time;
public System.Drawing.Point p;
}
#endregion
}
用法:
/// <summary>
/// Handle a KeyDown event and check for Hardbutton Return key
/// </summary>
/// <param name="e">A KeyEventArgs instance</param>
public override void HandleKeyDown(KeyEventArgs e)
{
if (e.KeyValue == 13)
{
if (!InputHelper.IsSipKeyPress(13, base.Handle))
{
CompleteProcess();
}
}
base.HandleKeyDown(e);
}
希望这对其他人有帮助:)