none
SendMessage Spotify RRS feed

  • Question

  • ' Spotify API V0.01 beta - a very quick First draft
    ' © august 3 2009 by Steffest
    ' This code is free to use in any way you want and comes with NO WARRANTIES
    ' tested with Spotify 0.3.18
    ' Usage:
    ' 
    ' Dim Spotify As New Spotify()
    ' 
    ' Spotify.PlayPause()
    ' Spotify.PlayPrev()
    ' Spotify.PlayNext()
    ' Spotify.Mute()
    ' Spotify.VolumeUp()
    ' Spotify.VolumeDown()
    ' Spotify.Nowplaying() (Gets the name of the current playing track)
    ' Spotify.Search("Artist",False) (Searches for "Artist")
    ' Spotify.Search("Artist",True) (Searches for "Artist" and starts playing the results)
    
    Public Class Spotify
    
    #Region " win32 "
        Private Declare Auto Function FindWindow Lib "user32" (ByVal lpClassName As String, ByVal lpWindowName As String) As IntPtr
        Private Declare Auto Function SendMessage Lib "user32" (ByVal hWnd As IntPtr, ByVal Msg As UInteger, ByVal wParam As IntPtr, ByVal lParam As IntPtr) As IntPtr
        Private Declare Auto Function SetForegroundWindow Lib "user32" (ByVal hWnd As IntPtr) As Boolean
        Private Declare Auto Function keybd_event Lib "user32" (ByVal bVk As Byte, ByVal bScan As Byte, ByVal dwFlags As Integer, ByVal dwExtraInfo As Integer) As Boolean
        Private Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long)
        Private Declare Auto Function GetWindowText Lib "user32" (ByVal hwnd As IntPtr, ByVal lpString As String, ByVal cch As IntPtr) As IntPtr
        Private Declare Auto Function SetWindowText Lib "user32" (ByVal hwnd As IntPtr, ByVal lpString As String) As Boolean
        Private Declare Auto Function EnumChildWindows Lib "user32" (ByVal hWndParent As Long, ByVal lpEnumFunc As Long, ByVal lParam As Long) As Long
    #End Region
    
    #Region " constants "
        Private Const WM_KEYDOWN = &H100
        Private Const WM_KEYUP = &H101
        Private Const WM_MOUSEACTIVATE = &H21
        Private Const KEYEVENTF_EXTENDEDKEY As Integer = &H1S
        Private Const KEYEVENTF_KEYUP As Integer = &H2S
    #End Region
    
        Private w As Integer
    
        Public Sub New()
            w = FindWindow("SpotifyMainWindow", vbNullString)
        End Sub
    
    
        Public Const VK_SPACE = &H20
    
        Public Function PlayPause() As Boolean
            On Error Resume Next
            SendMessage(w, WM_KEYDOWN, Keys.Space, 0)
            SendMessage(w, WM_KEYUP, Keys.Space, 0)
    
    
    
        End Function
    
        Public Function PlayPrev() As Boolean
            On Error Resume Next
            ' for some reason the PostMessage(w, WM_KEYDOWN, Keys.MediaNextTrack, 0) doesn't work
            ' sending ctrl+ commands to a windows still is a PITA ...
            SetForegroundWindow(w)
            keybd_event(Keys.ControlKey, &H1D, 0, 0)
            keybd_event(Keys.Left, &H45S, KEYEVENTF_EXTENDEDKEY Or 0, 0)
            keybd_event(Keys.Left, &H45S, KEYEVENTF_EXTENDEDKEY Or KEYEVENTF_KEYUP, 0)
            Sleep(100) ' wait until spotify has trapped the control key before releasing it
            keybd_event(Keys.ControlKey, &H1D, KEYEVENTF_KEYUP, 0)
        End Function
    
        Public Function PlayNext() As Boolean
            On Error Resume Next
            SetForegroundWindow(w)
            keybd_event(Keys.ControlKey, &H1D, 0, 0)
            keybd_event(Keys.Right, &H45S, KEYEVENTF_EXTENDEDKEY Or 0, 0)
            keybd_event(Keys.Right, &H45S, KEYEVENTF_EXTENDEDKEY Or KEYEVENTF_KEYUP, 0)
            Sleep(100) ' wait until spotify has trapped the control key before releasing it
            keybd_event(Keys.ControlKey, &H1D, KEYEVENTF_KEYUP, 0)
        End Function
    
        Public Function VolumeUp() As Boolean
            On Error Resume Next
            SetForegroundWindow(w)
            keybd_event(Keys.ControlKey, &H1D, 0, 0)
            keybd_event(Keys.Up, &H45S, KEYEVENTF_EXTENDEDKEY Or 0, 0)
            keybd_event(Keys.Up, &H45S, KEYEVENTF_EXTENDEDKEY Or KEYEVENTF_KEYUP, 0)
            Sleep(100) ' wait until spotify has trapped the control key before releasing it
            keybd_event(Keys.ControlKey, &H1D, KEYEVENTF_KEYUP, 0)
        End Function
    
        Public Function Mute() As Boolean
            On Error Resume Next
            SetForegroundWindow(w)
            keybd_event(Keys.ControlKey, &H1D, 0, 0)
            keybd_event(Keys.ShiftKey, &H1D, 0, 0)
            keybd_event(Keys.Down, &H45S, KEYEVENTF_EXTENDEDKEY Or 0, 0)
            keybd_event(Keys.Down, &H45S, KEYEVENTF_EXTENDEDKEY Or KEYEVENTF_KEYUP, 0)
            Sleep(100) ' wait until spotify has trapped the control key before releasing it
            keybd_event(Keys.ShiftKey, &H1D, KEYEVENTF_KEYUP, 0)
            keybd_event(Keys.ControlKey, &H1D, KEYEVENTF_KEYUP, 0)
        End Function
    
        Public Function VolumeDown() As Boolean
            On Error Resume Next
            SetForegroundWindow(w)
            keybd_event(Keys.ControlKey, &H1D, 0, 0)
            keybd_event(Keys.Down, &H45S, KEYEVENTF_EXTENDEDKEY Or 0, 0)
            keybd_event(Keys.Down, &H45S, KEYEVENTF_EXTENDEDKEY Or KEYEVENTF_KEYUP, 0)
            Sleep(100) ' wait until spotify has trapped the control key before releasing it
            keybd_event(Keys.ControlKey, &H1D, KEYEVENTF_KEYUP, 0)
        End Function
    
        Public Function Nowplaying() As String
            On Error Resume Next
            Dim lpText As String
            lpText = New String(Chr(0), 100)
            Dim intLength As Integer = GetWindowText(w, lpText, lpText.Length)
            If (intLength <= 0) OrElse (intLength > lpText.Length) Then Return "Unknown"
            Dim strTitle As String = lpText.Substring(0, intLength)
            strTitle = Mid(strTitle, 11)
            Return strTitle
        End Function
    
        Public Function Search(ByVal s As String, ByVal AndPlay As Boolean) As Boolean
            On Error Resume Next
            SetForegroundWindow(w)
            keybd_event(Keys.ControlKey, &H1D, 0, 0)
            keybd_event(Keys.L, &H45S, KEYEVENTF_EXTENDEDKEY Or 0, 0)
            keybd_event(Keys.L, &H45S, KEYEVENTF_EXTENDEDKEY Or KEYEVENTF_KEYUP, 0)
            Sleep(100) ' wait until spotify has trapped the control key before releasing it
            keybd_event(Keys.ControlKey, &H1D, KEYEVENTF_KEYUP, 0)
    
            SendKeys.SendWait(s & Chr(13))
    
            If AndPlay Then
                ' this is a bit stupid but works in this version: press tab twice, then enter
                Sleep(100)
                SendKeys.SendWait(Chr(9) & Chr(9) & Chr(13))
            End If
    
        End Function
    
    End Class

    The option PlayPause() isn't working.


    The Keyboard Shortcuts for play in spotfy is "Space"

    https://support.spotify.com/us/using_spotify/system_settings/keyboard-shortcuts/

    Thursday, January 4, 2018 1:57 AM

All replies

  •  So why not just use the keybd_event api function to press and release the space bar? 

    If you say it can`t be done then i`ll try it

    Thursday, January 4, 2018 2:22 AM
  • Could you show me how ?
    Thursday, January 4, 2018 2:28 AM
  • Could you show me how ?

     I don't have Spotify so,  i can not test it to see what the class name actually is but,  if the other subs in your code work then this should find the window,  set it as the foreground window,  and press/release the spacebar.

     
    Imports System.Runtime.InteropServices
    
    Public Class Form1
        Private Const KEYEVENTF_KEYDOWN As Integer = &H0
        Private Const KEYEVENTF_KEYUP As Integer = &H2
    
        <DllImport("user32.dll")> Public Shared Sub keybd_event(ByVal bVk As Byte, ByVal bScan As Byte, ByVal dwFlags As UInteger, ByVal dwExtraInfo As UInteger)
        End Sub
    
        <DllImport("user32.dll", EntryPoint:="FindWindowW")>
        Public Shared Function FindWindowW(<MarshalAs(UnmanagedType.LPTStr)> ByVal lpClassName As String, <MarshalAs(UnmanagedType.LPTStr)> ByVal lpWindowName As String) As IntPtr
        End Function
    
        <DllImport("user32.dll")> Public Shared Function SetForegroundWindow(ByVal hWnd As IntPtr) As <MarshalAs(UnmanagedType.Bool)> Boolean
        End Function
    
        Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
            Dim hWnd As IntPtr = FindWindowW("SpotifyMainWindow", Nothing)
            If hWnd <> IntPtr.Zero Then
                If SetForegroundWindow(hWnd) Then
                    keybd_event(CByte(Keys.Space), 0, KEYEVENTF_KEYDOWN, 0)
                    keybd_event(CByte(Keys.Space), 0, KEYEVENTF_KEYUP, 0)
                End If
            Else
                MessageBox.Show("SpotifyMainWindow not found.")
            End If
        End Sub
    End Class
    

     

     On another note,  you would probably be further ahead using UIAutomation to do all this automation of an external 3rd party application.  It would be much more reliable than shifting windows in and out of focus and simulating keys being pressed/released.  This is an unreliable way to go at it because a user or other application can shift the focus to another window at any time.  Not to mention,  the keys will be sent to another application if the wrong window has focus.


    If you say it can`t be done then i`ll try it

    Thursday, January 4, 2018 2:43 AM
  • Works, but the mais windows need to be maximazed, with SendMessage can be minimized, for UIAutomation you have some thing good to read about ?

    Thanks for help

    Thursday, January 4, 2018 10:16 PM
  • Works, but the mais windows need to be maximazed, with SendMessage can be minimized, for UIAutomation you have some thing good to read about ?

    Thanks for help

     If the code you are using for the SendMessage function is not working then the control that receives and processes the message when the window is showing,  may be a Button control,  not the window.

     If it is actually a button type control,  you could use a hand full of other win32 api functions to iterate through the controls and find the handle of the Button,  then send a BM_CLICK message to it's handle.  Iterating through the control windows can be done with the EnumChildWindows or FindWindowEx function.  SendMessage would be used to send the BM_CLICK message.

     Either way,  UIAutomation would be the best approach,  although i can not say if it would work for doing this with a minimized 'Spotify' window.  It may,  it may not.  You can start reading about UIAutomation at the msdn link below.  There are several examples on the internet and here on this forum for using it in Vb.Net.

    https://docs.microsoft.com/en-us/dotnet/framework/ui-automation/index


    If you say it can`t be done then i`ll try it

    Friday, January 5, 2018 12:31 AM