【问题标题】:Send key "MediaPlayPause" to an application without setting focus to it向应用程序发送密钥“MediaPlayPause”而不设置焦点
【发布时间】:2011-08-26 01:41:56
【问题描述】:

我正在创建一个程序,它将媒体键输入(例如MediaPlayPauseMediaNextTrack 等)发送到我拥有IntPtr 的应用程序。有点像虚拟遥控器。

所以在研究之后我发现了 this,它几乎准确地告诉了我如何解决我的问题。

但是,链接中提到的方法存在三个问题。

  1. 我无法将应用程序设置为前台窗口,因为我需要让我的应用程序获得焦点。
  2. 他们使用 SendKeys 函数,该函数要求目标窗口被聚焦,这与问题 1 背道而驰。
  3. 据我所知,SendKeys 无法发送键盘按钮,例如键盘播放/暂停按钮。

最后,我对我必须使用什么感到很困惑(SendInput?、SendMessage?)。

任何帮助将不胜感激。


编辑

使用我收到的答案,我将下面的示例代码组合在一起。
理论上,它应该找到记事本并在其中插入字母“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);
}

【问题讨论】:

  • 我的回答完全符合您的需要,而且非常简单有效。 (实际上,我迟到了将近 10 年,但我现在有和你一样的需求 :))

标签: c# sendmessage sendinput


【解决方案1】:

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

查看Windows API for common media player functions? 中的链接 - 也许有一些信息您可以使用...

至于焦点问题 - 没有 100% 可靠的解决方案(请参阅 How do I send key strokes to a window without having to activate it using Windows API?)... 100% 可靠性可以实现的最佳目标是聚焦应用程序、发送密钥、重新聚焦您的应用程序......除了您会编写某种设备驱动程序(内核模式)...

【讨论】:

  • 感谢您的快速回复!使用您的答案,我将看到的一些代码拼凑在一起here。我尝试将字母“L”发送到记事本,但记事本上什么也没有显示,我的应用程序也没有崩溃。我在这里遗漏了一些明显的东西吗?
  • 取决于您的 Windows 版本等。这可能是权限/权限问题...而且您没有关注记事本...如没有关注的描述,这不可靠...
【解决方案2】:

发送多媒体按键,包括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://docs.microsoft.com/en-us/windows/win32/inputdev/virtual-key-codes

SendKeys 类非常好,但也很有限。上述方法将按键命令直接发送到 Windows 操作系统。

【讨论】:

    猜你喜欢
    • 2012-12-30
    • 2014-02-15
    • 1970-01-01
    • 1970-01-01
    • 2018-11-12
    • 1970-01-01
    • 1970-01-01
    • 2017-09-20
    • 2020-11-24
    相关资源
    最近更新 更多