AutoHotkey Homepage AutoHotkey Community
Let's help each other out
 
 FAQFAQ   SearchSearch   MemberlistMemberlist   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

Example: A volume OSD using GDI+

 
Reply to topic    AutoHotkey Community Forum Index -> Scripts & Functions
View previous topic :: View next topic  
Author Message
TheGood



Joined: 30 Jul 2007
Posts: 580

PostPosted: Tue Mar 24, 2009 3:49 am    Post subject: Example: A volume OSD using GDI+ Reply with quote

This script is just an example of how to draw a volume OSD onto a GUI using GDI+. It requires tic's excellent GDI+ library. The function itself is heavily based on Tutorial 9 of tic's tutorials. The script monitors changes in Master, Wave and (if existent) Winamp volume. Any changes bring up a GUI in the middle of the screen notifying of the volume's new value.
Obviously, you can change it to your needs (position of the GUI, one GUI for all the volumes, etc...)

Code:
/*! TheGood
    VolumeOSD - A volume OSD using GDI+
*/

;This script requires tic's amazing GDI+ wrapper which can be found at:
;http://www.autohotkey.com/forum/viewtopic.php?t=32238

;Needed for SendMessage to work properly
DetectHiddenWindows, On

;You first need to start up GDI+
pToken := Gdip_Startup()

;Check for error
If Not pToken {
   MsgBox, 16, VolumeOSD, % "GDI+ failed to start. Please ensure you have GDI+ on your system." ;%
    . "`nThe program will now exit."
   ExitApp
}

;So that we can shutdown GDI+ nicely
OnExit, ExitingApp

;Create a layered window
Gui, 1:-Caption +E0x80000 +LastFound +AlwaysOnTop +ToolWindow
hGui1 := WinExist()
Gui, 2:-Caption +E0x80000 +LastFound +AlwaysOnTop +ToolWindow
hGui2 := WinExist()
Gui, 3:-Caption +E0x80000 +LastFound +AlwaysOnTop +ToolWindow
hGui3 := WinExist()

;Get the current data so that it won't automatically show on startup
SoundGet, iOldMaster, Master, Volume
SoundGet, bOldMaster, Master, Mute
SoundGet, iOldWave, Wave, Volume
SoundGet, bOldWave, Wave, Mute

;Check if Winamp exists
hWinamp := WinExist("ahk_class Winamp v1.x")
If hWinamp {
    SendMessage 0x400, -666, 122,, ahk_id %hWinamp%
    iOldWinamp := (ErrorLevel / 255) * 100
}

;Main loop
Loop {
   
    ;Get master volume and update OSD
    SoundGet, iMaster, Master, Volume
    SoundGet, bMaster, Master, Mute
   
    ;Check for changes
    If (iMaster <> iOldMaster) Or (bOldMaster <> bMaster) {
        VolumeOSD(hGui1, (A_ScreenWidth - 200) / 2, (A_ScreenHeight - 170) / 2, "Master Volume", iMaster
        , Round(iMaster) "%", 0xFFCCCCCC, (bMaster = "OFF") ? 0xFF0F0FFF : 0xFFFF0000, 0xFF000000, 0xFFFFFFFF)
        iLastMaster := A_TickCount
    }
   
    iOldMaster := iMaster
    bOldMaster := bMaster
   
    ;Get wave volume and update OSD
    SoundGet, iWave, Wave, Volume
    SoundGet, bWave, Wave, Mute
   
    ;Check for changes
    If (iWave <> iOldWave) Or (bOldWave <> bWave) {
        VolumeOSD(hGui2, (A_ScreenWidth - 200) / 2, ((A_ScreenHeight - 170) / 2) + 60, "Wave Volume", iWave
        , Round(iWave) "%", 0xFFCCCCCC, (bWave = "OFF") ? 0xFF0F0FFF : 0xFFFF0000, 0xFF000000, 0xFFFFFFFF)
        iLastWave := A_TickCount
    }
   
    iOldWave := iWave
    bOldWave := bWave
   
    If hWinamp {
       
        ;Get Winamp volume and update OSD
        SendMessage 0x400, -666, 122,, ahk_id %hWinamp%
        iWinamp := (ErrorLevel / 255) * 100
       
        ;Check for changes
        If (iWinamp <> iOldWinamp) {
            VolumeOSD(hGui3, (A_ScreenWidth - 200) / 2, ((A_ScreenHeight - 170) / 2) + 120, "Winamp Volume", iWinamp
            , Round(iWinamp) "%", 0xFFCCCCCC, 0xFF0F0FFF, 0xFF000000, 0xFFFFFFFF)
            iLastWinamp := A_TickCount
        }
       
        iOldWinamp := iWinamp
    }
   
    ;Check if we can leave
    If (A_TickCount - iLastMaster > 1000)
        Gui, 1:Hide
    If (A_TickCount - iLastWave > 1000)
        Gui, 2:Hide
    If (A_TickCount - iLastWinamp > 1000)
        Gui, 3:Hide
   
    ;Get some sleep
    Sleep, 50
}

;hwnd       - Handle of the GUI
;iX         - X coordinate of the GUI
;iY         - Y coordinate of the GUI
;sText      - Text to display
;iProgress  - Percentage value of the progress bar (eg. 50) - can have decimals
;sProgText  - Text to display on top of the progress bar
;cText      - Forecolor of sText in ARGB
;cProgFill  - Color of the progress bar in ARGB
;cProgShape - Color of the outline of the progress bar in ARGB
;cPercent   - Forecolor of sProgText in ARGB
VolumeOSD(hwnd, iX, iY, sText, iProgress, sProgText, cText, cProgFill, cProgShape, cPercent) {
    iW := 200, iH := 50
   
    ;Create a GDI bitmap
    hbm := CreateDIBSection(iW, iH)
   
    ;Get a device context compatible with the screen
    hdc := CreateCompatibleDC()
   
    ;Select the bitmap into the device context
    obm := SelectObject(hdc, hbm)
   
    ;Get a pointer to the graphics of the bitmap, for use with drawing functions
    G := Gdip_GraphicsFromHDC(hdc)
   
    ;Set the smoothing mode to antialias = 4 to make shapes appear smother
    Gdip_SetSmoothingMode(G, 4)
   
    ;Create a partially transparent to draw a rounded rectangle with
    pBrush := Gdip_BrushCreateSolid(0xCC000000)
   
    ;Fill the graphics of the bitmap with a rounded rectangle using the brush created
    Gdip_FillRoundedRectangle(G, pBrush, 0, 0, iW, iH, 10)
   
    ;Delete the brush as it is no longer needed and wastes memory
    Gdip_DeleteBrush(pBrush)
   
    ;Fix cText and cPercent so that they become option compatible with Gdip_TextToGraphic()
    cText := "c" SubStr(cText, 3), cPercent := "c" SubStr(cPercent, 3)
   
    ;Draw the main text at (6, 6) in specified color with AA at size 16
    Options = x6 y6 %cText% r4 s16
    Gdip_TextToGraphics(G, sText, Options, "Arial")
   
    ;It's now time to fill the shape. Prepare a brush
    pBrush := Gdip_BrushCreateSolid(cProgFill)
   
    ;Fill the shape
   Gdip_FillRoundedRectangle(G, pBrush, 8, 28, (iProgress / 100) * (iW - 16), 15, (iProgress >= 2) ? 2 : 0)
   
    ;We're done with the brush now
    Gdip_DeleteBrush(pBrush)
   
    ;Create a pen for the outline of the progress bar
    pBorderPen := Gdip_CreatePen(cProgShape, 1)
   
    ;We can now draw the outline
    Gdip_DrawRoundedRectangle(G, pBorderPen, 8, 28, iW - 16, 15, 2)
   
    ;We're done with the pen now
    Gdip_DeletePen(pBorderPen)
   
    ;Draw the progress bar text over the progress bar in specified color with AA at size 10
    Options := "x8 y29 h14 w" (iW - 16) " " cPercent " r4 s12 Center Bold"
    Gdip_TextToGraphics(G, sProgText, Options, "Arial")
   
    ;Update the specified window we have created with a handle to our bitmap
    UpdateLayeredWindow(hwnd, hdc, iX, iY, iW, iH)
   
    ; Select the object back into the hdc
    SelectObject(hdc, obm)
   
    ; Now the bitmap may be deleted
    DeleteObject(hbm)
   
    ; Also the device context related to the bitmap may be deleted
    DeleteDC(hdc)
   
    ; The graphics may now be deleted
    Gdip_DeleteGraphics(G)
   
    ;Show the GUI if it's not showing already
    If Not DllCall("IsWindowVisible", "UInt", hwnd)
        DllCall("ShowWindow", "UInt", hwnd, "UInt", 8)  ;SW_SHOWNA
   
    Return
}

;Shutdown GDI+ and get out
ExitingApp:
    Gdip_Shutdown(pToken)
    ExitApp
Return


Back to top
View user's profile Send private message Visit poster's website
virpara



Joined: 17 Dec 2011
Posts: 5

PostPosted: Thu Dec 22, 2011 8:49 pm    Post subject: Reply with quote

Fantastic Shocked Rolling Eyes Razz
Back to top
View user's profile Send private message
Display posts from previous:   
Reply to topic    AutoHotkey Community Forum Index -> Scripts & Functions All times are GMT
Page 1 of 1

 
Jump to:  
You can post new topics in this forum
You can reply to topics in this forum


Powered by phpBB © 2001, 2005 phpBB Group