Jump to content

Get current ID3 tag from winamp


Recommended Posts

Not to sound like a traitor, but...I found this at AutoHotKey.com

Winamp Automation functions (using SendMessage)

http://www.autohotkey.net/~jballi/Winamp/v1.0/Winamp.ahk

Read song title from Winamp memory pointer:

http://www.autohotkey.com/forum/viewtopic.php?p=22158#22158

I tested the second script and it works, so it just needs translated to AutoIt.

Link to comment
Share on other sites

I wouldn't have done this if I wasn't a superhero...but I converted the AutoHotKey script from above. The code is ugly, redundant, and could be made easier with some of the better AutoIt functions but it works well.

Enjoy.

#Include <misc.au3>

Dim $PID = 1

;Retrieve Winamp window handle
$winampHWND = WinGetHandle ( "[CLASS:Winamp v1.x]")

If $winampHWND = 0 Then
   MsgBox (0,"","Winamp does not appear to be running.")
   Exit
EndIf

; 0x0400 = WM_USER  0x7D = IPC_GETLISTPOS
$result = _SendMessage($winampHWND, 0x0400, 0, 0x7D, 0)
If @error Then
   MsgBox (0,"","SendMessage failed." & @error)
   Exit
EndIf

$result2 = _SendMessage($winampHWND, 0x0400, $result, 0xD4, 0)
If @error Then
   MsgBox (0,"","SendMessage failed.")
   Exit
EndIf

; Store the address in a new var.
$lpszTitle = $result2

; Get the Process ID of WinAMP.  It will be stored in the output-parameter PID.
$result3 = DllCall("user32.dll","int","GetWindowThreadProcessId","hwnd",$winampHWND,"int_ptr", $PID)

$PID = $result3[2]

if (@error OR NOT $PID) Then
   MsgBox (0,"","GetWindowThreadProcessId failed.")
   Exit
EndIf

;WARNING - Next command returns different result ($ProcessHandle) from AutoHotKey

; Open the process so we can to stuff with it.
; The call will return a process handle.
;ProcessHandle := DllCall("OpenProcess", "int", 24, "char", 0, "UInt", PID, "UInt") <-------From AutoHotKey

$result4 = DllCall("kernel32.dll", "uint", "OpenProcess", "byte", 0x10, "int",0, "int", $PID)

if (@ERROR OR NOT $result4[0]) then
   MsgBox (0,"","OpenProcess failed: " & @ERROR)
   Exit
endif

$ProcessHandle = $result4[0]

;MsgBox (0,"",$result4[0])

; Now we have the pointer stored in lpszTitle. To proceed we have to
; use ReadProcessMemory and read starting at the returned address.
; We have to read byte after byte until we encounter a "00" byte (string ends).

; clear the variable that will hold the track's name
$SongTitle = ""
While 1

    ; Read from WinAMP's memory. Value will be copied into the string buffer, which
    ; must contain exactly one character because ReadProcessMemory won't terminate
    ; the string, only overwrite its contents.
    ;$Output = "x"  ; Put exactly one character in as a placeholder.
    
    Local $v_Struct = DllStructCreate ('byte[1]')
    
    ;tempVar := DllCall("ReadProcessMemory", "UInt", ProcessHandle, "UInt", lpszTitle, "str", Output, "Uint", 1, "Uint *", 0)
    $result5 = DllCall('kernel32.dll', 'int', 'ReadProcessMemory', 'int', $ProcessHandle, 'int', $lpszTitle, 'int', DllStructGetPtr ($v_Struct, 1), 'int', 1, 'int', 0)    
    
    ; Error checking - i.e. no permission for reading from the process's memory
    if (@error) Then
        MsgBox (0,"","ReadProcessMemory failed: " & @error)
        DllCall("Kernel32.dll", "int", "CloseHandle", "int", $ProcessHandle)
        Exit
    EndIf
    
    $temp = DllStructGetData ($v_Struct, 1)

    ;Delete structure
    $v_Struct = 0    

    ; If the value of the byte read is zero we are at the end of the string.
    ; So quit the loop!
    if $temp = 0 then ExitLoop

    ; Append the character to our teststr variable that will hold the whole title string
    $SongTitle &= Chr($temp)

    ; Increment address by one to obtain next byte
    $lpszTitle += 1
WEnd

DllCall("Kernel32.dll", "int", "CloseHandle", "int", $ProcessHandle)  ; ErrorLevel and return value are not checked.

; Display our track's title
MsgBox (0,"","The track title is: " & $SongTitle)
Link to comment
Share on other sites

  • 1 month later...

@weaponx, haha <_< I was forgot about this topic and i search it, thats the reason for my "quick" response.

@big_daddy, i must install this ActiveWinamp before I use the script. Thats a problem, because if other users use the program they must install it too.

Link to comment
Share on other sites

  • 1 year later...

The code from weaponx just crashes autoit. I know it's old but maybe someone could update it, I'm not good with dll calls and the script crashes while getting the process id. I got the pid with autoit but still failed to get the song name.

Link to comment
Share on other sites

First thing, _SendMessage is no longer in Misc.au3, it's in SendMessage.au3.

Second, AutoIt doesn't like this call:

$result3 = DllCall("user32.dll","int","GetWindowThreadProcessId","hwnd",$winampHWND,"int_ptr", $PID)
$PID = $result3[2]

You can just cheat and use this:

$PID = ProcessExists("winamp.exe")
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

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...