我想为我们的 Windows Mobile 应用程序的远程控制功能模拟快捷方式。应该支持任何可能的快捷方式(想想Ctrl+/或Alt+ ä)。
有了keybd_event
我可以很好地模拟快捷键,但这个功能只允许使用虚拟键代码。因此,我想到了PostKeybdMessage
允许我将任何字符发送到前台窗口的功能。但是如果我结合这两个调用,Windows 将只打印字符而不是执行快捷方式。
这是我尝试过的:
- 静默发送 CTRL 键 (
KEYEVENTF_SILENT
) KeyShiftAnyCtrlFlag
在PostKeybdMessage
通话中添加- 玩了很多缓冲区和
PostKeybdMessage
调用标志(这很令人困惑)
我的问题是:
- 可以
PostKeybdMessage
用来模拟快捷方式还是我只是在浪费时间?如果可以,我在代码示例中做错了什么? - 是否有发送特殊字符(变音符号、#、=、...)的技巧
keybd_event
? - 还有其他方法可以模拟快捷方式吗?
简单的测试应用
public partial class ShortcutTest : Form
{
private const int KEYEVENTF_KEYUP = 0x0002;
private const int HWND_FOREGROUND = -1;
private const uint KEY_STATE_DOWN = 0x0080;
private const uint KEY_SHIFT_NO_CHARACTER = 0x00010000;
private const uint KEY_SHIFT_ANY_CONTROL = 0x40000000;
private const byte VK_CONTROL = 0x11; // Keys.ControlKey
[DllImport("coredll.dll", SetLastError = true)]
internal static extern void keybd_event(byte bVk, byte bScan, int dwFlags, int dwExtraInfo);
[DllImport("coredll.dll")]
private static extern bool PostKeybdMessage(int hwnd, uint vKey, uint KeyStateFlags, uint cCharacters, uint[] pShiftStateBuffer, uint[] pCharacterBuffer);
public ShortcutTest()
{
InitializeComponent();
}
private void timer1_Tick(object sender, EventArgs e)
{
timer1.Enabled = false;
keybd_event((byte)Keys.ControlKey, 0, 0, 0);
// this would work: keybd_event((byte)Keys.X, 0, 0, 0);
// this won't work
SendChar('x');
//keybd_event((byte)Keys.X, 0, KEYEVENTF_KEYUP, 0);
keybd_event((byte)Keys.ControlKey, 0, KEYEVENTF_KEYUP, 0);
button1.Enabled = true;
}
private void button1_Click(object sender, EventArgs e)
{
timer1.Enabled = true;
button1.Enabled = false;
}
public void SendChar(char ch)
{
uint[] input = new uint[] { (uint)ch };
uint[] downStates = { KEY_STATE_DOWN | KEY_SHIFT_ANY_CONTROL };
uint[] upStates = { KEY_SHIFT_NO_CHARACTER | KEY_SHIFT_ANY_CONTROL };
PostKeybdMessage(HWND_FOREGROUND, 0, downStates[0], 1, downStates, input);
// tested with KeyShiftDeadFlag and some others, with \0 char ...
PostKeybdMessage(HWND_FOREGROUND, 0, upStates[0], 1, upStates, input);
}
}
编辑:我只是查看了 OpenNETCF 的实现,SendKeys
它们keybd_event
只使用(例如,“+a”会失败)。