Go Back   Winamp Forums > Developer Center > Winamp Development

Reply
Thread Tools Search this Thread Display Modes
Old 14th April 2002, 17:24   #1
THEMike
Bastificator [Alumni]
 
THEMike's Avatar
 
Join Date: May 2000
Location: #nullsoft
Posts: 1,260
Unpublished API's

After a little natter with Tag about SHOUTcast he clued me into a few unpublished winamp API's that may be handy for you all:

code:

#ifndef __IPC_PE_H
#define __IPC_PE_H

#define IPC_PE_GETCURINDEX 100
#define IPC_PE_GETINDEXTOTAL 101
#define IPC_PE_GETINDEXINFO 102
#define IPC_PE_GETINDEXINFORESULT 103
#define IPC_PE_DELETEINDEX 104
#define IPC_PE_SWAPINDEX 105
#define IPC_PE_INSERTFILENAME 106
#define IPC_PE_GETDIRTY 107
#define IPC_PE_SETCLEAN 108



These are all sent to the playlist window not the main window.

"Beer?"
THEMike is offline   Reply With Quote
Old 16th April 2002, 19:31   #2
pi8
Junior Member
 
Join Date: Feb 2002
Posts: 7
Thanks a lot for posting this, man!! Not needed by me, though.
pi8 is offline   Reply With Quote
Old 16th April 2002, 21:21   #3
asandvig
Senior Member
 
asandvig's Avatar
 
Join Date: Dec 2000
Location: Oslo, Norway
Posts: 108
This looks nice, but what do they do and how to you send them? What parameters do they take, what do they return, etc..?
asandvig is offline   Reply With Quote
Old 17th April 2002, 03:14   #4
Gourou
Senior Member
 
Gourou's Avatar
 
Join Date: Feb 2002
Location: The backside of the universe on the trailing edge of eternity
Posts: 238
*licks his lips* time to go to work
Gourou is offline   Reply With Quote
Old 17th April 2002, 07:51   #5
THEMike
Bastificator [Alumni]
 
THEMike's Avatar
 
Join Date: May 2000
Location: #nullsoft
Posts: 1,260
#define IPC_PE_GETCURINDEX 100

Should be obvious, get position of current track in playlist.

Returns an int.

#define IPC_PE_DELETEINDEX 104

Remove specified track from list (takes int)

#define IPC_PE_SWAPINDEX 105

Swap two files in order on playlist

#define IPC_PE_INSERTFILENAME 106

Add a track.

These two are very interesting.

#define IPC_PE_GETDIRTY 107
#define IPC_PE_SETCLEAN 108

SETCLEAN sets the playlist as clean. If get dirty returns a 1 (I think) then the list has been edited by another process since you last setclean. It's a dirty read thing...

I have more info at home, I'll post it when I get a chance.

Should be simple to figure them out tho...

"Beer?"
THEMike is offline   Reply With Quote
Old 17th April 2002, 20:07   #6
zhaPP
Junior Member
 
Join Date: Apr 2002
Posts: 2
Thanks for the APIs, but I'm having problems how to use them.. Using the following code to insert a playlistitem:

char szTmp[64];
HWND PEWnd = FindWindow("Winamp PE",NULL);
strcpy(szTmp, "C:\\mp3\\test.mp3");
SendMessage(PEWnd,WM_USER,(LPARAM)szTmp,106);

Is this wrong? Seems to be that because it doesn't work for me..

How do you use IPC_PE_DELETEINDEX?
Can you just do the following:

int nIndex = 1;
SendMessage(WAWnd,WM_USER,nIndex,104);

Thanks in advance!
zhaPP is offline   Reply With Quote
Old 19th April 2002, 09:06   #7
THEMike
Bastificator [Alumni]
 
THEMike's Avatar
 
Join Date: May 2000
Location: #nullsoft
Posts: 1,260
All I have...

code:

#ifndef __IPC_PE_H
#define __IPC_PE_H

#define IPC_PE_GETCURINDEX 100
#define IPC_PE_GETINDEXTOTAL 101
#define IPC_PE_GETINDEXINFO 102
#define IPC_PE_GETINDEXINFORESULT 103
#define IPC_PE_DELETEINDEX 104
#define IPC_PE_SWAPINDEX 105
#define IPC_PE_INSERTFILENAME 106
#define IPC_PE_GETDIRTY 107
#define IPC_PE_SETCLEAN 108

typedef struct {
char file[MAX_PATH];
int index;
} fileinfo;

typedef struct {
HWND callback;
int index;
} callbackinfo;

#endif

g_winamp = FindWindow("Winamp v1.x",NULL);
g_playlist = FindWindow("Winamp PE",NULL);
COPYDATASTRUCT cds;
fileinfo f;
cds.dwData = IPC_PE_INSERTFILENAME;
strcpy(f.file, tempname); // Path to the new entry
if ( ins )
{
f.index=target; // Position to insert at
}
else
{
f.index=allsongs;
}
cds.lpData = (void *)&f;
cds.cbData = sizeof(fileinfo);

SendMessage(g_playlist,WM_COPYDATA,(WPARAM)NULL,(LPARAM)&cds);
sprintf(g_lastmode," Add File to Playlist ");
sprintf(g_lastreply," Inserted: %s at position %d ",f.file,f.index);

getfilename(tempname,movesong); /* unsafe, fullpath, but we dont show on page */
cursong = SendMessage g_playlist,WM_USER,IPC_PE_GETCURINDEX ,0);
target = cursong+1;
{
COPYDATASTRUCT cds;
fileinfo f;
cds.dwData = IPC_PE_INSERTFILENAME;
strcpy(f.file, tempname); // Path to the new entry
f.index=target; // Position to insert at
cds.lpData = (void *)&f;
cds.cbData = sizeof(fileinfo);
SendMessage(g_playlist,WM_COPYDATA,(WPARAM)NULL,(LPARAM)&cds);
}
if ( movesong > cursong ) movesong++;
SendMessage(g_playlist,WM_USER,IPC_PE_DELETEINDEX, movesong);
sprintf(g_lastmode," Move Song to next ");
sprintf(g_lastreply," From: %d To: %d ", movesong, target);


allsongs = SendMessage(g_playlist, WM_USER, IPC_PE_GETINDEXTOTAL,0);

sprintf(buf,"Status: %s | Total Songs: %d<br>", status, allsongs );
strcat(g_client[i].t_sendbuf,buf);

cursong = SendMessage(g_playlist,WM_USER,IPC_PE_GETCURINDEX ,0);

getfilename(tempname, cursong);
sprintf(buf,"Now Playing: <b>%d : %s</b><br>", cursong, tempname );

void getfilename(char *target, int index)
{
COPYDATASTRUCT cds;
callbackinfo f;
cds.dwData = IPC_PE_GETINDEXINFO;
f.callback = g_hwnd; // this is the HWND of the window which will receive the callback message
f.index=index; // Index of the entry to get info from
cds.lpData = (void *)&f;
cds.cbData = sizeof(callbackinfo);
g_callback = 1; /* Index Request */
SendMessage(g_playlist,WM_COPYDATA,(WPARAM)NULL,(LPARAM)&cds);
while ( g_callback == 1 )
{
log_printf("stuck");
Sleep(1000);
}
strcpy(target,g_file);
}



And if that doesn't do it for you, then I don't know what will...

"Beer?"
THEMike is offline   Reply With Quote
Old 19th April 2002, 09:40   #8
zhaPP
Junior Member
 
Join Date: Apr 2002
Posts: 2
Works great.. thanks a lot!!!
zhaPP is offline   Reply With Quote
Old 20th April 2002, 15:41   #9
Flippet
Junior Member
 
Join Date: Jun 2001
Location: Yeovil, Somerset, UK
Posts: 23
I see... what I got wrong was the message format difference between this and the normal winamp API messages...

SendMessage(hwnd,WM_USER,data,command) - Winamp main window
SendMessage(hwnd,WM_USER,command,data) - Playlist window

It works now, ta...

Phil, just me
Flippet is offline   Reply With Quote
Old 12th July 2002, 13:10   #10
ChrisNC
Junior Member
 
Join Date: Jul 2002
Posts: 1
VB Version?

Does anyone have a Visual Basic version of the code to insert a file into the playlist? I want to be able to insert a file at a particular location within the current playlist. Can this be done?

Thanks.
ChrisNC is offline   Reply With Quote
Old 18th July 2002, 05:27   #11
apol
Junior Member
 
Join Date: Jul 2002
Posts: 4
Swap index?

Does anyone know how to use IPC_PE_SWAPINDEX? I have a method, but it's not the best IMO. It works by switching the passed index with 0, so I figure I can just do it like this to swap two specific ones.

code:

void swapindex ( int numone, int numtwo )
{
HWND hwndPlaylist = FindWindow("Winamp PE", NULL);
SendMessage(hwndPlaylist, WM_USER, IPC_PE_SWAPINDEX, numone);
SendMessage(hwndPlaylist, WM_USER, IPC_PE_SWAPINDEX, numtwo);
SendMessage(hwndPlaylist, WM_USER, IPC_PE_SWAPINDEX, numone);
}

apol is offline   Reply With Quote
Old 19th July 2002, 23:51   #12
Gabi Slonto
Junior Member
 
Join Date: Mar 2001
Posts: 3
I want to translate it to Delphi ;-)
But there must be a problem with the pointer...
Is there anybody who could help..... ??

procedure InsertMp3ToPlayList(iAfterTrack : Integer; mp3ToAdd:string);
Type
TFileInfo = record
FileName : String;
Index : Integer;
end;
Var
cds : CopyDataStruct;
f : TFileInfo;
begin
Mp3ToAdd:=(MP3ToAdd+#0);
f.FileName := Mp3ToAdd;
f.Index := iAfterTrack;
cds.dwData := 106; //int for IPC_PE_INSERTFILENAME
cds.lpData := @f;
cds.cbData := SizeOf(TFileInfo);
GethWnd_WinAmpPL;
SendMessage(hwnd_WinampPL, WM_COPYDATA, 0, LParam(@cds));
end;
Gabi Slonto is offline   Reply With Quote
Old 22nd July 2002, 09:19   #13
barney911
Junior Member
 
Join Date: Jul 2002
Posts: 10
insert file into playlist

I found a solution to load mp3-file into a playlist with C#

If anybody needs this, just search the forum for "C# COPYDATA".

It appears under one of the first given search result postings (something with VB COPYDATA or so).


Greets,
Barney.
barney911 is offline   Reply With Quote
Old 24th July 2002, 00:41   #14
shrom
Junior Member
 
Join Date: Jun 2002
Posts: 6
To Gabi Slonto :

You could try this
Type
TFileInfo = packed record
FileName : Array[0..MAX_PATH-1] of Char;
Index : Integer;
end;
Var
cds : CopyDataStruct;
f : TFileInfo;
begin
StrLCopy(f.FileName, PChar(Mp3ToAdd), SizeOf(f.FileName));
f.Index := iAfterTrack;
cds.dwData := 106; //int for IPC_PE_INSERTFILENAME
cds.cbData := SizeOf(f);
cds.lpData := @f;
GethWnd_WinAmpPL;
SendMessage(hwnd_WinampPL, WM_COPYDATA, 0, LParam(@cds));
end;

It works for me : Delphi6, Winamp 2.8

Last edited by shrom; 24th July 2002 at 01:59.
shrom is offline   Reply With Quote
Old 1st October 2002, 15:38   #15
spib
Senior Member
 
Join Date: Jun 2000
Location: Manchester, UK
Posts: 106
Anyone noticed that this code doesn't work when the Playlist in is Winshade mode? It works when the playlist is full size or even when the playlist is 'closed' but not when in winshade mode.

Anyone have a fix for this?
spib is offline   Reply With Quote
Old 7th October 2002, 22:58   #16
SpazzMan
Junior Member
 
Join Date: Oct 2002
Location: In front of my computer. Yes, I know it says, "Where you _live_."
Posts: 2
I'm finding it to be worse than that: I get crashes when I winshade the playlist after deleting an song. It doesn't seem to matter how much time expires between the deletion and the winshading; as soon as that winshade button's clicked, Winamp goes down.

I would've like to be able to delete stuff, too. This is probably why they're unpublished...
SpazzMan is offline   Reply With Quote
Old 8th October 2002, 13:13   #17
spib
Senior Member
 
Join Date: Jun 2000
Location: Manchester, UK
Posts: 106
Well, that's the end of my Winamp 2 development I think. Winamp3 all the way from now on.
spib is offline   Reply With Quote
Old 11th December 2002, 15:01   #18
sicpuppy_123
Junior Member
 
sicpuppy_123's Avatar
 
Join Date: Dec 2002
Posts: 9
Playlist Position

Hey there
Does anyone know how choose where the new file goes in the playlist?
Pref in vb (not to good at c)
Thanks
sicpuppy_123 is offline   Reply With Quote
Old 17th February 2003, 22:37   #19
jmoschetti45
Senior Member
 
jmoschetti45's Avatar
 
Join Date: Oct 2002
Location: Marquette, MI
Posts: 101
Send a message via AIM to jmoschetti45 Send a message via Yahoo to jmoschetti45
When I delete something in the playlist from my program and then windowshade I don't have any problems accept a few miliseconds audio lag.
jmoschetti45 is offline   Reply With Quote
Old 23rd February 2003, 20:53   #20
SpazzMan
Junior Member
 
Join Date: Oct 2002
Location: In front of my computer. Yes, I know it says, "Where you _live_."
Posts: 2
And, for some reason, neither do I now. I wish I still had the old code I was using so I could see what I'm doing differently now. This is really weird.

While you're at it, could you say that your code is really well-organized and works the first time you compile it?
SpazzMan is offline   Reply With Quote
Old 24th February 2003, 14:32   #21
jmoschetti45
Senior Member
 
jmoschetti45's Avatar
 
Join Date: Oct 2002
Location: Marquette, MI
Posts: 101
Send a message via AIM to jmoschetti45 Send a message via Yahoo to jmoschetti45
Yes my code is nice and clean (includes spacing and indents)
No it didn't work the first time because I forgot to define the constants.
jmoschetti45 is offline   Reply With Quote
Old 4th May 2003, 22:46   #22
slabber
Junior Member
 
Join Date: Feb 2001
Posts: 5
VB Solution for playlist relocation

Aha! Victory! I got it all working in VB now, but there are some things i still don't understand, even though i got them working using trial and error. Does anyone know why the callback construction does not work? i found a nice workaround for it... And does anyone know why the length of the fileinfo struct can not be

byte(255) + long --> 256+4 = 260 bytes
but must be
byte(259) + long --> 260+4 = 264
???

i hope you can enlighten me on this...
okay, enough questions now; let's see the code:

code:


Public Const IPC_PE_GETCURINDEX = 100
Public Const IPC_PE_GETINDEXTOTAL = 101
Public Const IPC_PE_GETINDEXINFO = 102
Public Const IPC_PE_GETINDEXINFORESULT = 103
Public Const IPC_PE_DELETEINDEX = 104
Public Const IPC_PE_SWAPINDEX = 105
Public Const IPC_PE_INSERTFILENAME = 106
Public Const IPC_PE_GETDIRTY = 107
Public Const IPC_PE_SETCLEAN = 108

Public Const WM_COPYDATA = &H4A
Public Const WM_COMMAND = &H111
Public Const WM_USER = &H400

Public Type COPYDATASTRUCT ' look this struct up in the MSDN library for more info
dwData As Long
cbData As Long
lpData As Long
End Type

Public Type fileinfo
file(259) As Byte ' (i wanted 255, but it seems the struct MUST be a multiple of 8 bytes? can someone explain this?
index As Long 'VB Long = C int = 4 bytes

End Type

Public Type callbackinfo
callback As Long 'HWND callback;
index As Long 'int index;
End Type

Public Declare Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As Long
Public Declare Function SendMessage Lib "user32" Alias "SendMessageA" (ByVal hWnd As Long, ByVal wMsg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
Public Declare Function CopyDataSendMessage Lib "user32" Alias "SendMessageA" (ByVal WndID As Long, ByVal wMsg As Long, ByVal wParam As Long, ByRef lParam As COPYDATASTRUCT) As Long
Public Declare Function ReadProcessMemory Lib "kernel32" (ByVal hProcess As Long, ByVal lpBaseAddress As Any, ByVal lpBuffer As Any, ByVal nSize As Long, lpNumberOfBytesWritten As Long) As Long
Public Declare Function GetWindowThreadProcessId Lib "user32" (ByVal hWnd As Long, lpdwProcessId As Long) As Long
Public Declare Function OpenProcess Lib "kernel32" (ByVal dwDesiredAccess As Long, ByVal bInheritHandle As Long, ByVal dwProcessId As Long) As Long
Public Declare Function CloseHandle Lib "kernel32" (ByVal hObject As Long) As Long
Public Const PROCESS_VM_READ = &H10

Public Sub StringToByteArray(str As String, ByRef bte() As Byte)
Dim k As Integer

For k = 1 To Len(str)
bte(k - 1) = Asc(Mid(str, k, 1))
Next k
For k = Len(str) To UBound(bte) - 1
bte(k) = Asc(" ")
Next k
If Len(str) < UBound(bte) Then bte(Len(str)) = 0
End Sub

Public Sub insertsong(path As String, Optional target As Integer)

h_winamp = FindWindow("Winamp v1.x", vbNullString)
h_playlist = FindWindow("Winamp PE", vbNullString)
Dim songcount, cursong As Integer

songcount = SendMessage(h_playlist, WM_USER, IPC_PE_GETINDEXTOTAL, 0)

'set up the arguments for the INSERTFILENAME api to send to winamp:
Dim f As fileinfo
StringToByteArray path, f.file

If IsMissing(target) Then
f.index = songcount ';
Else
f.index = target '; // Position to insert at
End If

'use a windows standard COPYDATASTRUCT to package our function arguments.
Dim cds As COPYDATASTRUCT
cds.dwData = IPC_PE_INSERTFILENAME
cds.lpData = VarPtr(f)
cds.cbData = 264 'why?!? does it have to be a multiple of 8 bytes or something? 260 didn't work..

CopyDataSendMessage h_playlist, WM_COPYDATA, 0&, cds
' new song is now queued at the last position in the playlist

End Sub

'moves a song around the playlist so it becomes the next played song,
'or moves it to the specified index.
'NB: moving is interpreted as: take the song out (leaving a virtual gap),
'insert the song in the new position, by moving the song in that position and the ones after it
' to position+1, and finally deleting the gap.
Public Sub movesong(curPosition As Integer, Optional newPosition As Integer)
'TODO: sanity checks
h_winamp = FindWindow("Winamp v1.x", vbNullString)
h_playlist = FindWindow("Winamp PE", vbNullString)

Dim path As String
Dim playPosition As Integer

path = getfilename(curPosition)

'Delete the song that will be reinserted:
SendMessage h_playlist, WM_USER, IPC_PE_DELETEINDEX, curPosition


If IsMissing(newPosition) Then
' the song to be moved will be placed right after the currently playing song:
playPosition = SendMessage(h_playlist, WM_USER, IPC_PE_GETCURINDEX, 0)
newPosition = playPosition + 1
ElseIf newPosition > curPosition Then
newPosition = newPosition - 1
End If

Dim f As fileinfo
StringToByteArray path, f.file
f.index = newPosition

Dim cds As COPYDATASTRUCT
cds.dwData = IPC_PE_INSERTFILENAME
cds.lpData = VarPtr(f)
cds.cbData = 264 'why?!? does it have to be a multiple of 8 bytes or something? 260 didn't work..

CopyDataSendMessage h_playlist, WM_COPYDATA, 0&, cds

End Sub

Public Function getfilename(index As Integer) As String

On Error Resume Next

Dim Trackpos As Long
Dim mpointer As Long
Dim temp, temphandle, hwndwinampp As Long
Dim ntemp, ptemp
Dim Data As String * 256

mpointer = SendMessage(h_winamp, WM_USER, index, 211) '212 is Title
'do interprocess magic:
temp = GetWindowThreadProcessId(h_winamp, temphandle)
hwndwinampp = OpenProcess(PROCESS_VM_READ, False, temphandle)
Data = Space(256)
'pull the data:
ntemp = ReadProcessMemory(hwndwinampp, mpointer, Data, 256, temp)
'bail out:
ptemp = CloseHandle(hwndwinampp)
getfilename = Left(Data, InStr(1, Data, Chr(0)) - 1)

'the following does not work, the callback does not get called! why not?:
Dim cds As COPYDATASTRUCT
Dim f As callbackinfo
f.callback = GetProcAddress(AddressOf callbackf)
f.index = 12
cds.lpData = VarPtr(f)
cds.cbData = 8
cds.dwData = IPC_PE_GETINDEXINFO
CopyDataSendMessage h_winamp, WM_COPYDATA, 0&, cds

End Function


Public Function callbackf()
MsgBox "CALLBACK!"
Debug.Print "CALLBACK"
Stop
End Function

Public Function GetProcAddress(ByVal lngAddressOf As Long) As Long
GetProcAddress = lngAddressOf
End Function




(paste & play: paste it in a module, and call the insertsong & movesong functions te have it work)

Please let me know if you think the code is usefull!
slabber is offline   Reply With Quote
Old 10th June 2003, 01:12   #23
BYTE-Smasher
Junior Member
 
Join Date: Jun 2003
Posts: 8
The VB code doesn't seem to add songs in at all.... even though it's supposed to... any idea why? I copied and pasted fairly precisely....
BYTE-Smasher is offline   Reply With Quote
Old 12th June 2003, 17:51   #24
slabber
Junior Member
 
Join Date: Feb 2001
Posts: 5
I just tested it again in a clean project, from copying the above, and it really works! I use WA 2.91; maybe you have to up- / downgrade to make it work..
slabber is offline   Reply With Quote
Old 8th January 2004, 17:27   #25
TazDevil
Senior Member
 
TazDevil's Avatar
 
Join Date: Nov 2003
Location: Cyprus
Posts: 359
THEMike
According to the code that you posted the insert file/(s) works perfect as for the folders as well but hte only problem is that when
f.index= something
then all files of the folder are added to the bottom of the playlist and only the last file of the folder is set to the disired possition....

I would like some help here because i shouldn't have to transfer every file seperatly to the right possition.

Also about IPC_PE_SWAPINDEX it will swap the possitions of the indexes in the parenthesis, in the example the 2nd file on the list will become 5th, and the 5th -> 2nd

SendMessage(PE_WND,WM_WA_IPC,IPC_PE_SWAPINDEX, MAKELPARAM(1,4));
TazDevil is offline   Reply With Quote
Reply
Go Back   Winamp Forums > Developer Center > Winamp Development

Thread Tools Search this Thread
Search this Thread:

Advanced Search
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump