I wanted in one of my project to control Winamp from application written in Delphi. It is well-known that Winamp can be controlled programmatically by finding the Winamp's window. It can be done performing the following Win32 API call:
hwnd_winamp := FindWindow('Winamp v1.x', nil);
Winamp window's class is always Winamp v1.x regardless its actual version. Once you have the handle to winamp's window you can controll it by sending to it certain messages which are specified in Winamp's SDK. However, the SDK on Winamp's website is available only for C++ developers. By googling over the Internet I have come across the translation of those header file to pascal done by Carlos Andres Osorio Gonzalez. However, it is based on the antique version of SDK and is lacking new features. I've decided to extend it, translating the lacking entries from the latest version of C++ SDK.
What I've come up with can be downloaded here or can be viewed here in browser by clicking here.
unit WAmpMsg;
interface
uses
Windows, Messages;
// Winamp frontend/plug-in control API documentation
// Delphi version
//
//
// By Krzysztof Olczyk
// http://olczyk.krzysztof.googlepages.com
// Oct 2007
//
// Based on:
//
// WAmpMsg.pas
//
// By Carlos Andres Osorio Gonzalez
// cosorio@softhome.net
// http://www.geocities.com/wplugins
// Last updated: JUL.11.1999.
//
// Based on document frontend.h, By Justin Frankel
//
// It consists of Carlos' version + messages
// present in new version of SDK for Winamp 5
//
// Comments are kept from original C++ SDK
//
// Introduction
// -----------------------
// This file describes a means to easily communicate to Winamp
// via the classic Win32 Message API.
//
// First, you find the HWND of the Winamp main window. From a plug-in
// you can easily extract this from the plug-in structure (hMainWindow,
// hwndParent, whatever). For external apps, use:
//
// var
// HWND hwnd_winamp
//
// hwnd_winamp := FindWindow('Winamp v1.x', nil);
//
// (note: I know, we're in Winamp 2.x, but it's 1.x for compatibility)
//
// Once you have the hwnd_winamp, it's a good idea to check the version
// number. To do this, you send a WM_WA_IPC message to hwnd_winamp.
// Note that WM_WA_IPC is defined as Win32's WM_USER.
//
// Note that sometimes you might want to use PostMessage instead of
// SendMessage.
const
WM_WA_IPC = WM_USER;
////////////////////////////////////////////////////////////////////////////
IPC_GETVERSION = 0;
// var
// version: LongInt;
//
// version := SendMessage(hwnd_winamp, WM_WA_IPC, 0, IPC_GETVERSION);
//
// Version will be 0x20yx for winamp 2.yx. versions previous to Winamp 2.0
// typically (but not always) use 0x1zyx for 1.zx versions. Weird, I know.
//
// The basic format for sending messages to Winamp is:
//
// Var
// MsgResult: LongInt
//
// MsgResult := SendMessage(hwnd_winamp, WM_WA_IPC, command_data, command);
// (for the version check, command_data is 0).
IPC_DELETE = 101;
// SendMessage( hwnd_winamp, WM_WA_IPC, 0, IPC_DELETE);
//
// You can use IPC_DELETE to clear Winamp's internal playlist.
IPC_STARTPLAY = 102;
// SendMessage(hwnd_winamp, WM_WA_IPC, 0, IPC_STARTPLAY);
//
// Using IPC_STARTPLAY is like hitting 'Play' in Winamp, mostly.
IPC_ISPLAYING = 104;
// Var
// MsgResult: LongInt
//
// MsgResult := SendMessage(hwnd_winamp, WM_WA_IPC, 0, IPC_ISPLAYING);
//
// IPC_ISPLAYING returns the status of playback.
// If it returns 1, it is playing. if it returns 3, it is paused,
// if it returns 0, it is not playing.
IPC_GETOUTPUTTIME = 105;
// Var
// MsgResult: LongInt
//
// MsgResult := SendMessage(hwnd_winamp, WM_WA_IPC, mode, IPC_GETOUTPUTTIME);
//
// IPC_GETOUTPUTTIME returns the position in milliseconds of the
// current song (mode = 0), or the song length, in seconds (mode = 1).
// Returns -1 if not playing or error.
IPC_JUMPTOTIME = 106;
// (requires Winamp = 1.60+)
// SendMessage(hwnd_winamp, WM_WA_IPC, ms, IPC_JUMPTOTIME);
// IPC_JUMPTOTIME sets the position in milliseconds of the
// current song (approximately).
// Returns -1 if not playing, = 1 on eof, or 0 if successful
IPC_WRITEPLAYLIST = 120;
// (requires Winamp = 1.666+)
// SendMessage(hwnd_winamp, WM_WA_IPC, 0, IPC_WRITEPLAYLIST);
//
// IPC_WRITEPLAYLIST writes the current playlist to
// and returns the current playlist position.
// Kinda obsoleted by some of the 2.x new stuff, but still good for when
// using a front-end (instead of a plug-in)
IPC_SETPLAYLISTPOS = 121;
// (requires Winamp 2.0+)
// SendMessage(hwnd_winamp, WM_WA_IPC, position, IPC_SETPLAYLISTPOS)
//
// IPC_SETPLAYLISTPOS sets the playlsit position to 'position'.
IPC_SETVOLUME = 122;
// (requires Winamp 2.0+)
// SendMessage(hwnd_winamp, WM_WA_IPC, volume, IPC_SETVOLUME);
//
// IPC_SETVOLUME sets the volume of Winamp (from 0-255).
IPC_SETPANNING = 123;
// (requires Winamp 2.0+)
// SendMessage(hwnd_winamp, WM_WA_IPC, panning, IPC_SETPANNING);
//
// IPC_SETPANNING sets the panning of Winamp (from 0 (left) to 255 (right)).
IPC_GETLISTLENGTH = 124;
// (requires Winamp 2.0+)
// Var
// length: LongInt
//
// length := SendMessage(hwnd_winamp, WM_WA_IPC, 0, IPC_GETLISTLENGTH);
//
// IPC_GETLISTLENGTH returns the length of the current playlist, in
// tracks.
IPC_SETSKIN = 200;
// (requires Winamp 2.04+, only usable from plug-ins (not external apps))
// SendMessage(hwnd_winamp, WM_WA_IPC, WPARAM(PChar('skinname'), IPC_SETSKIN);
//
// IPC_SETSKIN sets the current skin to "skinname". Note that skinname
// can be the name of a skin, a skin .zip file, with or without path.
// If path isn't specified, the default search path is the winamp skins
// directory.
IPC_GETSKIN = 201;
// (requires Winamp 2.04+, only usable from plug-ins (not external apps))
//
// var
// skinname_buffer: PChar;
//
// GetMem(skinname_buffer, MAX_PATH);
// SendMessage(hwnd_winamp, WM_WA_IPC, WPARAM(skinname_buffer), IPC_GETSKIN);
//
// when don't need the variable skinname_buffer, call
// FreeMem(skinname_buffer, MAX_PATH);
//
//
// IPC_GETSKIN puts the directory where skin bitmaps can be found
// into skinname_buffer.
// skinname_buffer must be MAX_PATH characters in length.
// When using a .zip'd skin file, it'll return a temporary directory
// where the ZIP was decompressed.
IPC_EXECPLUG = 202;
// (requires Winamp 2.04+, only usable from plug-ins (not external apps))
// SendMessage(hwnd_winamp, WM_WA_IPC, WPARAM(PChar('vis_file.dll')), IPC_EXECPLUG);
//
// IPC_EXECPLUG executes a visualization plug-in pointed to by WPARAM.
// the format of this string can be:
// "vis_whatever.dll"
// "vis_whatever.dll, 0"; // (first mod, file in winamp plug-in dir)
// "C:\\dir\\vis_whatever.dll, 1"
IPC_GETPLAYLISTFILE = 211;
// (requires Winamp 2.04+, only usable from plug-ins (not external apps))
// var
// Name: PChar;
//
// Name := Pointer(SendMessage(hwnd_winamp, WM_WA_IPC, index, IPC_GETPLAYLISTFILE));
//
// IPC_GETPLAYLISTFILE gets the filename of the playlist entry [index].
// returns a pointer to it. returns NULL on error.
IPC_GETPLAYLISTTITLE = 212;
// (requires Winamp 2.04+, only usable from plug-ins (not external apps))
// var
// Name: PChar;
//
// Name := Pointer(SendMessage(hwnd_winamp, WM_WA_IPC, index, IPC_GETPLAYLISTTITLE));
//
// IPC_GETPLAYLISTTITLE gets the title of the playlist entry [index].
// returns a pointer to it. returns NULL on error.
IPC_GETLISTPOS = 125;
// (requires Winamp 2.05+)
// Var
// Pos: LongInt
//
// Pos := SendMessage(hwnd_winamp, WM_WA_IPC, 0, IPC_GETLISTPOS);
//
// IPC_GETLISTPOS returns the playlist position. A lot like IPC_WRITEPLAYLIST
// only faster since it doesn't have to write out the list. Heh, silly me.
IPC_GETINFO = 126;
// (requires Winamp 2.05+)
// Var
// Inf: LongInt
//
// Inf := SendMessage(hwnd_winamp, WM_WA_IPC, mode, IPC_GETINFO);
//
// IPC_GETINFO returns info about the current playing song. The value
// it returns depends on the value of 'mode'.
// Mode Meaning
// ------------------
// 0 Samplerate (i.e. 44100)
// = 1 Bitrate (i.e. = 128)
// 2 Channels (i.e. 2)
IPC_GETEQDATA = 127;
// (requires Winamp 2.05+)
// int data=SendMessage(hwnd_winamp, WM_WA_IPC, pos, IPC_GETEQDATA);
//
// IPC_GETEQDATA queries the status of the EQ.
// The value returned depends on what 'pos' is set to:
// Value Meaning
// ------------------
// 0-9 The = 10 bands of EQ data. 0-63 (+20db - -20db)
// = 10 The preamp value. 0-63 (+20db - -20db)
// = 11 Enabled. zero if disabled, nonzero if enabled.
// = 12 Autoload. zero if disabled, nonzero if enabled.
IPC_SETEQDATA = 128;
// (requires Winamp 2.05+)
// SendMessage(hwnd_winamp, WM_WA_IPC, pos, IPC_GETEQDATA);
// SendMessage(hwnd_winamp, WM_WA_IPC, value, IPC_SETEQDATA);
//
// IPC_SETEQDATA sets the value of the last position retrieved
// by IPC_GETEQDATA.
////////////////////////////////////////////////////////////////////////////
// Some API calls tend to require that you send data via WM_COPYDATA
// instead of WM_USER. Such as IPC_PLAYFILE:
IPC_PLAYFILE = 100;
// var
// cds: TCOPYDATASTRUCT;
//
// cds.dwData := IPC_PLAYFILE;
// cds.lpData := PChar('file.mp3');
// cds.cbData := strlen(cds.lpData) + 1; // include space for null char
// SendMessage(hwnd_winamp, WM_COPYDATA, 0, LongInt(@cds));
//
// This will play the file "file.mp3".
//
IPC_CHDIR = 103;
// var
// cds: TCOPYDATASTRUCT;
//
// cds.dwData = IPC_CHDIR;
// cds.lpData := PChar('c:\download');
// cds.cbData := strlen(cds.lpData) + 1; // include space for null char
// SendMessage(hwnd_winamp, WM_COPYDATA, 0, LongInt(@cds));
//
// This will make Winamp change to the directory C:\download
//
////////////////////////////////////////////////////////////////////////////
// Finally there are some WM_COMMAND messages that you can use to send
// Winamp misc commands.
//
// To send these, use:
//
// SendMessage(hwnd_winamp, WM_COMMAND, command_name, 0);
WINAMP_OPTIONS_EQ = 40036; // toggles the EQ window
WINAMP_OPTIONS_PLEDIT = 40040; // toggles the playlist window
WINAMP_VOLUMEUP = 40058; // turns the volume up a little
WINAMP_VOLUMEDOWN = 40059; // turns the volume down a little
WINAMP_FFWD5S = 40060; // fast forwards 5 seconds
WINAMP_REW5S = 40061; // rewinds 5 seconds
// the following are the five main control buttons, with optionally shift
// or control pressed
// (for the exact functions of each, just try it out)
WINAMP_BUTTON1 = 40044;
WINAMP_BUTTON2 = 40045;
WINAMP_BUTTON3 = 40046;
WINAMP_BUTTON4 = 40047;
WINAMP_BUTTON5 = 40048;
WINAMP_BUTTON1_SHIFT = 40144;
WINAMP_BUTTON2_SHIFT = 40145;
WINAMP_BUTTON3_SHIFT = 40146;
WINAMP_BUTTON4_SHIFT = 40147;
WINAMP_BUTTON5_SHIFT = 40148;
WINAMP_BUTTON1_CTRL = 40154;
WINAMP_BUTTON2_CTRL = 40155;
WINAMP_BUTTON3_CTRL = 40156;
WINAMP_BUTTON4_CTRL = 40157;
WINAMP_BUTTON5_CTRL = 40158;
WINAMP_FILE_PLAY = 40029; // pops up the load file(s) box
WINAMP_OPTIONS_PREFS = 40012; // pops up the preferences
WINAMP_OPTIONS_AOT = 40019; // toggles always on top
WINAMP_HELP_ABOUT = 40041; // pops up the about box :)
(***
**
**
**
**
** Here comes stuff added by me (Krzysztof)
**
**)
IPC_ADDBOOKMARK = 129;
(* (requires Winamp 2.4+)
** Sent as a WM_COPYDATA, using IPC_ADDBOOKMARK, adds the specified
** file/url to the Winamp bookmark list.
*)
(*
In winamp 5+, we use this as a normal WM_WA_IPC and the string:
"filename\0title\0"
to notify the library/bookmark editor that a bookmark
was added. Note that using this message in this context does not
actually add the bookmark.
do not use :)
*)
IPC_RESTARTWINAMP = 135;
(* (requires Winamp 2.2)
** SendMessage(hwnd_winamp,WM_WA_IPC,0,IPC_RESTARTWINAMP);
** IPC_RESTARTWINAMP will restart Winamp (isn't that obvious ? :)
*)
IPC_ISFULLSTOP = 400;
(* (requires winamp 2.7+ I think)
** ret=SendMessage(hwnd_winamp,WM_WA_IPC,0,IPC_ISFULLSTOP);
** useful for when you're an output plugin, and you want to see
** if the stop/close is a full stop, or just between tracks.
** returns nonzero if it's full, zero if it's just a new track.
*)
IPC_INETAVAILABLE = 242;
(* (requires Winamp 2.05+)
** val=SendMessage(hwnd_winamp,WM_WA_IPC,0,IPC_INETAVAILABLE);
** IPC_INETAVAILABLE will return 1 if the Internet connection is available for Winamp.
*)
IPC_UPDTITLE = 243;
(* (requires Winamp 2.2+)
** SendMessage(hwnd_winamp,WM_WA_IPC,0,IPC_UPDTITLE);
** IPC_UPDTITLE will ask Winamp to update the informations about the current title.
*)
IPC_REFRESHPLCACHE = 247;
(* (requires Winamp 2.2+)
** SendMessage(hwnd_winamp,WM_WA_IPC,0,IPC_REFRESHPLCACHE);
** IPC_REFRESHPLCACHE will flush the playlist cache buffer.
** (send this if you want it to go refetch titles for tracks)
*)
IPC_GET_SHUFFLE = 250;
(* (requires Winamp 2.4+)
** val=SendMessage(hwnd_winamp,WM_WA_IPC,0,IPC_GET_SHUFFLE);
**
** IPC_GET_SHUFFLE returns the status of the Shuffle option (1 if set)
*)
IPC_GET_REPEAT = 251;
(* (requires Winamp 2.4+)
** val=SendMessage(hwnd_winamp,WM_WA_IPC,0,IPC_GET_REPEAT);
**
** IPC_GET_REPEAT returns the status of the Repeat option (1 if set)
*)
IPC_SET_SHUFFLE = 252;
(* (requires Winamp 2.4+)
** SendMessage(hwnd_winamp,WM_WA_IPC,value,IPC_SET_SHUFFLE);
**
** IPC_SET_SHUFFLE sets the status of the Shuffle option (1 to turn it on)
*)
IPC_SET_REPEAT = 253;
(* (requires Winamp 2.4+)
** SendMessage(hwnd_winamp,WM_WA_IPC,value,IPC_SET_REPEAT);
**
** IPC_SET_REPEAT sets the status of the Repeat option (1 to turn it on)
*)
IPC_ENABLEDISABLE_ALL_WINDOWS = 259; // 0xdeadbeef to disable
(* (requires Winamp 2.9+)
** SendMessage(hwnd_winamp,WM_WA_IPC,enable?0:0xdeadbeef,IPC_MBOPENREAL);
** sending with 0xdeadbeef as the param disables all winamp windows,
** any other values will enable all winamp windows.
*)
IPC_GETWND = 260;
(* (requires Winamp 2.9+)
** HWND h=SendMessage(hwnd_winamp,WM_WA_IPC,IPC_GETWND_xxx,IPC_GETWND);
** returns the HWND of the window specified.
*)
IPC_GETWND_EQ = 0; // use one of these for the param
IPC_GETWND_PE = 1;
IPC_GETWND_MB = 2;
IPC_GETWND_VIDEO = 3;
IPC_ISWNDVISIBLE = 261; // same param as IPC_GETWND
(************************************************************************
***************** in-process only (WE LOVE PLUGINS)
************************************************************************)
IPC_GETHTTPGETTER = 240;
(* retrieves a function pointer to a HTTP retrieval function.
** if this is unsupported, returns 1 or 0.
** the function should be:
** int (*httpRetrieveFile)(HWND hwnd, char *url, char *file, char *dlgtitle);
** if you call this function, with a parent window, a URL, an output file, and a dialog title,
** it will return 0 on successful download, 1 on error.
*)
IPC_MBOPEN = 241;
(* (requires Winamp 2.05+)
** SendMessage(hwnd_winamp,WM_WA_IPC,0,IPC_MBOPEN);
** SendMessage(hwnd_winamp,WM_WA_IPC,(WPARAM)url,IPC_MBOPEN);
** IPC_MBOPEN will open a new URL in the minibrowser. if url is NULL, it will open the Minibrowser window.
*)
IPC_CHANGECURRENTFILE = 245;
(* (requires Winamp 2.05+)
** SendMessage(hwnd_winamp,WM_WA_IPC,(WPARAM)file,IPC_CHANGECURRENTFILE);
** IPC_CHANGECURRENTFILE will set the current playlist item.
*)
IPC_GETMBURL = 246;
(* (requires Winamp 2.2+)
* var
** buffer: array[0..4096] of char; // Urls can be VERY long
** SendMessage(hwnd_winamp,WM_WA_IPC,(WPARAM)buffer,IPC_GETMBURL);
** IPC_GETMBURL will retrieve the current Minibrowser URL into buffer.
** buffer must be at least 4096 bytes long.
*)
IPC_MBBLOCK = 248;
(* (requires Winamp 2.4+)
** SendMessage(hwnd_winamp,WM_WA_IPC,value,IPC_MBBLOCK);
**
** IPC_MBBLOCK will block the Minibrowser from updates if value is set to 1
*)
IPC_MBOPENREAL = 249;
(* (requires Winamp 2.4+)
** SendMessage(hwnd_winamp,WM_WA_IPC,(WPARAM)url,IPC_MBOPENREAL);
**
** IPC_MBOPENREAL works the same as IPC_MBOPEN except that it will works even if
** IPC_MBBLOCK has been set to 1
*)
IPC_ADJUST_OPTIONSMENUPOS = 280;
(* (requires Winamp 2.9+)
** int newpos=SendMessage(hwnd_winamp,WM_WA_IPC,(WPARAM)adjust_offset,IPC_ADJUST_OPTIONSMENUPOS);
** moves where winamp expects the Options menu in the main menu. Useful if you wish to insert a
** menu item above the options/skins/vis menus.
*)
IPC_GET_HMENU = 281;
(* (requires Winamp 2.9+)
** HMENU hMenu=SendMessage(hwnd_winamp,WM_WA_IPC,(WPARAM)0,IPC_GET_HMENU);
** values for data:
** 0 : main popup menu
** 1 : main menubar file menu
** 2 : main menubar options menu
** 3 : main menubar windows menu
** 4 : main menubar help menu
** other values will return NULL.
*)
IPC_GET_EXTENDED_FILE_INFO = 290; //pass a pointer to the following struct in wParam
IPC_GET_EXTENDED_FILE_INFO_HOOKABLE = 296;
(* (requires Winamp 2.9+)
** to use, create an extendedFileInfoStruct, point the values filename and metadata to the
** filename and metadata field you wish to query, and ret to a buffer, with retlen to the
** length of that buffer, and then SendMessage(hwnd_winamp,WM_WA_IPC,&struct,IPC_GET_EXTENDED_FILE_INFO);
** the results should be in the buffer pointed to by ret.
** returns 1 if the decoder supports a getExtendedFileInfo method
*)
type
p_extendedFileInfoStruct = ^extendedFileInfoStruct;
extendedFileInfoStruct = packed record
filename: pchar;
metadata: pchar;
ret: pchar;
retlen: integer;
end;
const
IPC_GET_BASIC_FILE_INFO = 291; //pass a pointer to the following struct in wParam
type
p_basicFileInfoStruct = ^basicFileInfoStruct;
basicFileInfoStruct = packed record
filename: pchar;
quickCheck: integer; // set to 0 to always get, 1 for quick, 2 for default (if 2, quickCheck will be set to 0 if quick wasnot used)
length: integer;
title: pchar;
titlelen: integer;
end;
const
IPC_GET_EXTLIST = 292; //returns doublenull delimited. GlobalFree() it when done. if data is 0, returns raw extlist, if 1, returns something suitable for getopenfilename
IPC_INFOBOX = 293;
type
p_infoBoxParam = ^infoBoxParam;
infoBoxParam = packed record
parent: HWND;
filename: pchar;
end;
const
IPC_SET_EXTENDED_FILE_INFO = 294; //pass a pointer to the a extendedFileInfoStruct in wParam
(* (requires Winamp 2.9+)
** to use, create an extendedFileInfoStruct, point the values filename and metadata to the
** filename and metadata field you wish to write in ret. (retlen is not used). and then
** SendMessage(hwnd_winamp,WM_WA_IPC,&struct,IPC_SET_EXTENDED_FILE_INFO);
** returns 1 if the metadata is supported
** Call IPC_WRITE_EXTENDED_FILE_INFO once you're done setting all the metadata you want to update
*)
const
IPC_WRITE_EXTENDED_FILE_INFO = 295;
(* (requires Winamp 2.9+)
** writes all the metadata set thru IPC_SET_EXTENDED_FILE_INFO to the file
** returns 1 if the file has been successfully updated, 0 if error
*)
IPC_FORMAT_TITLE = 297;
type
p_waFormatTitle = ^waFormatTitle;
waFormatTitle = packed record
spec: pchar; // nil = default winamp spec
p: pointer;
_out: pchar;
out_len: integer;
TAGFUNC: function (tag: pchar; p: pointer): pchar cdecl; //return 0 if not found
TAGFREEFUNC: procedure (tag: pchar; p: pointer) cdecl;
end;
const
IPC_GETUNCOMPRESSINTERFACE = 331;
(* returns a function pointer to uncompress(): *)
type
uncompress = function (dest: pbyte; var destLen: LongInt; source: pbyte; sourceLen: LongInt): LongInt;
(** right out of zlib, useful for decompressing zlibbed data.
** if you pass the parm of $10100000, it will return a pointer to wa_inflate_struct to an inflate API.
*)
type
p_wa_inflate_struct = ^wa_inflate_struct;
wa_inflate_struct = packed record
inflateReset: function (strm: pointer): integer cdecl;
inflateInit_: function (strm: pointer; version: pchar; stream_size: integer): integer cdecl;
inflate: function (strm: pointer; flush: boolean): integer cdecl;
inflateEnd: function (strm: pointer): integer cdecl;
crc32: function (crc: cardinal; buffer: pbyte; len: cardinal): cardinal cdecl;
end;
const
IPC_ADD_PREFS_DLG = 332;
IPC_REMOVE_PREFS_DLG = 333;
(* (requires Winamp 2.9+)
** to use, allocate a prefsDlgRec structure (either on the heap or some global
** data, but NOT on the stack), initialze the members:
** hInst to the DLL instance where the resource is located
** dlgID to the ID of the dialog,
** proc to the window procedure for the dialog
** name to the name of the prefs page in the prefs.
** where to 0 (eventually we may add more options)
** then, SendMessage(hwnd_winamp,WM_WA_IPC,&prefsRec,IPC_ADD_PREFS_DLG);
**
** you can also IPC_REMOVE_PREFS_DLG with the address of the same prefsRec,
** but you shouldn't really ever have to.
**
*)
IPC_OPENPREFSTOPAGE = 380; // pass an id of a builtin page, or a &prefsDlgRec of prefs page to open
type
p_prefsDlgRec = ^prefsDlgRec;
prefsDlgRec = packed record
hInst: THandle;
dlgID: integer;
proc: pointer;
name: pchar;
where: integer; // 0 for options, 1 for plugins, 2 for skins, 3 for bookmarks, 4 for prefs
_id: integer;
next: p_prefsDlgRec;
end;
const
IPC_GETINIFILE = 334; // returns a pointer to winamp.ini
IPC_GETINIDIRECTORY = 335; // returns a pointer to the directory to put config files in (if you dont want to use winamp.ini)
IPC_SPAWNBUTTONPOPUP = 361; // param =
// 0 = eject
// 1 = previous
// 2 = next
// 3 = pause
// 4 = play
// 5 = stop
IPC_OPENURLBOX = 360; // pass a HWND to a parent, returns a HGLOBAL that needs to be freed with GlobalFree(), if successful
IPC_OPENFILEBOX = 362; // pass a HWND to a parent
IPC_OPENDIRBOX = 363; // pass a HWND to a parent
// pass an HWND to a parent. call this if you take over the whole UI so that the dialogs are not appearing on the
// bottom right of the screen since the main winamp window is at 3000x3000, call again with NULL to reset
IPC_SETDIALOGBOXPARENT = 364;
// pass 0 for a copy of the skin HBITMAP
// pass 1 for name of font to use for playlist editor likeness
// pass 2 for font charset
// pass 3 for font size
IPC_GET_GENSKINBITMAP = 503;
IPC_GET_EMBEDIF = 505; // pass an embedWindowState
// returns an HWND embedWindow(embedWindowState *); if the data is NULL, otherwise returns the HWND directly
type
p_embedWindowState = ^embedWindowState;
embedWindowState = packed record
me: HWND;
flags: integer;
r: TRect;
user_ptr: pointer; // for application use
extra_data: array [0..63] of integer; // for internal winamp use
end;
const
EMBED_FLAGS_NORESIZE = 1; // set this bit in embedWindowState.flags to keep window from being resizable
EMBED_FLAGS_NOTRANSPARENCY = 2; // set this bit in embedWindowState.flags to make gen_ff turn transparency off for this wnd
IPC_EMBED_ENUM = 532;
type
p_embedEnumStruct = ^embedEnumStruct;
embedEnumStruct = packed record
enumProc: function (ws: p_embedWindowState; param: p_embedEnumStruct): cardinal cdecl;
user_data: integer; // or more :)
end;
// pass
const
IPC_EMBED_ISVALID = 533;
IPC_CONVERTFILE = 506;
(* (requires Winamp 2.92+)
** Converts a given file to a different format (PCM, MP3, etc...)
** To use, pass a pointer to a waFileConvertStruct struct
** This struct can be either on the heap or some global
** data, but NOT on the stack. At least, until the conversion is done.
**
** eg: SendMessage(hwnd_winamp,WM_WA_IPC,&myConvertStruct,IPC_CONVERTFILE);
**
** Return value:
** 0: Can't start the conversion. Look at myConvertStruct->error for details.
** 1: Conversion started. Status messages will be sent to the specified callbackhwnd.
** Be sure to call IPC_CONVERTFILE_END when your callback window receives the
** IPC_CB_CONVERT_DONE message.
*)
type
p_convertFileStruct = ^convertFileStruct;
convertFileStruct = packed record
sourcefile: pchar; // "c:\\source.mp3"
destfilr: pchar; // "c:\\dest.pcm"
destformat: array[0..8] of integer; // like 'PCM ',srate,nch,bps
callbackwnd: HWND; // window that will receive the IPC_CB_CONVERT notification messages
error: pchar; //if IPC_CONVERTFILE returns 0, the reason will be here
bytes_done: integer; //you can look at both of these values for speed statistics
bytes_total: integer;
bytes_out: integer;
killswitch: integer; // don't set it manually, use IPC_CONVERTFILE_END
extra_data: array [0..63] of integer; // for internal winamp use
end;
const
IPC_CONVERTFILE_END = 507;
(* (requires Winamp 2.92+)
** Stop/ends a convert process started from IPC_CONVERTFILE
** You need to call this when you receive the IPC_CB_CONVERTDONE message or when you
** want to abort a conversion process
**
** eg: SendMessage(hwnd_winamp,WM_WA_IPC,&myConvertStruct,IPC_CONVERTFILE_END);
**
** No return value
*)
type
p_convertConfigStruct = ^convertConfigStruct;
convertConfigStruct = packed record
hwndParent: HWND;
format: integer;
hwndConfig: HWND;
extra_data: array[0..7] of integer;
end;
const
IPC_CONVERT_CONFIG = 508;
IPC_CONVERT_CONFIG_END = 509;
type
p_converterEnumFmtStruct = ^converterEnumFmtStruct;
converterEnumFmtStruct = packed record
enumProc: procedure (user_data: integer; desc: pchar; fourcc: integer) cdecl;
user_data: integer;
end;
const
IPC_CONVERT_CONFIG_ENUMFMTS = 510;
(* (requires Winamp 2.92+)
*)
type
p_burnCDStruct = ^burnCDStruct;
burnCDStruct = packed record
cdletter: char;
playlist_file: pchar;
callback_hwnd: HWND;
error: pchar;
end;
const
IPC_BURN_CD = 511;
(* (requires Winamp 5.0+)
*)
type
p_convertSetPriority = ^convertSetPriority;
convertSetPriority = packed record
cfs: p_convertFileStruct;
priority: integer;
end;
const
IPC_CONVERT_SET_PRIORITY = 512;
type
p_waHookTitleStruct = ^waHookTitleStruct;
waHookTitleStruct = packed record
filename: pchar;
title: pchar;
length: integer;
force_useformatting: LongBool;
end;
const
// return TRUE if you hook this
IPC_HOOK_TITLES = 850;
IPC_GETSADATAFUNC = 800;
// 0: returns a char *export_sa_get() that returns 150 bytes of data
// 1: returns a export_sa_setreq(int want);
IPC_ISMAINWNDVISIBLE = 900;
IPC_SETPLEDITCOLORS = 920;
type
p_waSetPlColorsStruct = ^waSetPlColorsStruct;
waSetPlColorsStruct = packed record
numElems: integer;
elems: PINT;
bm: HBITMAP;
end;
const
// the following IPC use waSpawnMenuParms as parameter
IPC_SPAWNEQPRESETMENU = 933;
IPC_SPAWNFILEMENU = 934; //menubar
IPC_SPAWNOPTIONSMENU = 935; //menubar
IPC_SPAWNWINDOWSMENU = 936; //menubar
IPC_SPAWNHELPMENU = 937; //menubar
IPC_SPAWNPLAYMENU = 938; //menubar
IPC_SPAWNPEFILEMENU = 939; //menubar
IPC_SPAWNPEPLAYLISTMENU = 940; //menubar
IPC_SPAWNPESORTMENU = 941; //menubar
IPC_SPAWNPEHELPMENU = 942; //menubar
IPC_SPAWNMLFILEMENU = 943; //menubar
IPC_SPAWNMLVIEWMENU = 944; //menubar
IPC_SPAWNMLHELPMENU = 945; //menubar
IPC_SPAWNPELISTOFPLAYLISTS = 946;
type
p_waSpawnMenuParms = ^waSpawnMenuParms;
waSpawnMenuParms = packed record
wnd: HWND;
xpos, ypos: integer;
end;
// waSpawnMenuParms2 is used by the menubar submenus
p_waSpawnMenuParms2 = ^waSpawnMenuParms2;
waSpawnMenuParms2 = packed record
wnd: HWND;
xpos, ypos: integer;
width, height: integer;
end;
const
// system tray sends this (you might want to simulate it)
WM_WA_SYSTRAY = WM_USER+1;
// input plugins send this when they are done playing back
WM_WA_MPEG_EOF = WM_USER+1;
//// video stuff
IPC_IS_PLAYING_VIDEO = 501; // returns >1 if playing, 0 if not, 1 if old version (so who knows):)
IPC_GET_IVIDEOOUTPUT = 500; // see below for IVideoOutput interface
function VIDEO_MAKETYPE(A, B, C, D: Cardinal): Cardinal;
const
VIDUSER_SET_INFOSTRING = $1000;
VIDUSER_GET_VIDEOHWND = $1001;
VIDUSER_SET_VFLIP = $1002;
type
VideoOutput = class;
Subsitem = class
end;
p_YV12_PLANE = ^YV12_PLANE;
YV12_PLANE = packed record
baseAddr: pbyte;
rowBytes: LongInt;
end;
p_YV12_PLANES = ^YV12_PLANES;
YV12_PLANES = packed record
y, u, v: YV12_PLANE;
end;
VideoMsgCallback = function (token: pointer; hwnd: HWND; uMsg, wParam, lParam: Cardinal): Cardinal;
VideoOutput = class
procedure _cpp_destructor() cdecl; virtual; abstract;
function open(w, h, vflip: integer; aspectration: double; fmt: cardinal): integer cdecl; virtual; abstract;
procedure setcallback(msgcallback: VideoMsgCallback; token: pointer) cdecl; virtual; abstract;
procedure draw(frame: pointer) cdecl; virtual; abstract;
procedure drawSubtitle(item: SubsItem) cdecl; virtual; abstract;
procedure showStatusMsg(text: pchar) cdecl; virtual; abstract;
function get_latency(): integer cdecl; virtual; abstract;
procedure notifyBufferState(bufferstate: integer) cdecl; virtual; abstract;
function extended(param1: integer; param2: integer; param3: integer): integer; virtual; abstract;
end;
// these messages are callbacks that you can grab by subclassing the winamp window
const
// wParam =
IPC_CB_WND_EQ = 0; // use one of these for the param
IPC_CB_WND_PE = 1;
IPC_CB_WND_MB = 2;
IPC_CB_WND_VIDEO = 3;
IPC_CB_WND_MAIN = 4;
IPC_CB_ONSHOWWND = 600;
IPC_CB_ONHIDEWND = 601;
IPC_CB_GETTOOLTIP = 602;
IPC_CB_MISC = 603;
IPC_CB_MISC_TITLE = 0;
IPC_CB_MISC_VOLUME = 1; // volume/pan
IPC_CB_MISC_STATUS = 2;
IPC_CB_MISC_EQ = 3;
IPC_CB_MISC_INFO = 4;
IPC_CB_MISC_VIDEOINFO = 5;
IPC_CB_CONVERT_STATUS = 604; // param value goes from 0 to 100 (percent)
IPC_CB_CONVERT_DONE = 605;
IPC_ADJUST_FFWINDOWSMENUPOS = 606;
(* (requires Winamp 2.9+)
** int newpos=SendMessage(hwnd_winamp,WM_WA_IPC,(WPARAM)adjust_offset,IPC_ADJUST_FFWINDOWSMENUPOS);
** moves where winamp expects the freeform windows in the menubar windows main menu. Useful if you wish to insert a
** menu item above extra freeform windows.
*)
IPC_ISDOUBLESIZE = 608;
IPC_ADJUST_FFOPTIONSMENUPOS = 609;
(* (requires Winamp 2.9+)
** int newpos=SendMessage(hwnd_winamp,WM_WA_IPC,(WPARAM)adjust_offset,IPC_ADJUST_FFOPTIONSMENUPOS);
** moves where winamp expects the freeform preferences item in the menubar windows main menu. Useful if you wish to insert a
** menu item above preferences item.
*)
IPC_GETTIMEDISPLAYMODE = 610; // returns 0 if displaying elapsed time or 1 if displaying remaining time
IPC_SETVISWND = 611; // param is hwnd, setting this allows you to receive ID_VIS_NEXT/PREVOUS/RANDOM/FS wm_commands
ID_VIS_NEXT = 40382;
ID_VIS_PREV = 40383;
ID_VIS_RANDOM = 40384 ;
ID_VIS_FS = 40389 ;
ID_VIS_CFG = 40390 ;
ID_VIS_MENU = 40391 ;
IPC_GETVISWND = 612; // returns the vis cmd handler hwnd
IPC_ISVISRUNNING = 613;
IPC_CB_VISRANDOM = 628 ;// param is status of random
IPC_SETIDEALVIDEOSIZE = 614; // sent by winamp to winamp, trap it if you need it. width=HIWORD(param), height=LOWORD(param)
IPC_GETSTOPONVIDEOCLOSE = 615;
IPC_SETSTOPONVIDEOCLOSE = 616 ;
type
p_transAccelStruct = ^transAccelStruct;
transAccelStruct = packed record
hwnd: HWND;
uMsg: Integer;
wParam, lParam: Integer;
end;
const
IPC_TRANSLATEACCELERATOR = 617;
type
p_windowCommand = ^windowCommand;
windowCommand = packed record
cmd, x, y, align: Integer;
end;
const
IPC_CB_ONTOGGLEAOT = 618;
IPC_GETPREFSWND = 619;
IPC_SET_PE_WIDTHHEIGHT = 620; // data is a pointer to a POINT structure that holds width & height
IPC_GETLANGUAGEPACKINSTANCE = 621;
IPC_CB_PEINFOTEXT = 622; // data is a string, ie: "04:21/45:02"
IPC_CB_OUTPUTCHANGED = 623; // output plugin was changed in config
IPC_GETOUTPUTPLUGIN = 625;
IPC_SETDRAWBORDERS = 626;
IPC_DISABLESKINCURSORS = 627;
IPC_CB_RESETFONT = 629;
IPC_IS_FULLSCREEN = 630; // returns 1 if video or vis is in fullscreen mode
IPC_SET_VIS_FS_FLAG = 631; // a vis should send this message with 1/as param to notify winamp that it has gone to or has come back from fullscreen mode
IPC_SHOW_NOTIFICATION = 632;
IPC_GETSKININFO = 633;
// >>>>>>>>>>> Next is 634
IPC_PLCMD = 1000;
PLCMD_ADD = 0;
PLCMD_REM = 1;
PLCMD_SEL = 2;
PLCMD_MISC = 3;
PLCMD_LIST = 4;
IPC_MBCMD = 1001;
MBCMD_BACK = 0;
MBCMD_FORWARD = 1;
MBCMD_STOP = 2;
MBCMD_RELOAD = 3;
MBCMD_MISC = 4;
IPC_VIDCMD = 1002;
VIDCMD_FULLSCREEN = 0;
VIDCMD_1X = 1;
VIDCMD_2X = 2;
VIDCMD_LIB = 3;
VIDPOPUP_MISC = 4;
IPC_MBURL = 1003; //sets the URL
IPC_MBGETCURURL = 1004; //copies the current URL into wParam (have a 4096 buffer ready)
IPC_MBGETDESC = 1005 ;//copies the current URL description into wParam (have a 4096 buffer ready)
IPC_MBCHECKLOCFILE = 1006; //checks that the link file is up to date (otherwise updates it). wParam=parent HWND
IPC_MBREFRESH = 1007; //refreshes the "now playing" view in the library
IPC_MBGETDEFURL = 1008; //copies the default URL into wParam (have a 4096 buffer ready)
IPC_STATS_LIBRARY_ITEMCNT = 1300; // updates library count status
// IPC 2000-3000 reserved for freeform messages, see gen_ff/ff_ipc.h
IPC_FF_FIRST = 2000;
IPC_FF_LAST = 3000;
IPC_GETDROPTARGET = 3001;
IPC_PLAYLIST_MODIFIED = 3002; // sent to main wnd whenever the playlist is modified
IPC_PLAYING_FILE = 3003 ;// sent to main wnd with the file as parm whenever a file is played
IPC_FILE_TAG_MAY_HAVE_UPDATED = 3004; // sent to main wnd with the file as parm whenever a file tag might be updated
IPC_ALLOW_PLAYTRACKING = 3007;
// send nonzero to allow, zero to disallow
IPC_HOOK_OKTOQUIT = 3010; // return 0 to abort a quit, nonzero if quit is OK
IPC_WRITECONFIG = 3011; // pass 2 to write all, 1 to write playlist + common, 0 to write common+less common
// pass a string to be the name to register, and returns a value > 65536, which is a unique value you can use
// for custom WM_WA_IPC messages.
IPC_REGISTER_WINAMP_IPCMESSAGE = 65536 ;
implementation
function VIDEO_MAKETYPE(A, B, C, D: Cardinal): Cardinal;
begin
Result := A or (B shl 8) or (C shl 16) or (D shl 24);
end;
end.
2 comments:
Hi There :)
Great to see other ppl have searching for this. I will try it like, hmmm, the 24st amp-ctrl i tested.
Thank You
Best regards, Thule
Hi There :)
Great to see other ppl have searching for this. I will try it like, hmmm, the 24st amp-ctrl i tested.
Thank You
Best regards, Thule
Post a Comment