Click here to Skip to main content
Click here to Skip to main content

Retrieve the Winamp song title with .NET

, 5 Jan 2004
Rate this:
Please Sign up or sign in to vote.
An article on Winamp and Windows API

Introduction

Ever needed the current Winamp song title? This article describes how to get it using some simple Windows API functions. For example, you could use this code in a nick name changer for an IM program. This code is only tested with Winamp 5, but should also be compatible with all other Winamp versions.

Using the code

First, you need to find the handle of the Winamp window using FindWindow, which is defined in the API reference as follows:

HWND FindWindow(
      LPCTSTR lpClassName,
      LPCTSTR lpWindowName
);

In C# .NET this function is referenced as follows:

[System.Runtime.InteropServices.DllImport("user32.dll", 
    CharSet=System.Runtime.InteropServices.CharSet.Auto)]
public static extern IntPtr FindWindow(string lpClassName, 
    string lpWindowName);

And in VB .NET:

Private Declare Auto Function FindWindow Lib "user32" ( _
    ByVal lpClassName As String, _
    ByVal lpWindowName As String) As IntPtr

It is known that the Winamp class name is "Winamp v1.x". It is not required to specify a window name, so we pass vbNullString (VB) or null (C#) in the function call. If a Winamp windows is found, the return value is its handle, else, the function returns NULL (.NET: IntPtr.Null). Once you have found the window handle, you can retrieve the window's text using GetWindowText:

int GetWindowText(
      HWND hWnd,
      LPTSTR lpString,
      int nMaxCount
);
[System.Runtime.InteropServices.DllImport("user32.dll", 
    CharSet=System.Runtime.InteropServices.CharSet.Auto)]
public static extern int GetWindowText(IntPtr hwnd, 
    string lpString, int cch);
Private Declare Auto Function GetWindowText Lib "user32" ( _
    ByVal hwnd As IntPtr, _
    ByVal lpString As String, _
    ByVal cch As Integer) As Integer

The return value of this function is the length of the window text. If the function succeeds, we have the window text containing the song title. The text consists of the track number (in the current playlist), followed by a dot and a space, then the track title and finally the text " - Winamp". When Winamp is paused or stopped, it may end with " - Winamp [Paused]" or " - Winamp [Stopped]". In this case we want the function to return only the state ("Paused" or "Stopped"). In the other case, we remove " - Winamp" from the end of the string and the track number at the beginning. Finally we remove all spaces from the beginning and the end of the resulting string and find the song title!

Complete C# .NET source code

[System.Runtime.InteropServices.DllImport("user32.dll", 
  CharSet=System.Runtime.InteropServices.CharSet.Auto)]
public static extern IntPtr FindWindow(string lpClassName, 
  string lpWindowName);
 
[System.Runtime.InteropServices.DllImport("user32.dll", 
  CharSet=System.Runtime.InteropServices.CharSet.Auto)]
public static extern int GetWindowText(IntPtr hwnd,
  string lpString, int cch);
 
const string lpClassName = "Winamp v1.x";
const string strTtlEnd = " - Winamp";
 
static string GetSongTitle() 
{
      IntPtr hwnd = FindWindow(lpClassName, null);
      if (hwnd.Equals(IntPtr.Zero)) return "Not running";
 
      string lpText = new string((char) 0, 100);
      int intLength = GetWindowText(hwnd, lpText, lpText.Length);
            
      if ((intLength <= 0) || (intLength > lpText.Length)) 
        return "unknown";
 
      string strTitle = lpText.Substring(0, intLength);
      int intName = strTitle.IndexOf(strTtlEnd);
      int intLeft = strTitle.IndexOf("[");
      int intRight = strTitle.IndexOf("]");
 
      if ((intName >= 0) && (intLeft >= 0) && (intName < intLeft) &&
          (intRight >= 0) && (intLeft + 1 < intRight))
            return strTitle.Substring(intLeft + 1, intRight - intLeft - 1);
 
      if ((strTitle.EndsWith(strTtlEnd)) && 
            (strTitle.Length > strTtlEnd.Length))
            strTitle = strTitle.Substring(0, 
                strTitle.Length - strTtlEnd.Length);
 
      int intDot = strTitle.IndexOf(".");
      if ((intDot > 0) && IsNumeric(strTitle.Substring(0, intDot)))
            strTitle = strTitle.Remove(0, intDot + 1);
 
      return strTitle.Trim();
}
 
static bool IsNumeric(string Value)
{
      try 
      {
            double.Parse(Value);
            return true;
      }
      catch
      {
            return false;
      }
}

Complete VB .NET source code

Private Declare Auto Function FindWindow Lib "user32" ( _
  ByVal lpClassName As String, _
  ByVal lpWindowName As String) As IntPtr
Private Declare Auto Function GetWindowText Lib "user32" ( _
   ByVal hwnd As IntPtr, _
   ByVal lpString As String, _
   ByVal cch As Integer) As Integer
 
Private Const lpClassName = "Winamp v1.x"
Private Const strTtlEnd = " - Winamp"
 
Private Function GetWinampSong() As String
    Dim hwnd As IntPtr = FindWindow(lpClassName, vbNullString)
 
    Dim lpText As String
 
    If hwnd.Equals(IntPtr.Zero) Then Return "Not running"
 
    lpText = New String(Chr(0), 100)
    Dim intLength As Integer = GetWindowText(hwnd, lpText, _
      lpText.Length)
 
    If (intLength <= 0) OrElse (intLength > lpText.Length) _
             Then Return "Unknown"
 
    Dim strTitle As String = lpText.Substring(0, intLength)
    Dim intName As Integer = strTitle.IndexOf(strTtlEnd)
    Dim intLeft As Integer = strTitle.IndexOf("[")
    Dim intRight As Integer = strTitle.IndexOf("]")
 
    If (intName >= 0) AndAlso (intLeft >= 0) AndAlso _
            (intName < intLeft) AndAlso _
       (intRight >= 0) AndAlso (intLeft + 1 < intRight) Then _
        Return strTitle.Substring(intLeft + 1, intRight - intLeft - 1)
 
    If (strTitle.EndsWith(strTtlEnd)) AndAlso _
        (strTitle.Length > strTtlEnd.Length) Then _
        strTitle = strTitle.Substring(0, _
          strTitle.Length - strTtlEnd.Length)
 
    Dim intDot As Integer = strTitle.IndexOf(".")
    If (intDot > 0) AndAlso (IsNumeric( _
           strTitle.Substring(0, intDot))) Then _
        strTitle = strTitle.Remove(0, intDot + 1)
 
    Return strTitle.Trim
End Function

Points of Interest

When I first wrote my code I used MarshallAs attributes. I made a mistake by specifying a wrong, but valid argument and spent about one hour looking for the bug. The function GetWindowText always returned 0. In this case, this attribute is not required, so don't use it.

History

  • Original code. Jan 6 2004.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here

About the Author

Niels Penneman

Belgium Belgium
No Biography provided
Follow on   LinkedIn

Comments and Discussions

 
GeneralFind window Not Working Pinmembereg_Anubhava23-Oct-09 19:02 
GeneralRe: Find window Not Working PinmemberNiels Penneman24-Oct-09 0:27 
GeneralFindWindow + API Pinmemberavmgan_314817-Sep-06 19:28 
GeneralRe: FindWindow + API PinmemberVirtual1ty15-Sep-07 9:35 
Questionbook????? Pinmembermohit narang20-Jul-06 0:20 
AnswerRe: book????? PinmemberNiels Penneman20-Jul-06 4:18 
Generalproblem Pinmembermohit narang18-Jul-06 22:47 
GeneralRe: problem PinmemberNiels Penneman19-Jul-06 5:36 
Generalnewbies Pinmembermohit narang18-Jul-06 21:48 
GeneralRe: newbies PinmemberColin Angus Mackay18-Jul-06 22:30 
mohit narang wrote:
how we came to know about this functiuon and more function of user32.dll

 
It is all in MSDN[^]
 

Scottish Developers events:
* .NET debugging, tracing and instrumentation by Duncan Edwards Jones and Code Coverage in .NET by Craig Murphy
* Developer Day Scotland: are you interested in speaking or attending?

My: Website | Blog
GeneralRe: newbies PinmemberNiels Penneman19-Jul-06 5:34 
Questionsime improvements? Pinmemberfredjeboy1-Dec-05 9:07 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Mobile
Web02 | 2.8.140721.1 | Last Updated 6 Jan 2004
Article Copyright 2004 by Niels Penneman
Everything else Copyright © CodeProject, 1999-2014
Terms of Service
Layout: fixed | fluid