3

我试图通过在我的 C# WPF 应用程序中调用 Win32 API 来更改系统的音量。我查看过的每个站点都显示类似于以下的代码:

double val_c = 0;

private void slider1_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e)
{
    const uint WM_APPCOMMAND = 0x319;
    const uint APPCOMMAND_VOLUME_UP = 10;
    const uint APPCOMMAND_VOLUME_DOWN = 9;
    const uint APPCOMMAND_VOLUME_MUTE = 8;

    IntPtr handy = this.Handle;

    if (slider1.Value < val_c)
    {
        Win32.Win32.SendMessage(handy, WM_APPCOMMAND, handy, new IntPtr(APPCOMMAND_VOLUME_DOWN));
    }
    else
    {
        Win32.Win32.SendMessage(handy, WM_APPCOMMAND, handy, new IntPtr(APPCOMMAND_VOLUME_UP));
    }
    val_c = slider1.Value;
}

我不知道在哪里指定我要设置的确切值。

上面的代码将音量增加了多少?实际上,尽管上述内容已发布在多个论坛、博客等上,但我无法使其正常工作。只有在最后一个参数中添加“* 0x10000”时它才有效。即便如此,我也无法弄清楚它的意义。

当滑块(最小值为 0,最大值为 100)值发生变化时,我设置了上述设置,但滑块与实际系统音量不同步。只需将滑块设置为 25 即可将系统音量设置为 100。

4

1 回答 1

1

我认为有两个问题。一是消息参数的定义,应该如下

const uint WM_APPCOMMAND = 0x319;
const uint APPCOMMAND_VOLUME_UP = 0xA0000;
const uint APPCOMMAND_VOLUME_DOWN = 0x90000;
const uint APPCOMMAND_VOLUME_MUTE = 0x80000;

另一个是您需要根据滑块的当前值与先前值之间的差异多次应用向上/向下更改。

所以,像这样的事情(请注意,消息参数应该只转换为IntPtr而不是new'ed

if (slider1.Value < val_c)
{
    int nDiff = (int)(val_c - slider1.Value);
    for (int i = 0; i < nDiff; ++i)
    {
        Win32.Win32.SendMessage(handy, WM_APPCOMMAND, handy, (IntPtr)APPCOMMAND_VOLUME_DOWN);
    }
}
else
{
    int nDiff = (int)(slider1.Value - val_c);
    for (int i = 0; i < nDiff; ++i)
    {
        Win32.Win32.SendMessage(handy, WM_APPCOMMAND, handy, (IntPtr)APPCOMMAND_VOLUME_UP);
    }
}

上面的代码可以稍微简化一下:

IntPtr pArg = (slider1.Value < val_c) ? (IntPtr)APPCOMMAND_VOLUME_DOWN : (IntPtr)APPCOMMAND_VOLUME_UP;
int nDiff = (int)Math.Abs(val_c - slider1.Value);
for (int i = 0; i < nDiff; ++i)
{
    Win32.Win32.SendMessage(handy, WM_APPCOMMAND, handy, pArg);
}

唯一的另一件事是,当您的应用程序启动时,您需要知道当前的音量设置,以便您可以将滑块设置为正确的初始值。

这里有一个(更复杂的)教程,展示了如何做到这一点,尽管在开始时将音量初始设置为某个已知值可能更实用(即,将音量降低 100 次以确保它为零启动)。

于 2013-06-09T07:53:43.553 回答