只要它以0xA和0x9开头,APPCOMMAND_VOLUME_UP和APPCOMMAND_VOLUME_DOWN的值是否真的重要?

时间:2016-01-19 11:04:42

标签: c# .net winforms-interop

我使用以下代码以编程方式修改系统卷。我诚实地告诉你,我从lot of sources获得了来自互联网的相同代码。

    //private const int APPCOMMAND_VOLUME_UP = 0xA0000;
    private const int APPCOMMAND_VOLUME_UP = 0xAFFFF;
    private const int APPCOMMAND_VOLUME_DOWN = 0x90000;
    private const int WM_APPCOMMAND = 0x319;

    [DllImport("user32.dll")]
    public static extern IntPtr SendMessageW(IntPtr hWnd, int Msg,
        IntPtr wParam, IntPtr lParam);

    private void btnVolumeUp_Click(object sender, RoutedEventArgs e)
    {
        SendMessageW(new WindowInteropHelper(this).Handle, WM_APPCOMMAND, new WindowInteropHelper(this).Handle,
            (IntPtr)APPCOMMAND_VOLUME_UP);
    }

我发现两个变量APPCOMMAND_VOLUME_UP和APPCOMMAND_VOLUME_DOWN的值只要上限值以 0xA 开头且下限值以 0x9 即可。对于UP和DOWN场景,我已尝试在0000和FFFF之间使用许多不同的值。这些价值观真的不重要吗?

我对互操作电话没有多少了解。有人可以解释这些价值观的重要性吗?

提前谢谢!

1 个答案:

答案 0 :(得分:3)

没有"值"。 LPARAM参数编码三个不同的属性:

  • 该命令,例如APPCOMMAND_VOLUME_UP为10(0x0A)。
  • 设备,指示命令的生成方式,可以是key,mouse或oem。
  • "键",表示生成命令时哪些修饰符生效。就像用于键盘的shift / ctrl和用于鼠标的单击鼠标按钮
  • 一样

这三个属性的编码方式是位域在C语言中的工作方式。十六进制的位模式是0xDCCCKKKK,其中C是命令,D是设备,K是键。

由于您自己合成了消息,因此没有任何有意义的方法来报告设备或密钥。也没关系,你应该简单地使用0(设备=键盘,没有修改键)。请注意,您现在使用的值不正确,0xAFFFF不使用正确的键值,并且您说CTRL和SHIFT键已关闭。可能不足以最终混淆shell,这些修饰键不会影响特定命令的工作方式。

所以一个理智的实现看起来像:

public enum AppCommand {
    VolumeDown = 9
    VolumeUp = 10,
    // etc..
}

private void SendAppCommand(AppCommand cmd) {
    var hwnd = new WindowInteropHelper(this).Handle;
    SendMessageW(hwnd, WM_APPCOMMAND, hwnd, (int)cmd << 16);
}