如何触发Windows音量显示?

How to trigger the Windows volume display?

当在 windows 上按下增加音量的标准键盘键时,左上角会出现一个小的 window,显示音量以及可能有关播放媒体的信息。我正在寻找一种在不更改音量状态的情况下触发 window 的方法,最好是以一种易于与 Autohotkey 集成的方式。

Windows 8介绍了Media​Control class that lets Modern apps hook into the system playback control. In Windows 8.1 and 10 it was replaced by the System​Media​Transport​Controls class.

虽然它支持“Manual control of the System Media Transport Controls”,但似乎没有办法 show/hide 叠加层,当然也不是来自桌面应用程序。

进入未记录的领域,我找到了叠加层的 class 名称,这将我带到了 HideVolumeOSD。不幸的是,class 名称相当通用,因此您可能还必须查看 window 的大小以确定它是否是卷覆盖。

我不知道只显示 window 是否可行,Windows 不希望它可见,除非响应键盘和播放事件。 HideVolumeOSD 应用程序使用 keybd_event(音量 up/down)来触发它,但如评论中所述,这是有问题的...

我设置了一个自动热键来提高音量,降低音量(对于快捷键 ctrl+pgdn)。

^PgDn::
   Send {Volume_Up}
   Send {Volume_Down}
   return     

通过存储当前音量,发送媒体键,然后将音量更新为存储值 +/- 1(或 +0,如果只是寻求显示 OSD)。

当音量 <=3 时模仿 Volume_Down 时存在边缘情况。发送的 Volume_Down 按键触发静音,但这可以通过手动将静音设置为关闭来解决,或者将音量预先设置为 4,以防止四舍五入为 0。选择哪种方法取决于当音量从 <=3 值降低时,如果您更喜欢短暂的可能更响亮的声音(预设为 4)或短暂的静音(之后禁用静音)。

以下代码在 AHK v2.

; Prefix with '$' so as to prevent self triggering, since internally sending Volume_Up
$Volume_Up::{
    ; Get the current volume. SoundGetVolume returns a float which often needs rounding
    volume:=Round(SoundGetVolume())
    ; Send the Volume_Up key, so the media display is triggered
    Send "{Volume_Up}"
    ; Indiscriminately set the volume manually to volume+1
    SoundSetVolume(volume+1)
}

; Much the same as above, yet when sending Volume_Down at volumes <=3 the volume
;   is rounded down to 0 which triggers mute. The volume is then set properly,
;   yet remains muted. In order to not hear a cut in the audio, you need to set
;   the volume to 4 when (1<volume<=3) so that the Volume_Down doesn't round it
;   down to 0, or disable the mute afterwards (if volume > 1). This causes a
;   brief volume spike or mute blip, respectively. Currently the volume spike option
;   is uncommented.
$Volume_Down::{
    volume:=Round(SoundGetVolume())

    ; Bumping the volume before sending the Volume_Down to prevent mute blip (if needed)
    if(1 < volume and volume <= 3){
        SoundSetVolume(4)
    }

    Send "{Volume_Down}"
    SoundSetVolume(volume-1)

    ; ; Disable accidental triggering of mute when volume >= 3 after sending Volume_Down
    ; if(volume > 1) {
    ;   SoundSetMute(0)
    ; }
}

只触发 OSD 作为问题询问以下工作。点击音量键然后快速重置音量将显示它,但如果当前静音则需要考虑以防止声音闪烁。使用音量键是因为双切换 Volume_Mute 会导致声音输出出现间隙。

; Trigger the on screen display of the volume bar by hitting Volume_Up and
;   then quickly resetting the volume. If muted and send Volume_Up, we will
;   hear audio at original volume for a brief second. To prevent this, we
;   can set the volume to 0 and send Volume_Down instead.
^PgUp::{
    volume:=Round(SoundGetVolume())
    muted:=SoundGetMute()

    ; Trigger the display with a volume key (might briefly bump the volume if unmuted)
    if (muted or volume == 0) {
        SoundSetVolume(0)
        Send "{Volume_Down}"
    } else {
        Send "{Volume_Up}"
    }

    ; Reset to the original volume and mute status
    SoundSetMute(muted)
    SoundSetVolume(volume)
}

所有相同的代码,但未注释:

$Volume_Up::{
    volume:=Round(SoundGetVolume())
    Send "{Volume_Up}"
    SoundSetVolume(volume+1)
}

$Volume_Down::{
    volume:=Round(SoundGetVolume())
    if(1 < volume and volume <= 3){
        SoundSetVolume(4)
    }
    Send "{Volume_Down}"
    SoundSetVolume(volume-1)
}

^PgUp::{
    volume:=Round(SoundGetVolume())
    muted:=SoundGetMute()
    if (muted or volume == 0) {
        SoundSetVolume(0)
        Send "{Volume_Down}"
    } else {
        Send "{Volume_Up}"
    }
    SoundSetMute(muted)
    SoundSetVolume(volume)
}

基于 Anna Wang 的回答 ()。

这将恢复音量,即使它处于奇数值。

^PgDn:: ;Ctrl+Page Down
  SoundGet, original_volume
  SendInput {Volume_Down}  
  SoundSet, original_volume
return