GUI-Overlay in full-screen application

Get help with using AutoHotkey (v1.1 and older) and its commands and hotkeys
cl_panda
Posts: 7
Joined: 17 Apr 2018, 08:14

GUI-Overlay in full-screen application

22 Apr 2018, 09:43

Hi,

I'm writing a script to change the volume of a full-screen app (like games) via nircmd.exe and the windows-volume-mixer.
The full-screen detection and volume-changer are working so far. Now I want to display the current volume with a GUI overlay without any lag.

The problem is that the game minimizes while displaying the GUI overlay.
I tried to set the focus back to the game immediately after the GUI generation - but then, the game minimizes briefly and goes back to full-screen.

My code so far:

Code: Select all

volume := 1

; 
; Increase full-screen app volume
; 
$NumpadAdd::
  isFullScreen := isWindowFullScreen("A")
  
  if (isFullScreen) {
    volume += 0.1
    volume := volume > 1 ? 1 : volume
    Run, nircmd.exe setappvolume focused %volume%
    GoSub, SubOverlayOpen
  } else {
    Send {NumpadAdd}
  }
  Return

; 
; Decrease full-screen app volume
; 
$NumpadSub::
  isFullScreen := isWindowFullScreen("A")
  
  if (isFullScreen) {
    volume -= 0.1
    volume := volume < 0 ? 0 : volume
    Run, nircmd.exe setappvolume focused %volume%
    GoSub, SubOverlayOpen
  } else {
    Send {NumpadSub}
  }
  Return

; 
; Check if current window is in full-screen
; 
isWindowFullScreen(winTitle) {
  winID := WinExist(winTitle)

  If (!winID)
    Return false

  WinGet style, Style, ahk_id %WinID%
  WinGetPos ,,,winW,winH, %winTitle%
  ; 0x800000 is WS_BORDER.
  ; 0x20000000 is WS_MINIMIZE.
  ; no border and not minimized
  Return ((style & 0x20800000) or winH < A_ScreenHeight or winW < A_ScreenWidth) ? false : true
}

; 
; Open overlay
; 
SubOverlayOpen:  
  Gui, GUI_Overlay:New, +LastFound +AlwaysOnTop -Caption +E0x80020
  Gui, Margin, 5, 5
  Gui, Font, s16, Arial
  Gui, Add, Text, w40 Center cWhite, %volume%
  
  Gui, Color, 000000
  WinSet, Transparent, 200
  WinSet, ExStyle, +0x80020
  Gui, Show, Hide, Overlay
  
  WinMove, 20, 20
  Gui, GUI_Overlay:Show
  
  SetTimer, SubOverlayClose, 1000
  Return

; 
; Close Overlay
; 
SubOverlayClose:
  Gui, GUI_Overlay:Destroy
  Return
swagfag
Posts: 6222
Joined: 11 Jan 2017, 17:59

Re: GUI-Overlay in full-screen application

22 Apr 2018, 10:41

you cant do this for exclusive fullscreen without a custom hook

if u have a dx9 game, an ahk wrapper exists - https://github.com/agrippa1994/DX9-Overlay-API

for dx9+ you can use https://github.com/nefarius/Indicium-Supra, for which no ahk wrapper exists, but at that point why even bother with ahk, write ur osd in c++

and finally, weigh the extent to which u are comfortable using hooks in ur game if you do decide to go that route, lest u get banned

ahk will work with fullscreen borderless though
cl_panda
Posts: 7
Joined: 17 Apr 2018, 08:14

Re: GUI-Overlay in full-screen application

22 Apr 2018, 12:01

Thanks for replying.

Since I don't want to risk any game bans i'll not use any dx extensions.
nircmd.exe does not interact with the game, afaik. My current ahk-code should be safe to use, isn't it?

I'm considering another possibility to inform the user of the current volume-value, like displaying it on a second screen or play a sound cue.
Is it possible to play a sound at a specific volume? SoundPlay doesn't have this option.
swagfag
Posts: 6222
Joined: 11 Jan 2017, 17:59

Re: GUI-Overlay in full-screen application

22 Apr 2018, 14:10

no, your current script wont get you banned dont worry

but if you wanted to display overlays in a game running in exclusive fullscreen, youd need to draw them from within the game
for that to happen, youd need access to these drawing functions
injecting the hooks grants you such access, its the injecting that can get u busted
cl_panda
Posts: 7
Joined: 17 Apr 2018, 08:14

Re: GUI-Overlay in full-screen application

22 Apr 2018, 14:56

ah, i see. thanks.

The text-to-speech feature could work pretty good, didn't know that it is that easy.
You can even change the speech volume easily. I'll give it a try.

The app should run in exclusive full-screen. Borderless windowed decreases fps in most games.
cl_panda
Posts: 7
Joined: 17 Apr 2018, 08:14

Re: GUI-Overlay in full-screen application

23 Apr 2018, 09:53

I tested the tts feature and ended up not using it. It works great, but it feels very weird :)
For a sound feedback it should be just a little beep :D

I know there are libs for playing sounds, but i don't want to bloat the code. Thus no feedback for now.

If someone want to use it as well:
  • Download nircmd.exe at https://www.nirsoft.net/utils/nircmd.html (at the very bottom) and place it near the ahk-file.
  • Hotkeys only fires in full-screen apps like games:
    • NumpadSub = Decrease volume by 0.1
    • NumpadAdd = Increase volume by 0.1
    • NumpadMult = Toggle volume between 0.3 and 1
Code:

Code: Select all

; 
; Current volume of full-screen application
; Value between 0 (muted) and 1 (100%)
; 
current_appvolume := 1

; 
; Toggle full-screen app volume
; 
$NumpadMult::
  if (isWindowFullScreen("A")) {
    if (current_appvolume < 1) {
      set_appvolume(1)
    } else {
      set_appvolume(0.3)
    }
  } else {
    Send {NumpadMult}
  }
  return

; 
; Increase full-screen app volume
; 
$NumpadAdd::
  if (isWindowFullScreen("A")) {
    set_appvolume(current_appvolume + 0.1)
  } else {
    Send {NumpadAdd}
  }
  return

; 
; Decrease full-screen app volume
; 
$NumpadSub::
  if (isWindowFullScreen("A")) {
    set_appvolume(current_appvolume - 0.1)
  } else {
    Send {NumpadSub}
  }
  return

; 
; Set volume of focused application
; 
set_appvolume(volume) {
  global current_appvolume

  if (volume > 1) {
    volume := 1
  } else if (volume < 0) {
    volume := 0
  } else {
    volume := Round(volume, 2) + 0
  }
    
  Run, nircmd.exe setappvolume focused %volume%
  current_appvolume := volume
  return
}
  
; 
; Check if current window is in full-screen
; 
isWindowFullScreen(winTitle) {
  winID := WinExist(winTitle)

  If (!winID)
    return false

  WinGet style, Style, ahk_id %WinID%
  WinGetPos ,,,winW,winH, %winTitle%
  ; 0x800000 is WS_BORDER.
  ; 0x20000000 is WS_MINIMIZE.
  ; no border and not minimized
  return ((style & 0x20800000) or winH < A_ScreenHeight or winW < A_ScreenWidth) ? false : true
}
User avatar
evilC
Posts: 4823
Joined: 27 Feb 2014, 12:30

Re: GUI-Overlay in full-screen application

23 Apr 2018, 11:03

Also, you are not properly passing the keys through:

Code: Select all

$NumpadSub::
  if (isWindowFullScreen("A")) {
    set_appvolume(current_appvolume - 0.1)
  } else {
    Send {NumpadSub}	; Sends press AND RELEASE of NumpadSub in response to press!
  }
  return
NumpadSub:: gets called on PRESS of NumbpadSub, but you send press *and release* of NumpadSub.
As you ARE blocking the press event with NumpadSub:: but ARE NOT blocking the release event, you can simply send the down event

Code: Select all

$NumpadSub::
  if (isWindowFullScreen("A")) {
    set_appvolume(current_appvolume - 0.1)
  } else {
    Send {NumpadSub down}	; Only send press of NumpadSub in response to press. Release is not blocked, so will be seen normally
  }
  return
cl_panda
Posts: 7
Joined: 17 Apr 2018, 08:14

Re: GUI-Overlay in full-screen application

23 Apr 2018, 19:27

Thanks for the improvements. Also changed some names for consistency. Updated ahk-file:

Code: Select all

; 
; Current volume of full-screen application
; Value between 0 (muted) and 1 (100%)
; 
currentAppVolume := 1

; 
; Toggle full-screen app volume
; 
$NumpadMult::
  if (isActiveWindowFullScreen()) {
    if (currentAppVolume < 1) {
      setAppVolume(1)
    } else {
      setAppVolume(0.3)
    }
  } else {
    Send {NumpadMult down}
  }
  return

; 
; Increase full-screen app volume
; 
$NumpadAdd::
  if (isActiveWindowFullScreen()) {
    setAppVolume(currentAppVolume + 0.1)
  } else {
    Send {NumpadAdd down}
  }
  return

; 
; Decrease full-screen app volume
; 
$NumpadSub::
  if (isActiveWindowFullScreen()) {
    setAppVolume(currentAppVolume - 0.1)
  } else {
    Send {NumpadSub down}
  }
  return

; 
; Set volume of focused application
; 
setAppVolume(volume) {
  global currentAppVolume

  if (volume > 1) {
    volume := 1
  } else if (volume < 0) {
    volume := 0
  } else {
    volume := Round(volume, 2) + 0
  }
    
  Run, nircmd.exe setappvolume focused %volume%
  currentAppVolume := volume
  return
}
  
; 
; Checks if active window is in full-screen
; 
isActiveWindowFullScreen() {
  winID := WinExist("A")

  If (!winID)
    return false

  WinGet style, Style, ahk_id %winID%
  WinGetPos ,,,winW,winH, A
  ; 0x800000 is WS_BORDER.
  ; 0x20000000 is WS_MINIMIZE.
  ; no border and not minimized
  return ((style & 0x20800000) or winH < A_ScreenHeight or winW < A_ScreenWidth) ? false : true
}
Edit: Fixed a bug

Return to “Ask for Help (v1)”

Who is online

Users browsing this forum: Bing [Bot] and 437 guests