Jump to content

GUICtrlCreatePic in WMPlayer.ocx


Emanoel
 Share

Recommended Posts

@CYCho : yeah it's nice like that, centered, as in the usual players.
By the way, the line Local $iPos = 0 isn't needed anymore (I think Nine deleted it in his last edited script)

@Nine : more important, I found something that needs a fix.
1) Let's say the music plays and you press the Pause Button => music stops and shuttle doesn't move anymore, Button caption changes to "Resume", all this is normal.

2) Then you left click anywhere inside the $idSongName control area (not on the shuttle) => Case $GUI_EVENT_PRIMARYDOWN is triggered, the shuttle new position is correctly calculated (GUICtrlSetPos), the media currentPosition property too ($oPlayer.Controls.currentPosition) and the music is heard again ($oPlayer.Controls.Play)

Issue : the shuttle doesn't move anymore while the music is playing again and the Button still indicates "Resume" (it should indicate "Pause" because the music is now playing)

Adding 2 lines could fix this :

Case $GUI_EVENT_PRIMARYDOWN
    If GUIGetCursorInfo()[4] = $idSongName Then
        GUICtrlSetPos($idShuttle, MouseGetPos(0))
        $x = MouseGetPos(0) / $iSliderLength * $iMediaLength
        $oPlayer.Controls.currentPosition = $x > $iMediaLength ? $iMediaLength : $x
        $oPlayer.Controls.Play
        AdlibRegister(Slider, $adlibInterval) ; <============ added
        GUICtrlSetData($idPause, "Pause")     ; <============ added
    EndIf

But... there's a 2nd case that should be considered : imagine the music is playing and we left click anywhere inside the $idSongName control area (not on the shuttle) => Case $GUI_EVENT_PRIMARYDOWN is triggered.

In this 2nd case, the last 3 lines in Case $GUI_EVENT_PRIMARYDOWN aren't needed anymore and everything will work fine when they're commented :

Case $GUI_EVENT_PRIMARYDOWN
    If GUIGetCursorInfo()[4] = $idSongName Then
        GUICtrlSetPos($idShuttle, MouseGetPos(0))
        $x = MouseGetPos(0) / $iSliderLength * $iMediaLength
        $oPlayer.Controls.currentPosition = $x > $iMediaLength ? $iMediaLength : $x
;~      $oPlayer.Controls.Play
;~      AdlibRegister(Slider, $adlibInterval)
;~      GUICtrlSetData($idPause, "Pause")
    EndIf

To solve both cases, maybe a test could be done (based on the Button caption "Resume" or "Pause") to know when the 3 lines just above are required (when the caption is "Resume") or superfluous (when the caption is "Pause")

The easy way could be to use the 3 lines in both cases, but isn't it a bit dangerous to AdlibRegister() over and over without AdlibUnRegister() ?
Good luck

Link to comment
Share on other sites

I rewrite my code to have the feature "change position of song by clicking on slider bar". When I add ElseIf ... (line 99-103), shuttle button goes to end of song and gui closes immediately.

#include <GuiConstants.au3>
#include <Misc.au3>
Global $SliderButton = @ScriptDir & "\SliderButton.jpg"

$hGui = GUICreate("Music Player", 400, 75, -1, -1)
$idSongName = GUICtrlCreateButton("", 0, 0, 400, 20)                 ;music file name
GUICtrlSetState(-1, $GUI_DISABLE)
$iShuttleWidth = 20
$ShuttleButton = GUICtrlCreateButton("", 0, 0, $iShuttleWidth, 20)
GUICtrlSetColor(-1, 0x000000)
GUICtrlSetBkColor(-1, 0x646464)
$PauseButton = GUICtrlCreateButton("Pause", 208, 40, 80, 20)
$PlayButton = GUICtrlCreateButton("Play", 112, 40, 80, 20)
$Progress = GUICtrlCreateLabel("0:00", 4, 25, 45, 20, $SS_LEFT)  ; current media position
$Length = GUICtrlCreateLabel("0:00", 350, 25, 45, 20, $SS_RIGHT) ; media length
GUISetState(@SW_SHOW)

$FilePath = "C:\Users\Anonymous\Downloads\Music\Chelsea Wolfe - Two spirit [128].mp3"
$oPlayer = ObjCreate("WMPlayer.OCX")
If Not IsObj($oPlayer) Then
    MsgBox(0, "WMPlayer.OCX", "Cannot create a WMP object.", 5)
    GUIDelete($hGui)
    Exit
EndIf

$iPos = 0                       ; x coordinate of $ShuttleButton control in progress bar
$hDLL = DllOpen("user32.dll")   ; to dectect mouse down on the $ShuttleButton control
$iSliderLength = 370            ; in pixels
$adlibInterval = 250            ; in milliseconds
$oPlayer.URL = ""
$iMediaLength = 0
$mediaPos = 0

$oPlayer.Settings.Volume = 100

$oPlayer.URL = $FilePath
$hTimer = TimerInit()
While $oPlayer.playState <> 3       ; 1 - stopped, 2 - paused, 3 - playing
    If TimerDiff($hTimer) > 3000 Then
        MsgBox(0, "WMPlayer.OCX", $FilePath & @CRLF & @CRLF & "Cannot play this file.", 5)
        ExitLoop
    EndIf
    Sleep(5)
WEnd

$sFile = StringMid($FilePath, StringInStr($FilePath, "\", 0, -1) + 1)
GUICtrlSetData($idSongName, $sFile)
$iMediaLength = Int($oPlayer.currentMedia.Duration)     ; in seconds
GUICtrlSetData($Length, Int($iMediaLength / 60) & ":" & StringFormat("%02i", Mod($iMediaLength, 60)))
AdlibRegister("Slider", $adlibInterval)
$oPlayer.Controls.Pause
While 1
    $nMsg = GUIGetMsg()
    Switch $nMsg
        Case $GUI_EVENT_CLOSE
            $oPlayer.Close
            Exit
        Case $PlayButton
            If GUICtrlRead($PlayButton) = "Play" Then
                $oPlayer.Controls.Play
                AdlibRegister("Slider")
                GUICtrlSetData($PlayButton, "Stop")
            Else
                $oPlayer.Controls.currentPosition = 0
                $oPlayer.Controls.Pause
                GUICtrlSetData($PlayButton, "Play")
            EndIf
        Case $PauseButton
            If GUICtrlRead($PauseButton) = "Pause" Then
                $oPlayer.Controls.Pause
                AdlibUnRegister()
                GUICtrlSetData($PauseButton, "Resume")
            ElseIf GUICtrlRead($PlayButton) <> "Play" And GUICtrlRead($PauseButton) <> "Pause" Then
                $oPlayer.Controls.Play
                AdlibRegister("Slider")
                GUICtrlSetData($PauseButton, "Pause")
            EndIf
        Case $GUI_EVENT_PRIMARYDOWN
            If GUIGetCursorInfo()[4] = $ShuttleButton Then
                AdlibUnRegister()
                $x = MouseGetPos(0)
                $xOffset = $x - $iPos
                While _IsPressed("01", $hDLL) = 1
                    $x = MouseGetPos(0)
                    If $x > 380 + $xOffset Then
                        $x = 380 + $xOffset
                    ElseIf $x < $xOffset Then
                        $x = $xOffset
                    EndIf
                    $iPos = $x - $xOffset
                    GUICtrlSetPos($ShuttleButton, $iPos)
                    Sleep(10)
                WEnd
                $mediaPos = $iPos / $iSliderLength * $iMediaLength
                $oPlayer.Controls.currentPosition = $mediaPos
                $oPlayer.Controls.Play
                AdlibRegister("Slider", $adlibInterval)
            ElseIf GUIGetCursorInfo()[4] = $idSongName Then
                GUICtrlSetPos($ShuttleButton, MouseGetPos(0) - $iShuttleWidth / 2)
                $x = (MouseGetPos(0) - $iShuttleWidth / 2) / $iSliderLength * $iMediaLength
                $oPlayer.Controls.currentPosition = $x > $iMediaLength ? $iMediaLength : $x
                $oPlayer.Controls.Play
            EndIf
    EndSwitch
    If $oPlayer.playState = 1 Then
        ExitLoop
    EndIf
WEnd

Func Slider()
    $mediaPos = $oPlayer.Controls.currentPosition
    $iPos = $mediaPos * $iSliderLength / $iMediaLength
    GUICtrlSetPos($ShuttleButton, $iPos)
    GUICtrlSetData($Progress, Int($mediaPos / 60) & ":" & StringFormat("%02i", Mod($mediaPos, 60)))
EndFunc   ;==>Slider

 

Link to comment
Share on other sites

Alright guys.  I implemented your suggestions.  I added back and forward song buttons.  I thought I would use the actual object to know the play state.  I also remove the blinking of the current play time.

Spoiler
#include <GUIConstantsEx.au3>
#include <StaticConstants.au3>
#include <Constants.au3>
#include <Misc.au3>
#include <GDIPlus.au3>
#include <Array.au3>

Opt("MustDeclareVars", 1)
Opt("MouseCoordMode", 2)

Local $tImage
_GDIPlus_Startup()
Local $hImage = _ConvertStringToImage($tImage, 18, 18)
Local $hBitmap = _GDIPlus_BitmapCreateHBITMAPFromBitmap($hImage)
_GDIPlus_ImageDispose($hImage)
_GDIPlus_Shutdown()

Local $hGui = GUICreate("WMPlayer.OCX", 400, 75, -1, -1)
Local $idSongName = GUICtrlCreateButton("", 0, 0, 400, 20)
GUICtrlSetState(-1, $GUI_DISABLE)
Local $iShuttleWidth = 18
Local $idShuttle = GUICtrlCreatePic("", 0, 0, $iShuttleWidth, 18)
GUICtrlSendMsg(-1, $STM_SETIMAGE, $IMAGE_BITMAP, $hBitmap)
_WinAPI_DeleteObject($hBitmap)
Local $idPause = GUICtrlCreateButton("Pause", 160, 40, 80, 20)
Local $idProgress = GUICtrlCreateLabel("0:00", 4, 25, 45, 20, $SS_LEFT) ; current media position
Local $idLength = GUICtrlCreateLabel("0:00", 350, 25, 45, 20, $SS_RIGHT) ; media length
Local $idBack = GUICtrlCreateLabel(ChrW(0xD5), 4, 40, 30, 20)
GUICtrlSetFont(-1, 12, $FW_MEDIUM, $GUI_FONTNORMAL, "Wingdings")
Local $idForward = GUICtrlCreateLabel(ChrW(0xD6), 375, 40, 30, 20)
GUICtrlSetFont(-1, 12, $FW_MEDIUM, $GUI_FONTNORMAL, "Wingdings")

GUISetState(@SW_SHOW)

Local $aPlayList[3]     ; Put your own mp3 file paths in this playlist
$aPlayList[0] = 2       ; number of files in the playlist
$aPlayList[1] = "King Crimson - 21st Century Schizoid Man.mp3"
$aPlayList[2] = "ZZTop - La Grange.wav"

For $i = $aPlayList[0] To 1 Step -1
  If Not FileExists($aPlayList[$i]) Then
    _ArrayDelete($aPlayList, $i)
    $aPlayList[0] -= 1
  EndIf
Next
If Not $aPlayList[0] Then Exit MsgBox(0, "WMPlayer.ocx", "None of the files listed in $aPlayList array exists.", 5)

Local $oPlayer = ObjCreate("WMPlayer.OCX")
If Not IsObj($oPlayer) Then Exit MsgBox(0, "WMPlayer.OCX", "Cannot create a WMP object.", 5)

Local $iSliderLength = 380             ; in pixels
Local $adlibInterval = 250            ; in milliseconds
$oPlayer.Settings.Volume = 100

Local $nFile = 0, $sFullPath, $hTimer, $sFile, $iMediaLength, $x
While 1
  $nFile += 1
  If $nFile > $aPlayList[0] Then $nFile = 1
  GUICtrlSetState($idBack, $nFile = 1 ? $GUI_DISABLE : $GUI_ENABLE)
  GUICtrlSetState($idForward, $nFile = $aPlayList[0] ? $GUI_DISABLE : $GUI_ENABLE)

  $sFullPath = $aPlayList[$nFile]

  $oPlayer.URL = $sFullPath
  $hTimer = TimerInit()
  While $oPlayer.playState <> 3     ; 1 - stopped, 2 - paused, 3 - playing
    If TimerDiff($hTimer) > 3000 Then
      MsgBox(0, "WMPlayer.OCX", $sFullPath & @CRLF & @CRLF & "Cannot play this file.", 5)
      ExitLoop
    EndIf
    Sleep(10)
  WEnd
  If $oPlayer.playState <> 3 Then ContinueLoop

  $sFile = StringMid($sFullPath, StringInStr($sFullPath, "\", 0, -1) + 1)
  GUICtrlSetData($idSongName, $sFile)
  $iMediaLength = Int($oPlayer.currentMedia.Duration)   ; in seconds
  GUICtrlSetData($idLength, Int($iMediaLength / 60) & ":" & StringFormat("%02i", Mod($iMediaLength, 60)))
  AdlibRegister(Slider, $adlibInterval)

  While 1
    Switch GUIGetMsg()
      Case $GUI_EVENT_CLOSE
        $oPlayer.Close()
        Exit
      Case $idPause
        If GUICtrlRead($idPause) = "Pause" Then
          $oPlayer.Controls.Pause
          AdlibUnRegister()
          GUICtrlSetData($idPause, "Resume")
        Else
          $oPlayer.Controls.Play
          AdlibRegister(Slider)
          GUICtrlSetData($idPause, "Pause")
        EndIf
      Case $idShuttle
        AdlibUnRegister()
        While _IsPressed("01")
          $x = MouseGetPos(0)
          GUICtrlSetPos($idShuttle, $x-$iShuttleWidth/2)
          Sleep(10)
        WEnd
        $oPlayer.Controls.currentPosition = ($x-$iShuttleWidth/2) / $iSliderLength * $iMediaLength
        $oPlayer.Controls.Play
        AdlibRegister(Slider, $adlibInterval)
        GUICtrlSetData($idPause, "Pause")
      Case $GUI_EVENT_PRIMARYDOWN
        If GUIGetCursorInfo()[4] = $idSongName Then
          GUICtrlSetPos($idShuttle, MouseGetPos(0)-$iShuttleWidth/2)
          $x = (MouseGetPos(0)-$iShuttleWidth/2) / $iSliderLength * $iMediaLength
          $oPlayer.Controls.currentPosition = $x > $iMediaLength ? $iMediaLength : $x
          If $oPlayer.playState = 2 Then
            $oPlayer.Controls.Play
            AdlibRegister(Slider, $adlibInterval)
            GUICtrlSetData($idPause, "Pause")
          EndIf
        EndIf
      Case $idBack
        $nFile -= 2
        ContinueCase
      Case $idForward
        If $oPlayer.playState = 2 Then GUICtrlSetData($idPause, "Pause")
        ExitLoop
    EndSwitch
    If $oPlayer.playState = 1 Then ExitLoop
  WEnd
WEnd

Func Slider()
  Local Static $iPlayTime
  Local $iMP = Round($oPlayer.Controls.currentPosition)
  Local $iPos = $iMP * $iSliderLength / $iMediaLength
  GUICtrlSetPos($idShuttle, $iPos)
  If $iPlayTime = $iMP Then Return
  GUICtrlSetData($idProgress, Int($iMP / 60) & ":" & StringFormat("%02i", Mod($iMP, 60)))
  $iPlayTime = $iMP
EndFunc   ;==>Slider

; based on https://www.autoitscript.com/forum/topic/204254-saveretrieve-images-tofrom-text-string/

Func _ConvertStringToImage(ByRef $tBuffer, $iWidth, $iHeight)
  Local Const $IMAGE = "FFF6DAFFFFF1D7FF4E341CFF44311CFF40311EFF493726FF4A3020FF563525FF533121FF52331EFF4E331EFF4B351CFF49351CFF4B351CFF52321FFF473125FFF6F5F7FFE2EDF5FFFFF6DCFF54361DFF78634DFF716350FF7D7361FF746757FF745F50FF7F6557FF836657FF816756FF7C6954FF786A53FF786A54FF7A6954FF806856FF7C6758FF2E271EFFF6F7EEFF4E341CFF826D57FF736A56FF6B6957FF616153FF636156FF756C62FF77695DFF746457FF726555FF6E6655FF6B6754FF6B6755FF6D6655FF726557FF776653FF897455FF4D3610FF4E3B26FF6F614EFF6B6957FF707566FF5C6459FF6E736AFF67655DFF666059FF6F685FFF6D695EFF686A5EFF666A5EFF646B5EFF686A5EFF6D685FFF786A58FF876A43FF5E3B09FF3C2D1AFF786E5CFF656557FF5A6257FF5F6963FF545D5AFF5F6260FF696766FF676362FF656460FF5F6560FF5C675FFF5C6660FF5E6560FF636462FF6F6659FF836A48FF5F3E11FF4B3928FF766959FF615F54FF6A6F66FF5B6461FF666E6EFF5D5F60FF6D6A6CFF696466FF656565FF606665FF5C6765FF5C6666FF5E6666FF636468FF70675EFF826A4CFF573910FF472D1DFF7C6758FF797066FF605E56FF5C5F5DFF636566FF696269FF615960FF6A5F67FF676166FF616266FF5F6364FF5E6366FF5F6266FF656167FF6F635FFF82694FFF53360FFF563526FF785E50FF76685CFF6B655EFF676564FF6B686AFF665E65FF70656FFF6D6068FF6B6068FF666267FF626367FF606368FF646268FF69606AFF746360FF836A50FF563912FF543222FF826556FF756558FF6F685FFF686463FF686365FF6C6169FF6D6068FF6F6068FF6B6068FF666267FF626465FF626367FF646367FF696168FF746360FF846A4CFF583A11FF543320FF7F6554FF736656FF6D695EFF666561FF646464FF696267FF6B6068FF6B6068FF696267FF626465FF606465FF606465FF626465FF686267FF72645EFF826A4EFF563912FF4F341FFF7A6752FF6F6756FF6A6A5EFF606661FF5F6564FF646367FF666267FF666267FF626465FF5F6564FF5B6664FF5B6664FF5F6564FF646365FF6F655EFF7D6852FF513818FF4C361DFF766851FF6C6856FF666A5EFF5F6760FF5D6564FF606367FF626367FF626367FF606465FF5B6664FF596763FF596763FF5D6663FF646563FF6D665DFF7D6852FF513818FF4A361DFF766851FF6C6856FF646B5EFF5D6761FF5B6664FF5F6467FF606367FF626367FF606465FF5B6664FF596763FF5B6761FF5D6761FF646561FF70665CFF806A4EFF563914FF4D351FFF786752FF6E6756FF686A5EFF5F6661FF5D6565FF606368FF646268FF646268FF626465FF5F6564FF5D6663FF5F6661FF626661FF686561FF74665AFF846B4BFF5A3A11FF533320FF7E6654FF736658FF6D685FFF646563FF626465FF666268FF696168FF696168FF686267FF646365FF626563FF646561FF686561FF6F6361FF79655AFF866A4CFF583912FF513322FF7F6554FF766656FF74685CFF6D665DFF6D655EFF706361FF726361FF726361FF726360FF6F6460FF6D655EFF6F665DFF72665CFF77645CFF7D6657FF82694FFF513816FFFFF8E7FF463220FF83705BFF7B6952FF7B6650FF7F6950FF7F674FFF7E664EFF816854FF806854FF7E6954FF7E6954FF7E6954FF806953FF836951FF816953FF483520FFFFF4DEFFFFEFDEFFFFF1DEFF442F19FF483117FF5A4121FF4F3412FF563815FF583C1AFF533617FF523618FF50351AFF50351AFF50351AFF503618FF533518FF4E361AFFF9E9D8FFFFFFF4FF"
  Return _ReadImageFromText($tBuffer, $IMAGE, $iWidth, $iHeight)
EndFunc   ;==>_ConvertStringToImage

Func _ReadImageFromText(ByRef $tByte, $sString, $iWidth, $iHeight, $bFileName = False)
  ; Recreate image from text file
  If $bFileName Then $sString = FileRead($sString)
  Local $dData = Binary("0x" & $sString)
  $tByte = DllStructCreate("byte string[" & $iWidth * $iHeight * 4 & "]")
  DllStructSetData($tByte, 1, $dData)
  Return _GDIPlus_BitmapCreateFromScan0($iWidth, $iHeight, $GDIP_PXF32ARGB, $iWidth * 4, DllStructGetPtr($tByte, "string"))
EndFunc   ;==>_ReadImageFromText

 

 

Edited by Nine
Link to comment
Share on other sites

@Emanoel  There is an extremely important Opt at the beginning of the script... But now you are mixing old and new code.  At the current state, your script will never work correctly.

Edited by Nine
Link to comment
Share on other sites

Link to comment
Share on other sites

@Nine : all sounds good now, great piece of code and bravo for the back and forward song buttons !

There's just one line that should be modified to match all others AdlibRegister() syntax, in case someone changes the default value of $adlibInterval = 250 to something else :

AdlibRegister(Slider)

AdlibRegister(Slider, $adlibInterval)

Thanks @Emanoel & @CYCho for your ideas
Time to prepare the playlist :)

Link to comment
Share on other sites

Changed the symbols for back and forward (didn't like them much).  Made a separate func to load image. And corrected bug found by @pixelsearch

Spoiler
#include <GUIConstantsEx.au3>
#include <StaticConstants.au3>
#include <Constants.au3>
#include <Misc.au3>
#include <GDIPlus.au3>
#include <Array.au3>

Opt("MustDeclareVars", 1)
Opt("MouseCoordMode", 2)

Local $hGui = GUICreate("WMPlayer.OCX", 400, 75, -1, -1)
GUISetBkColor(0xFFFFFF)
Local $idSongName = GUICtrlCreateButton("", 0, 0, 400, 20)
GUICtrlSetState(-1, $GUI_DISABLE)
Local $iShuttleWidth = 18
Local $idShuttle = GUICtrlCreatePic("", 0, 0, $iShuttleWidth, 18)
Local $hBitmap = LoadImage(_ConvertStringToImage, $iShuttleWidth, 18)
GUICtrlSendMsg(-1, $STM_SETIMAGE, $IMAGE_BITMAP, $hBitmap)
_WinAPI_DeleteObject($hBitmap)
Local $idPause = GUICtrlCreateButton("Pause", 160, 42, 80, 24)
GUICtrlSetFont(-1, 9)
Local $idProgress = GUICtrlCreateLabel("0:00", 4, 25, 45, 20, $SS_LEFT) ; current media position
Local $idLength = GUICtrlCreateLabel("0:00", 350, 25, 45, 20, $SS_RIGHT) ; media length
Local $idBack = GUICtrlCreateLabel(ChrW(0x276C) & ChrW(0x276C), 6, 40, 30, 30)
GUICtrlSetFont(-1, 14, $FW_SEMIBOLD, $GUI_FONTNORMAL, "Segoe UI Symbol")
Local $idForward = GUICtrlCreateLabel(ChrW(0x276D) & ChrW(0x276D), 380, 40, 30, 20)
GUICtrlSetFont(-1, 14, $FW_SEMIBOLD, $GUI_FONTNORMAL, "Segoe UI Symbol")

Local $aPlayList[5]     ; Put your own mp3 file paths in this playlist
$aPlayList[0] = 4       ; number of files in the playlist
$aPlayList[1] = "C:\Applications\AutoIt\WASApi\King Crimson - 21st Century Schizoid Man.mp3"
$aPlayList[2] = "C:\Applications\AutoIt\WASApi\ZZTop - La Grange.mp3"
$aPlayList[3] = "C:\Applications\AutoIt\WASApi\Don Henley - The Boys of Summer.mp3"
$aPlayList[4] = "C:\Applications\AutoIt\WASApi\Vanilla Fudge - You Keep me Hanging on.mp3"

For $i = $aPlayList[0] To 1 Step -1
  If Not FileExists($aPlayList[$i]) Then
    _ArrayDelete($aPlayList, $i)
    $aPlayList[0] -= 1
  EndIf
Next
If Not $aPlayList[0] Then Exit MsgBox(0, "WMPlayer.ocx", "None of the files listed in $aPlayList array exists.", 5)

Local $oPlayer = ObjCreate("WMPlayer.OCX")
If Not IsObj($oPlayer) Then Exit MsgBox(0, "WMPlayer.OCX", "Cannot create a WMP object.", 5)

Local $iSliderLength = 380             ; in pixels
Local $adlibInterval = 250            ; in milliseconds
$oPlayer.Settings.Volume = 100

GUISetState(@SW_SHOW)

Local $nFile = 0, $sFullPath, $hTimer, $sFile, $iMediaLength, $x
While 1
  $nFile += 1
  If $nFile > $aPlayList[0] Then $nFile = 1
  GUICtrlSetState($idBack, $nFile = 1 ? $GUI_DISABLE : $GUI_ENABLE)
  GUICtrlSetState($idForward, $nFile = $aPlayList[0] ? $GUI_DISABLE : $GUI_ENABLE)

  $sFullPath = $aPlayList[$nFile]

  $oPlayer.URL = $sFullPath
  $hTimer = TimerInit()
  While $oPlayer.playState <> 3     ; 1 - stopped, 2 - paused, 3 - playing
    If TimerDiff($hTimer) > 3000 Then
      MsgBox(0, "WMPlayer.OCX", $sFullPath & @CRLF & @CRLF & "Cannot play this file.", 5)
      ExitLoop
    EndIf
    Sleep(10)
  WEnd
  If $oPlayer.playState <> 3 Then ContinueLoop

  $sFile = StringMid($sFullPath, StringInStr($sFullPath, "\", 0, -1) + 1)
  GUICtrlSetData($idSongName, $sFile)
  $iMediaLength = Int($oPlayer.currentMedia.Duration)   ; in seconds
  GUICtrlSetData($idLength, Int($iMediaLength / 60) & ":" & StringFormat("%02i", Mod($iMediaLength, 60)))
  AdlibRegister(Slider, $adlibInterval)

  While 1
    Switch GUIGetMsg()
      Case $GUI_EVENT_CLOSE
        $oPlayer.Close()
        Exit
      Case $idPause
        If GUICtrlRead($idPause) = "Pause" Then
          $oPlayer.Controls.Pause
          AdlibUnRegister()
          GUICtrlSetData($idPause, "Resume")
        Else
          $oPlayer.Controls.Play
          AdlibRegister(Slider, $adlibInterval)
          GUICtrlSetData($idPause, "Pause")
        EndIf
      Case $idShuttle
        AdlibUnRegister()
        While _IsPressed("01")
          $x = MouseGetPos(0)
          GUICtrlSetPos($idShuttle, $x - $iShuttleWidth / 2)
          Sleep(10)
        WEnd
        $oPlayer.Controls.currentPosition = ($x - $iShuttleWidth / 2) / $iSliderLength * $iMediaLength
        $oPlayer.Controls.Play
        AdlibRegister(Slider, $adlibInterval)
        GUICtrlSetData($idPause, "Pause")
      Case $GUI_EVENT_PRIMARYDOWN
        If GUIGetCursorInfo()[4] = $idSongName Then
          GUICtrlSetPos($idShuttle, MouseGetPos(0) - $iShuttleWidth / 2)
          $x = (MouseGetPos(0) - $iShuttleWidth / 2) / $iSliderLength * $iMediaLength
          $oPlayer.Controls.currentPosition = $x > $iMediaLength ? $iMediaLength : $x
          If $oPlayer.playState = 2 Then
            $oPlayer.Controls.Play
            AdlibRegister(Slider, $adlibInterval)
            GUICtrlSetData($idPause, "Pause")
          EndIf
        EndIf
      Case $idBack
        $nFile -= 2
        ContinueCase
      Case $idForward
        If $oPlayer.playState = 2 Then GUICtrlSetData($idPause, "Pause")
        ExitLoop
    EndSwitch
    If $oPlayer.playState = 1 Then ExitLoop
  WEnd
WEnd

Func Slider()
  Local Static $iPlayTime
  Local $iMP = Round($oPlayer.Controls.currentPosition)
  Local $iPos = $iMP * $iSliderLength / $iMediaLength
  GUICtrlSetPos($idShuttle, $iPos)
  If $iPlayTime = $iMP Then Return
  GUICtrlSetData($idProgress, Int($iMP / 60) & ":" & StringFormat("%02i", Mod($iMP, 60)))
  $iPlayTime = $iMP
EndFunc   ;==>Slider

; based on https://www.autoitscript.com/forum/topic/204254-saveretrieve-images-tofrom-text-string/

Func _ConvertStringToImage(ByRef $tBuffer, $iWidth, $iHeight)
  Local Const $IMAGE = "FFF6DAFFFFF1D7FF4E341CFF44311CFF40311EFF493726FF4A3020FF563525FF533121FF52331EFF4E331EFF4B351CFF49351CFF4B351CFF52321FFF473125FFF6F5F7FFE2EDF5FFFFF6DCFF54361DFF78634DFF716350FF7D7361FF746757FF745F50FF7F6557FF836657FF816756FF7C6954FF786A53FF786A54FF7A6954FF806856FF7C6758FF2E271EFFF6F7EEFF4E341CFF826D57FF736A56FF6B6957FF616153FF636156FF756C62FF77695DFF746457FF726555FF6E6655FF6B6754FF6B6755FF6D6655FF726557FF776653FF897455FF4D3610FF4E3B26FF6F614EFF6B6957FF707566FF5C6459FF6E736AFF67655DFF666059FF6F685FFF6D695EFF686A5EFF666A5EFF646B5EFF686A5EFF6D685FFF786A58FF876A43FF5E3B09FF3C2D1AFF786E5CFF656557FF5A6257FF5F6963FF545D5AFF5F6260FF696766FF676362FF656460FF5F6560FF5C675FFF5C6660FF5E6560FF636462FF6F6659FF836A48FF5F3E11FF4B3928FF766959FF615F54FF6A6F66FF5B6461FF666E6EFF5D5F60FF6D6A6CFF696466FF656565FF606665FF5C6765FF5C6666FF5E6666FF636468FF70675EFF826A4CFF573910FF472D1DFF7C6758FF797066FF605E56FF5C5F5DFF636566FF696269FF615960FF6A5F67FF676166FF616266FF5F6364FF5E6366FF5F6266FF656167FF6F635FFF82694FFF53360FFF563526FF785E50FF76685CFF6B655EFF676564FF6B686AFF665E65FF70656FFF6D6068FF6B6068FF666267FF626367FF606368FF646268FF69606AFF746360FF836A50FF563912FF543222FF826556FF756558FF6F685FFF686463FF686365FF6C6169FF6D6068FF6F6068FF6B6068FF666267FF626465FF626367FF646367FF696168FF746360FF846A4CFF583A11FF543320FF7F6554FF736656FF6D695EFF666561FF646464FF696267FF6B6068FF6B6068FF696267FF626465FF606465FF606465FF626465FF686267FF72645EFF826A4EFF563912FF4F341FFF7A6752FF6F6756FF6A6A5EFF606661FF5F6564FF646367FF666267FF666267FF626465FF5F6564FF5B6664FF5B6664FF5F6564FF646365FF6F655EFF7D6852FF513818FF4C361DFF766851FF6C6856FF666A5EFF5F6760FF5D6564FF606367FF626367FF626367FF606465FF5B6664FF596763FF596763FF5D6663FF646563FF6D665DFF7D6852FF513818FF4A361DFF766851FF6C6856FF646B5EFF5D6761FF5B6664FF5F6467FF606367FF626367FF606465FF5B6664FF596763FF5B6761FF5D6761FF646561FF70665CFF806A4EFF563914FF4D351FFF786752FF6E6756FF686A5EFF5F6661FF5D6565FF606368FF646268FF646268FF626465FF5F6564FF5D6663FF5F6661FF626661FF686561FF74665AFF846B4BFF5A3A11FF533320FF7E6654FF736658FF6D685FFF646563FF626465FF666268FF696168FF696168FF686267FF646365FF626563FF646561FF686561FF6F6361FF79655AFF866A4CFF583912FF513322FF7F6554FF766656FF74685CFF6D665DFF6D655EFF706361FF726361FF726361FF726360FF6F6460FF6D655EFF6F665DFF72665CFF77645CFF7D6657FF82694FFF513816FFFFF8E7FF463220FF83705BFF7B6952FF7B6650FF7F6950FF7F674FFF7E664EFF816854FF806854FF7E6954FF7E6954FF7E6954FF806953FF836951FF816953FF483520FFFFF4DEFFFFEFDEFFFFF1DEFF442F19FF483117FF5A4121FF4F3412FF563815FF583C1AFF533617FF523618FF50351AFF50351AFF50351AFF503618FF533518FF4E361AFFF9E9D8FFFFFFF4FF"
  Return _ReadImageFromText($tBuffer, $IMAGE, $iWidth, $iHeight)
EndFunc   ;==>_ConvertStringToImage

Func _ReadImageFromText(ByRef $tByte, $sString, $iWidth, $iHeight, $bFileName = False)
  ; Recreate image from text file
  If $bFileName Then $sString = FileRead($sString)
  Local $dData = Binary("0x" & $sString)
  $tByte = DllStructCreate("byte string[" & $iWidth * $iHeight * 4 & "]")
  DllStructSetData($tByte, 1, $dData)
  Return _GDIPlus_BitmapCreateFromScan0($iWidth, $iHeight, $GDIP_PXF32ARGB, $iWidth * 4, DllStructGetPtr($tByte, "string"))
EndFunc   ;==>_ReadImageFromText

Func LoadImage($fFunc, $iWidth, $iHeight)
  Local $tImage
  _GDIPlus_Startup()
  Local $hImage = $fFunc($tImage, $iWidth, $iHeight)
  Local $hBitmap = _GDIPlus_BitmapCreateHBITMAPFromBitmap($hImage)
  _GDIPlus_ImageDispose($hImage)
  _GDIPlus_Shutdown()
  Return $hBitmap
EndFunc   ;==>LoadImage

 

Have fun !

Thanks to all for your ideas and testings.  Special thanks to @CYCho for initial code.

Link to comment
Share on other sites

I changed the code and turned the buttons to OnEvent. Now you can drop new file into gui or open it with the "..." button whenever you want, pause the whole program with the "Pause" button.

Opt("GUIOnEventMode", 1)
Opt("GUIResizeMode", 1)
Opt("MouseCoordMode", 2)
#include <Misc.au3>
#include <ButtonConstants.au3>
#include <EditConstants.au3>
#include <GUIConstantsEx.au3>
#include <StaticConstants.au3>
#include <WindowsConstants.au3>

Global $FilePath, $Paused = False
Global $FileExt[] = [".3g2", ".3gp2", ".3gp", ".3gpp", ".aac", ".adt", ".adts", ".aif", ".aifc", ".aiff", ".asf", ".asx", ".au", ".avi", ".cda", _
        ".dvr-ms", ".flac", ".ivf", ".m1v", ".m2ts", ".m3u", ".m4a", ".m4v", ".mid", ".midi", ".mov", ".mp2", ".mp3", ".mp4", ".mp4v", ".mpa", ".mpe", _
        ".mpeg", ".mpg", ".rmi", ".snd", ".wav", ".wax", ".wm", ".wma", ".wmd", ".wms", ".wmv", ".wmx", ".wmz", ".wpl", ".wvx"]
$oPlayer = ObjCreate("WMPlayer.OCX")
$iPos = 0                       ; x coordinate of $ShuttleButton control in progress bar
$hDLL = DllOpen("user32.dll")   ; to dectect mouse down on the $ShuttleButton control
$iSliderLength = 421            ; in pixels
$adlibInterval = 250            ; in milliseconds
$oPlayer.URL = ""
$iMediaLength = 0
$mediaPos = 0
$iShuttleWidth = 25

#Region ### START Koda GUI section ### Form=
$hGui = GUICreate("Music Player", 466, 170, 192, 132, Default, BitOR($WS_EX_TOPMOST, $WS_EX_ACCEPTFILES))
GUISetOnEvent($GUI_EVENT_CLOSE, "CLOSEClicked")
Global $PauseButton = GUICtrlCreateButton("Play", 184, 128, 99, 33)
GUICtrlSetOnEvent($PauseButton, "PauseButton")
Global $InputFile = GUICtrlCreateInput("", 8, 32, 417, 55)
GUICtrlSetState($InputFile, $GUI_DROPACCEPTED)
GUICtrlGetHandle($InputFile)
GUICtrlSetBkColor(-1, 0xE3E3E3)
GUICtrlSetCursor(-1, 5)
GUICtrlCreateLabel("Drop your song here or browse it:", 8, 8, 199, 20)
$BrowseButton = GUICtrlCreateButton("...", 432, 32, 27, 25)
GUICtrlSetOnEvent($BrowseButton, "BrowseFile")
Global $Sliderbar = GUICtrlCreateButton("", 8, 96, 451, 25, $BS_CENTER)
GUICtrlSetState(-1, $GUI_DISABLE)
GUICtrlSetBkColor(-1, 0xE3E3E3)
Global $ShuttleButton = GUICtrlCreateButton("", 8, 96, $iShuttleWidth, 25)
GUICtrlSetBkColor(-1, 0x646464)
GUISetOnEvent($GUI_EVENT_PRIMARYDOWN, "_Event_PrimaryDown")
Global $Progress = GUICtrlCreateLabel("0:00", 8, 128, 28, 20, $SS_LEFT)  ; current media position
Global $Length = GUICtrlCreateLabel("0:00", 432, 128, 28, 20, $SS_RIGHT) ; media length
GUISetState(@SW_SHOW)
GUISetOnEvent($GUI_EVENT_DROPPED, "DropFile")
#EndRegion ### END Koda GUI section ###

$oPlayer = ObjCreate("WMPlayer.OCX")
If Not IsObj($oPlayer) Then
    MsgBox(0, "WMPlayer.OCX", "Cannot create a WMP object.", 5)
    GUIDelete($hGui)
    Exit
EndIf

Global $iPos = 0                       ; x coordinate of $ShuttleButton control in progress bar
Global $hDLL = DllOpen("user32.dll")   ; to dectect mouse down on the $ShuttleButton control
Global $SliderLength = 370             ; in pixels
Global $adlibInterval = 250            ; in milliseconds
$oPlayer.URL = ""
Global $mediaLength = 0
Global $mediaPos = 0

$oPlayer.Settings.Volume = 100
While 1
    Sleep(10)
    If $Paused Then
        While $Paused
            Sleep(100)
        WEnd
    EndIf
    If $oPlayer.playState = 3 Then                    ; when song playing
        ;ConsoleWrite("Playing ")                   do whatever you want
    ElseIf $oPlayer.playState = 1 Then              ; when song stopped
        GUICtrlSetData($PauseButton, "Play Again!")
    EndIf
WEnd

Func CLOSEClicked()
    $oPlayer.Close
    Exit
EndFunc   ;==>CLOSEClicked

Func BrowseFile()
    Local $Extension = Null
    For $temp In $FileExt
        $Extension &= "*" & $temp & ";"
    Next
    $Extension = (StringTrimRight($Extension, 1))
    $FilePath = FileOpenDialog("Open Music File", "", "Media Files (" & $Extension & ")", 12)
    If CheckFile() Then
        GUICtrlSetData($InputFile, $FilePath)
        GUICtrlSetData($Sliderbar, _RemoveFileExt(StringMid($FilePath, StringInStr($FilePath, "\", 0, -1) + 1)))
        $oPlayer.URL = $FilePath
        Local $hTimer = TimerInit()
        While $oPlayer.playState <> 3   ; 1 - stopped, 2 - paused, 3 - playing
            If TimerDiff($hTimer) > 3000 Then
                MsgBox(0, "WMPlayer.OCX", $FilePath & @CRLF & @CRLF & "Cannot play this file.", 5)
                ExitLoop
            EndIf
            Sleep(5)
        WEnd
        $oPlayer.Controls.Pause
        $oPlayer.Controls.currentPosition = 0
        $iMediaLength = Int($oPlayer.currentMedia.Duration) ; in seconds
        GUICtrlSetData($Length, Int($iMediaLength / 60) & ":" & StringFormat("%02i", Mod($iMediaLength, 60)))
        AdlibRegister("Slider", $adlibInterval)
        GUICtrlSetData($PauseButton, "Play")
    EndIf
EndFunc   ;==>BrowseFile

Func DropFile()
    $oPlayer.Close
    Switch @GUI_DropId
        Case $InputFile
            $FilePath = GUICtrlRead($InputFile)
            If CheckFile() Then
                GUICtrlSetData($Sliderbar, _RemoveFileExt(StringMid($FilePath, StringInStr($FilePath, "\", 0, -1) + 1)))
                $oPlayer.URL = $FilePath
                Local $hTimer = TimerInit()
                While $oPlayer.playState <> 3 ; 1 - stopped, 2 - paused, 3 - playing
                    If TimerDiff($hTimer) > 3000 Then
                        MsgBox(0, "WMPlayer.OCX", $FilePath & @CRLF & @CRLF & "Cannot play this file.", 5)
                        ExitLoop
                    EndIf
                    Sleep(5)
                WEnd
                $oPlayer.Controls.Pause
                $oPlayer.Controls.currentPosition = 0
                $iMediaLength = Int($oPlayer.currentMedia.Duration) ; in seconds
                GUICtrlSetData($Length, Int($iMediaLength / 60) & ":" & StringFormat("%02i", Mod($iMediaLength, 60)))
                AdlibRegister("Slider", $adlibInterval)
                GUICtrlSetData($PauseButton, "Play")
            EndIf
    EndSwitch
EndFunc   ;==>DropFile

Func PauseButton()
    CheckFile()
    If GUICtrlRead($PauseButton) = "Pause" Then
        $oPlayer.Controls.Pause
        AdlibUnRegister()
        $Paused = True
        GUICtrlSetData($PauseButton, "Resume")
    Else
        $oPlayer.Controls.Play
        AdlibRegister("Slider")
        $Paused = False
        GUICtrlSetData($PauseButton, "Pause")
    EndIf
EndFunc   ;==>PauseButton

Func _Event_PrimaryDown()
    Local $n_msg = GUIGetCursorInfo()[4]
    Switch $n_msg
        Case $ShuttleButton
            AdlibUnRegister()
            $x = MouseGetPos(0)
            $xOffset = $x - $iPos
            While _IsPressed("01")
                $x = MouseGetPos(0)
                GUICtrlSetPos($ShuttleButton, $x - $iShuttleWidth / 2)
                Sleep(10)
            WEnd
            $oPlayer.Controls.currentPosition = ($x - $iShuttleWidth / 2) / $iSliderLength * $iMediaLength
            $oPlayer.Controls.Play
            AdlibRegister("Slider", $adlibInterval)
        Case $Sliderbar
            GUICtrlSetPos($ShuttleButton, MouseGetPos(0) - $iShuttleWidth / 2)
            $x = (MouseGetPos(0) - $iShuttleWidth / 2) / $iSliderLength * $iMediaLength
            $oPlayer.Controls.currentPosition = $x > $iMediaLength ? $iMediaLength : $x
            $oPlayer.Controls.Play
    EndSwitch
EndFunc   ;==>_Event_PrimaryDown

Func CheckFile()
    Local $check = True
    For $temp In $FileExt
        If StringInStr($FilePath, $temp, Default, -1) = False Then
            $check = False
        Else
            $check = True
            ExitLoop
        EndIf
    Next
    If $FilePath = "" Then
        MsgBox(0, "File Error", "The file has not been selected yet.")
        Return 0
    ElseIf $check = False Then
        MsgBox(0, "File Error", "The dropped file is not a media file, try again please.")
        Return 0
    EndIf
    Return 1
EndFunc   ;==>CheckFile

Func _RemoveFileExt($string)
    Return StringLeft($string, StringInStr($string, ".", Default, -1) - 1)
EndFunc   ;==>_RemoveFileExt

Func Slider()
    $mediaPos = $oPlayer.Controls.currentPosition
    $iPos = $mediaPos * $SliderLength / $mediaLength
    GUICtrlSetPos($ShuttleButton, $iPos)
    GUICtrlSetData($Progress, Int($mediaPos / 60) & ":" & StringFormat("%02i", Mod($mediaPos, 60)))
EndFunc   ;==>Slider

The problem is "Sliderbar" button is located on the Shuttle button (overlapped) 🤔. Since it's my first time working on "GUIOnEventMode", can't fix shuttle button problem.

Edited by Emanoel
Link to comment
Share on other sites

I like the fact that, with the basic music player script (Nine's last script or his precedent one), each one of us can now add some functionality and personalize the script for his own need. I notice that Emanoel did that in the post just above, great :)

My personal need was to be able to quickly modify the volume level and few lines of code just did it (a slider control, no need of tick marks or another fancy design, the pic speaks for itself)

758143677_wmplayerwithrandomslider.png.a7234a4dce83630c119fa530b049ad9d.png

If you want to do same, here are the 3 groups of required lines, you sure will know where to place them, adjusting the coords to your own script :

Local $idVolume = GUICtrlCreateSlider(155, 55, 90, 25, $TBS_NOTICKS)
GUICtrlSetLimit(-1, 100, 0) ; volume level (0 - 100)
GUICtrlSetData(-1, 50) ; initial volume level (50)
...

; Nine's original line below was = 100
$oPlayer.Settings.Volume = 50          ; initial volume level (50)
...

  Case $idVolume
    $oPlayer.Settings.Volume = GUICtrlRead($idVolume)

Something else : the "blue" shuttle in the pic above is just for fun. Its color changes each time the script is run, due to the following script line and 6 little separated pics 18x18 pixels. Let's be creative :sorcerer:

Local $idShuttle = GUICtrlCreatePic(@ScriptDir & "\SliderButton" & Random(1,6,1) & ".jpg", 0, 0, $iShuttleWidth, 18)

SliderButtons.png.fb98fa43ac69732553260da72f0b8110.png

Edited by pixelsearch
Special thanks to @CYCho for initial code (I noticed that just now !)
Link to comment
Share on other sites

@pixelsearch Nice changes! I had trouble changing the shuttle image, and @Nine used several functions and lines to solve it. But now there is no need to add them, I separated picture to 6 parts and used your line for $idShuttle, the problem is solved! Maybe he can explain what happened?

Edited by Emanoel
Link to comment
Share on other sites

11 hours ago, Emanoel said:

The problem is "Sliderbar" button is located on the Shuttle button (overlapped) 🤔

This is because you created $ShuttleButton before the disabled $Sliderbar
I reworked your script a bit, it's not 100% finished but it works better now.

#include <ButtonConstants.au3>
#include <EditConstants.au3>
#include <GUIConstantsEx.au3>
#include <Misc.au3>
#include <StaticConstants.au3>
#include <WindowsConstants.au3>

Opt("GUIOnEventMode", 1)
Opt("GUIResizeMode", 1)
Opt("MouseCoordMode", 2)

Global $FilePath, $Paused = False
Global $FileExt[] = [".3g2", ".3gp2", ".3gp", ".3gpp", ".aac", ".adt", ".adts", ".aif", ".aifc", ".aiff", ".asf", ".asx", ".au", ".avi", ".cda", _
        ".dvr-ms", ".flac", ".ivf", ".m1v", ".m2ts", ".m3u", ".m4a", ".m4v", ".mid", ".midi", ".mov", ".mp2", ".mp3", ".mp4", ".mp4v", ".mpa", ".mpe", _
        ".mpeg", ".mpg", ".rmi", ".snd", ".wav", ".wax", ".wm", ".wma", ".wmd", ".wms", ".wmv", ".wmx", ".wmz", ".wpl", ".wvx"]

Global $iSliderLength = 421            ; in pixels
Global $adlibInterval = 250            ; in milliseconds
Global $iMediaLength = 0
Global $iShuttleWidth = 25

#Region ### START Koda GUI section ### Form=
$hGui = GUICreate("Music Player", 466, 170, 192, 132, Default, BitOR($WS_EX_TOPMOST, $WS_EX_ACCEPTFILES))
GUISetOnEvent($GUI_EVENT_CLOSE, "CLOSEClicked")

Global $PauseButton = GUICtrlCreateButton("Play", 184, 128, 99, 33)
GUICtrlSetOnEvent($PauseButton, "PauseButton")

Global $InputFile = GUICtrlCreateInput("", 8, 32, 417, 55)
GUICtrlSetState($InputFile, $GUI_DROPACCEPTED)
GUICtrlGetHandle($InputFile)
GUICtrlSetBkColor(-1, 0xE3E3E3)
GUICtrlSetCursor(-1, 5)

GUICtrlCreateLabel("Drop your song here or browse it:", 8, 8, 199, 20)

$BrowseButton = GUICtrlCreateButton("...", 432, 32, 27, 25)
GUICtrlSetOnEvent($BrowseButton, "BrowseFile")

Global $Sliderbar = GUICtrlCreateButton("", 8, 96, 451, 25, $BS_CENTER)
GUICtrlSetState(-1, $GUI_DISABLE)
GUICtrlSetBkColor(-1, 0xE3E3E3)

Global $ShuttleButton = GUICtrlCreateButton("", 8, 96, $iShuttleWidth, 25)
GUICtrlSetBkColor(-1, 0x646464)
GUISetOnEvent($GUI_EVENT_PRIMARYDOWN, "_Event_PrimaryDown")

Global $Progress = GUICtrlCreateLabel("0:00", 8, 128, 28, 20, $SS_LEFT)  ; current media position
Global $Length = GUICtrlCreateLabel("0:00", 432, 128, 28, 20, $SS_RIGHT) ; media length

GUISetState(@SW_SHOW)
GUISetOnEvent($GUI_EVENT_DROPPED, "DropFile")
#EndRegion ### END Koda GUI section ###

$oPlayer = ObjCreate("WMPlayer.OCX")
If Not IsObj($oPlayer) Then
    MsgBox(0, "WMPlayer.OCX", "Cannot create a WMP object.", 5)
    GUIDelete($hGui)
    Exit
EndIf

$oPlayer.URL = ""
$oPlayer.Settings.Volume = 100

While 1
    Sleep(10)
    If $Paused Then
        While $Paused
            Sleep(100)
        WEnd
    EndIf
    If $oPlayer.playState = 3 Then                  ; when song playing
        ;ConsoleWrite("Playing ")                   do whatever you want
    ElseIf $oPlayer.playState = 1 Then              ; when song stopped
        GUICtrlSetData($PauseButton, "Play Again!")
    EndIf
WEnd

Func CLOSEClicked()
    $oPlayer.Close
    Exit
EndFunc   ;==>CLOSEClicked

Func BrowseFile()
    Local $Extension = Null
    For $temp In $FileExt
        $Extension &= "*" & $temp & ";"
    Next
    $Extension = (StringTrimRight($Extension, 1))
    $FilePath = FileOpenDialog("Open Music File", "", "Media Files (" & $Extension & ")", 12)
    If CheckFile() Then
        GUICtrlSetData($InputFile, $FilePath)
        GUICtrlSetData($Sliderbar, _RemoveFileExt(StringMid($FilePath, StringInStr($FilePath, "\", 0, -1) + 1)))
        $oPlayer.URL = $FilePath
        Local $hTimer = TimerInit()
        While $oPlayer.playState <> 3   ; 1 - stopped, 2 - paused, 3 - playing
            If TimerDiff($hTimer) > 3000 Then
                MsgBox(0, "WMPlayer.OCX", $FilePath & @CRLF & @CRLF & "Cannot play this file.", 5)
                ExitLoop
            EndIf
            Sleep(5)
        WEnd
        $oPlayer.Controls.Pause
        $oPlayer.Controls.currentPosition = 0
        $iMediaLength = Int($oPlayer.currentMedia.Duration) ; in seconds
        GUICtrlSetData($Length, Int($iMediaLength / 60) & ":" & StringFormat("%02i", Mod($iMediaLength, 60)))
        AdlibRegister("Slider", $adlibInterval)
        GUICtrlSetData($PauseButton, "Play")
    EndIf
EndFunc   ;==>BrowseFile

Func DropFile()
    $oPlayer.Close
    Switch @GUI_DropId
        Case $InputFile
            $FilePath = GUICtrlRead($InputFile)
            If CheckFile() Then
                GUICtrlSetData($Sliderbar, _RemoveFileExt(StringMid($FilePath, StringInStr($FilePath, "\", 0, -1) + 1)))
                $oPlayer.URL = $FilePath
                Local $hTimer = TimerInit()
                While $oPlayer.playState <> 3 ; 1 - stopped, 2 - paused, 3 - playing
                    If TimerDiff($hTimer) > 3000 Then
                        MsgBox(0, "WMPlayer.OCX", $FilePath & @CRLF & @CRLF & "Cannot play this file.", 5)
                        ExitLoop
                    EndIf
                    Sleep(5)
                WEnd
                $oPlayer.Controls.Pause
                $oPlayer.Controls.currentPosition = 0
                $iMediaLength = Int($oPlayer.currentMedia.Duration) ; in seconds
                GUICtrlSetData($Length, Int($iMediaLength / 60) & ":" & StringFormat("%02i", Mod($iMediaLength, 60)))
                AdlibRegister("Slider", $adlibInterval)
                GUICtrlSetData($PauseButton, "Play")
            EndIf
    EndSwitch
EndFunc   ;==>DropFile

Func PauseButton()
    CheckFile()
    If GUICtrlRead($PauseButton) = "Pause" Then
        $oPlayer.Controls.Pause
        AdlibUnRegister()
        $Paused = True
        GUICtrlSetData($PauseButton, "Resume")
    Else
        $oPlayer.Controls.Play
        AdlibRegister("Slider", $adlibInterval)
        $Paused = False
        GUICtrlSetData($PauseButton, "Pause")
    EndIf
EndFunc   ;==>PauseButton

Func _Event_PrimaryDown()
    Local $n_msg = GUIGetCursorInfo()[4]
    Switch $n_msg
        Case $ShuttleButton
            AdlibUnRegister()
            ; $x = MouseGetPos(0)
            ; $xOffset = $x - $iPos
            While _IsPressed("01")
                $x = MouseGetPos(0)
                GUICtrlSetPos($ShuttleButton, $x - $iShuttleWidth / 2)
                Sleep(10)
            WEnd
            $oPlayer.Controls.currentPosition = ($x - $iShuttleWidth / 2) / $iSliderLength * $iMediaLength
            $oPlayer.Controls.Play
            AdlibRegister("Slider", $adlibInterval)
        Case $Sliderbar
            GUICtrlSetPos($ShuttleButton, MouseGetPos(0) - $iShuttleWidth / 2)
            $x = (MouseGetPos(0) - $iShuttleWidth / 2) / $iSliderLength * $iMediaLength
            $oPlayer.Controls.currentPosition = $x > $iMediaLength ? $iMediaLength : $x
            $oPlayer.Controls.Play
    EndSwitch
EndFunc   ;==>_Event_PrimaryDown

Func CheckFile()
    Local $check = True
    For $temp In $FileExt
        If StringInStr($FilePath, $temp, Default, -1) = False Then
            $check = False
        Else
            $check = True
            ExitLoop
        EndIf
    Next
    If $FilePath = "" Then
        MsgBox(0, "File Error", "The file has not been selected yet.")
        Return 0
    ElseIf $check = False Then
        MsgBox(0, "File Error", "The dropped file is not a media file, try again please.")
        Return 0
    EndIf
    Return 1
EndFunc   ;==>CheckFile

Func _RemoveFileExt($string)
    Return StringLeft($string, StringInStr($string, ".", Default, -1) - 1)
EndFunc   ;==>_RemoveFileExt

Func Slider()
    Local Static $iPlayTime
    Local $mediaPos = Round($oPlayer.Controls.currentPosition)
    Local $iPos = $mediaPos * $iSliderLength / $iMediaLength
    GUICtrlSetPos($ShuttleButton, $iPos)
    If $iPlayTime = $mediaPos Then Return
    GUICtrlSetData($Progress, Int($mediaPos / 60) & ":" & StringFormat("%02i", Mod($mediaPos, 60)))
    $iPlayTime = $mediaPos
EndFunc   ;==>Slider

 

Link to comment
Share on other sites

@Nine : good design ! I like these "chevrons" (angle brackets ?)
Glad you kept the original size in your last pic (406 x 108), it's much better for tests on the pic. I guess your client size didn't change, it's still 400 x 75 when mine became 400 x 80, no big deal.

I had a dream (lol) while napping, which will probably lead to something like this (for the visible part) :

2014205138_Ninesplayer1.png.b2a3b584b5bc1dbd6be3810899666650.png

The goal is to keep the code as shorter as possible, while having basic useful functionalities without reinventing the wheel. As modifying the script constantly to change the playlist isn't really user friendly, I'll probably add soon the following changes in the script I use :

* 4 buttons (1st, prec, next, last) as shown in the pic

* Ability to drag and drop one music file in any of the 2 empty rectangular zones at the left or right of the "Resume" button, even if there's no indication where to drop them :

1477400280_Ninesplayer2.png.7151d404589dd75a4b52e6047dc412bf.png

The drop zones will be 2 "big" rectangular label controls (the bigger, the best), no captions on them, so there won't be additional colored dropped zones, we'll see.

*I won't go with WM_DROPFILES message (multi files drag & drop) but stick with a simple @GUI_DragFile (one file), rejecting the file if its extension doesn't suit.

* The file dropped will be added at the end of the already existing $aPlayList array, updating the GUI title at the same time (for example "WMPlayer : 1 on 4" will become "WMPlayer : 1 on 5")

* The file dropped won't be played immediately in case another music file is playing (we'll have to push the ">>" button if we want to listen to the dropped file)

* When the script is exited, all the $aPlayList array will be written to a txt file (same name as the script, extension ".txt")

* A minimal $aPlayList array should remain in the script, at least with one title, because...

* ...the ".txt" file containing a playlist isn't mandatory when we run the script :
1) If the .txt file exists, then it will immediately populate the $aPlayList array
2) If the .txt file doesn't exist, then the "hard-coded" $aPlayList array (containing at least 1 title) will be used.

That's all for today... until the next nap :yawn:

Link to comment
Share on other sites

That's  why I wrote yesterday : now that we got the functional basic player (as found in your last script),  then each one of us will take a different path by adding the functionalities he likes.

For example, you'll probably add in your personalized player the "random/shuffle" or "loop one/loop all" buttons as shown in your last pic, while I'll just add the "1st", "last" and 2 big invisible drop zones... not forgetting the "non mandatory" playlist .txt file and the Topmost attribute for the GUI : it's great to have the GUI on top during drag & drop operations (instead of dragging the file to the taskbar)

Also, for being coherent, when I drop a file inside the GUI, I need this "last" button to be added because the eventual music actually playing shouldn't stop, my need is an automatical "enqueue", just like in this pic (taken from any Browser after a right-click has been done on a music file)

1998785383_enqueueinwinamp.png.e6d0e0e22dbfc85298cdfd4f6d71109b.png

Well... no matter the path each one takes, happy scripting to you all :)

Link to comment
Share on other sites

  • 4 weeks later...

Hi everybody :)
I faced a minor issue when a song title is displayed :

263191988_SonnyCher.png.84de8377878c4482a8cfb5fc7483e7b7.png

It should be written "Sonny & Cher" (as read in the song title) but the "&" is missing in the pic.
Searching here and there, I found 2 possible solutions :

1) Double the && in the title, then one & will be correctly displayed
But this mean you'll have to check each title before it's displayed, not really user friendly.

2) Add a $SS_NOPREFIX static style when creating the control,  in our case it's a... button control :

Local $idSliderZone = GUICtrlCreateButton("", 0, 0, 400, 20, $SS_NOPREFIX)

I didn't know a static style could be added to a button control but it's working fine. Here is what MSDN stipulates about this style :

SS_NOPREFIX : Prevents interpretation of any ampersand (&) characters in the control's text as accelerator prefix characters. These are displayed with the ampersand removed and the next character in the string underlined. This static control style may be included with any of the defined static controls. You can combine SS_NOPREFIX with other styles. This can be useful when filenames or other strings that may contain an ampersand (&) must be displayed in a static control in a dialog box.

I wondered if this style (value 0x0080) could interfere with real button styles. There is a button style having the same value, it's $BS_BITMAP ("Specifies that the button displays a bitmap"). Fortunately, we won't use these 2 styles at same time for different purposes.

& also appears here :

If Not $iTotalSongs Then GUICtrlSetData($idSliderZone, "Playlist is empty : Drag & Drop music files in big empty areas")

Nice place to "send messages" to the user !

Link to comment
Share on other sites

@Nine do you please know if a tooltip created initially with GUICtrlSetTip() can be "dynamic" and contain some kind of variable, for example :

loop.png

I created this one with GUICtrlSetTip(-1, "click to loop")
But later, after the control has been enabled, I would like its tooltip to display "click to unloop" instead of :

loop2.png.ef06a4f98ac327ab52689677d6dbfb57.png

Of course, I could have set it up initially with a  "loop/unloop" caption, but my question is : can a tooltip be created with a "non-static caption" with GUICtrlSetTip() and later be evaluated differently, depending on the content of a variable etc...
Thanks :)

Edited by pixelsearch
Link to comment
Share on other sites

Thanks Nine, so you reset the tooltip each time the variable content changes and not only when the control is created, good idea :)

I applied it immediately to what follows and now I can see the whole content of a field without any scrolling, all this with a simple GUICtrlSetTip() well placed in the script. I knew it was right to ask you !

dynamic.png.ca9648a97889587a173f2d3703c4014a.png

Edit: concerning the player functionalities, I'm keeping Sequential / Random... ("never say never !") but I don't need that "repeat" button, so it's gone... for now. Btw, I made some great changes in the player. Now, even when I'm stuck in the ArrayDisplay GUI While... loop (my playlist), I still have access to all controls of the player (the main GUI above isn't disabled any more), pure magic :)

Edited by pixelsearch
Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

×
×
  • Create New...