The desired behavior when used with volume control keys can be gotten by storing the current volume, sending a media key press, then updating the volume to the stored value +/- 1 (or +0, if just seeking to display the OSD).
There is an edge case when mimicking Volume_Down when the volume is <=3. The sent Volume_Down keypress triggers the mute, but this can be accommodated for by manually setting the mute to be off afterwards, or by pre-setting the volume to 4, which prevents the rounding to 0. Which method to choose depends upon if you prefer a brief blip of potentially louder sound (pre-set to 4) or a brief mute (disable mute afterwards) when the volume is lowered from <=3 values.
The following code is in 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)
; }
}
To just trigger the OSD as the question asks the following works. Hitting a volume key then quickly resetting the volume will displays it, yet considerations need to be made if currently muted as to prevent a blip of sound. Volume keys are used since double toggling Volume_Mute causes a gap in the sound output.
; 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)
}
All of the same code, yet uncommented:
$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)
}