使用 APPCOMMAND_MEDIA_NEXT_TRACK 发送消息
Send message with APPCOMMAND_MEDIA_NEXT_TRACK
我正在尝试编写一个简单的应用程序来跳过当前播放的曲目,类似于键盘上的媒体按钮的工作方式。
我找到了静音 (0x80000) 的 LParam 值,但我不知道如何找到命令的值,例如下一首/上一首曲目,或者 8(来自下面的文章)如何映射到 0x80000,所以我可以解决如何将 11(下面文章的下一首曲目)映射到有效的代码?
静音通过使用 0x80000 起作用,但在使用 8 时不起作用。
抱歉,如果这是一个愚蠢的问题,我以前从未做过任何互操作的事情。
谢谢
https://msdn.microsoft.com/en-us/library/windows/desktop/ms646275%28v=vs.85%29.aspx
using System;
using System.Runtime.InteropServices;
using System.Windows.Forms;
public partial class Form1 : Form
{
private const int WM_APPCOMMAND = 0x319;
private const int APPCOMMAND_VOLUME_MUTE = 0x80000;
private const int APPCOMMAND_VOLUME_MUTE_INT = 8;
//private const int APPCOMMAND_MEDIA_NEXT_TRACK = ?;
private const int APPCOMMAND_MEDIA_NEXT_TRACK = 11;
[DllImport("user32.dll")]
public static extern IntPtr SendMessageW(IntPtr hWnd, int Msg, IntPtr wParam, int lParam);
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
// doesn't work
//SendMessageW(this.Handle, WM_APPCOMMAND, this.Handle,
// APPCOMMAND_VOLUME_MUTE_INT);
SendMessageW(this.Handle, WM_APPCOMMAND, this.Handle,
APPCOMMAND_VOLUME_MUTE);
}
}
SendMessage() 的参数通常以不寻常的方式打包。一个必要的邪恶,因为它只有简单的参数类型并且需要支持许多不同类型的消息。也设计用于 C,一种不支持任何方法重载的语言。 WM_APPCOMMAND 确实如此,lparam 被打包以携带 3 个值(命令、设备编号、键状态)。
正确的代码是:
SendMessage(this.Handle, WM_APPCOMMAND, this.Handle, (IntPtr)((int)cmd << 16));
其中 cmd 是您要发送的命令。就像示例代码中的 APPCOMMAND_VOLUME_MUTE_INT 或 APPCOMMAND_MEDIA_NEXT_TRACK 一样。还解释了 0x8000 来自哪里,它是 8 << 16.
请注意,您的 SendMessage() 声明是错误的,最后一个参数是 IntPtr,而不是 int。您会在 this post.
中找到可用于任何类型项目的 C# 包装器 class
我正在尝试编写一个简单的应用程序来跳过当前播放的曲目,类似于键盘上的媒体按钮的工作方式。
我找到了静音 (0x80000) 的 LParam 值,但我不知道如何找到命令的值,例如下一首/上一首曲目,或者 8(来自下面的文章)如何映射到 0x80000,所以我可以解决如何将 11(下面文章的下一首曲目)映射到有效的代码?
静音通过使用 0x80000 起作用,但在使用 8 时不起作用。
抱歉,如果这是一个愚蠢的问题,我以前从未做过任何互操作的事情。
谢谢
https://msdn.microsoft.com/en-us/library/windows/desktop/ms646275%28v=vs.85%29.aspx
using System;
using System.Runtime.InteropServices;
using System.Windows.Forms;
public partial class Form1 : Form
{
private const int WM_APPCOMMAND = 0x319;
private const int APPCOMMAND_VOLUME_MUTE = 0x80000;
private const int APPCOMMAND_VOLUME_MUTE_INT = 8;
//private const int APPCOMMAND_MEDIA_NEXT_TRACK = ?;
private const int APPCOMMAND_MEDIA_NEXT_TRACK = 11;
[DllImport("user32.dll")]
public static extern IntPtr SendMessageW(IntPtr hWnd, int Msg, IntPtr wParam, int lParam);
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
// doesn't work
//SendMessageW(this.Handle, WM_APPCOMMAND, this.Handle,
// APPCOMMAND_VOLUME_MUTE_INT);
SendMessageW(this.Handle, WM_APPCOMMAND, this.Handle,
APPCOMMAND_VOLUME_MUTE);
}
}
SendMessage() 的参数通常以不寻常的方式打包。一个必要的邪恶,因为它只有简单的参数类型并且需要支持许多不同类型的消息。也设计用于 C,一种不支持任何方法重载的语言。 WM_APPCOMMAND 确实如此,lparam 被打包以携带 3 个值(命令、设备编号、键状态)。
正确的代码是:
SendMessage(this.Handle, WM_APPCOMMAND, this.Handle, (IntPtr)((int)cmd << 16));
其中 cmd 是您要发送的命令。就像示例代码中的 APPCOMMAND_VOLUME_MUTE_INT 或 APPCOMMAND_MEDIA_NEXT_TRACK 一样。还解释了 0x8000 来自哪里,它是 8 << 16.
请注意,您的 SendMessage() 声明是错误的,最后一个参数是 IntPtr,而不是 int。您会在 this post.
中找到可用于任何类型项目的 C# 包装器 class