发送键“mediaplaypause”;到一个应用程序,而不为它设置焦点

本文关键字:应用程序 一个 焦点 设置 mediaplaypause | 更新日期: 2023-09-27 18:06:37

我正在创建一个程序,该程序将向我拥有IntPtr的应用程序发送媒体密钥输入(例如MediaPlayPause, MediaNextTrack等)。有点像虚拟遥控器。

所以经过研究我发现这个几乎告诉我如何解决我的问题。然而,链接中提到的方法有三个问题。

  1. 我不能将应用程序设置为前台窗口,因为我需要我的应用程序聚焦。
  2. 他们使用SendKeys函数,这需要目标窗口被聚焦,这违背了问题1。
  3. 据我所知,SendKeys不能发送键盘按钮,如键盘播放/暂停按钮。

最后,我对我必须使用的(SendInput ?, SendMessage ?)感到相当困惑。

如有任何帮助,不胜感激。


编辑

根据我收到的答案,我编写了下面的示例代码。
理论上,它应该找到notepad并在其中插入字母"L"。

但是记事本上没有显示任何东西,也没有应用程序崩溃。我是否遗漏了一个明显的错误?

[DllImport("user32.dll", EntryPoint = "FindWindow", SetLastError = true)]
static extern IntPtr FindWindowByCaption(int ZeroOnly, string lpWindowName);
[DllImport("user32.dll", CharSet = CharSet.Auto)]
static extern IntPtr SendMessage(IntPtr hWnd, UInt32 Msg, int wParam, IntPtr lParam);
const int WM_KEYDOWN = 0x100;
//const int WM_KEYUP = 0x101;
const int L_KEY = 0x4C;
private void button1_Click(object sender, EventArgs e)
{
    IntPtr ip = FindWindowByCaption(0, "Untitled - Notepad");
    SendMessage(ip, WM_KEYDOWN, L_KEY, IntPtr.Zero);
    //SendMessage(ip, WM_KEYUP, L_KEY, IntPtr.Zero);
}

发送键“mediaplaypause”;到一个应用程序,而不为它设置焦点

这些键大多被转换为WM_APPCOMMAND*消息…所以你可以尝试SendMessage,另一个选项是SendInput(如果应用程序是基于directinput的)…

查看Windows API中常见媒体播放器功能的链接?-也许有一些信息你可以使用…

至于焦点问题-没有100%可靠的解决方案(参见我如何发送按键到一个窗口,而不必使用Windows API激活它?)…你能实现100%可靠性的最好方法就是聚焦应用程序,发送密钥,重新聚焦应用程序……除非你写一些设备驱动程序(内核模式)…

要发送多媒体密钥,包括Play/PauseNextTrackPrevTrack等,您可以使用keybd_event:

public class Program
{
    public const int KEYEVENTF_EXTENTEDKEY = 1;
    public const int KEYEVENTF_KEYUP = 0;
    public const int VK_MEDIA_NEXT_TRACK = 0xB0;
    public const int VK_MEDIA_PLAY_PAUSE = 0xB3;
    public const int VK_MEDIA_PREV_TRACK = 0xB1;
    [DllImport("user32.dll")]
    public static extern void keybd_event(byte virtualKey, byte scanCode, uint flags, IntPtr extraInfo);
    public static void Main(string[] args)
    {
        keybd_event(VK_MEDIA_PLAY_PAUSE, 0, KEYEVENTF_EXTENTEDKEY, IntPtr.Zero);    // Play/Pause
        //keybd_event(VK_MEDIA_PREV_TRACK, 0, KEYEVENTF_EXTENTEDKEY, IntPtr.Zero);  // PrevTrack
        //keybd_event(VK_MEDIA_NEXT_TRACK, 0, KEYEVENTF_EXTENTEDKEY, IntPtr.Zero);  // NextTrack
    }

下面是这个windows api可以处理的键代码列表:
https://learn.microsoft.com/en-us/windows/win32/inputdev/virtual-key-codes

SendKeys类非常好,但它也有局限性。上面的方法直接向Windows操作系统发送key命令。

相关文章: