📄 wa_ipc.pas
字号:
IPC_CHANGECURRENTFILE = 245;
(* (requires Winamp 2.05+)
** SendMessage(hwnd_winamp,WM_WA_IPC,WPARAM(PChar(file)),IPC_CHANGECURRENTFILE);
** IPC_CHANGECURRENTFILE will set the current playlist item.
*)
IPC_GETMBURL = 246;
(* (requires Winamp 2.2+)
** var buffer: array[0..4095] of Char; // Urls can be VERY long
** SendMessage(hwnd_winamp,WM_WA_IPC,WPARAM(Pointer(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(PChar(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+)
** 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 := SendMessage(hwnd_winamp,WM_WA_IPC,WPARAM(0),IPC_GET_HMENU);
** returns the main popup menu if the data is 0.
** other values are currently undefined, and will return nil.
*)
IPC_GET_EXTENDED_FILE_INFO = 290; {pass a pointer to the following struct 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 query, and ret to a buffer, with retlen to the
** length of that buffer, and then SendMessage(hwnd_winamp,WM_WA_IPC,Integer(@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
PextendedFileInfoStruct = ^TextendedFileInfoStruct;
TextendedFileInfoStruct = 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
PbasicFileInfoStruct = ^TbasicFileInfoStruct;
TbasicFileInfoStruct = record
filename: PChar;
quickCheck: Integer;
{filled in by winamp}
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
PinfoBoxParam = ^TinfoBoxParam;
TinfoBoxParam = record
parent: HWND;
filename: PChar;
end;
{ [Saivert] Nullsoft didn't specify this, but I guess you call it like:
SendMessage(hwnd_winamp,WM_WA_IPC,Integer(@AnInfoBoxParam),IPC_INFOBOX);
}
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,Integer(@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
*)
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
PwaFormatTitle = ^TwaFormatTitle;
TwaFormatTitle = record
spec : pchar; // NULL=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().
** int (*uncompress)(unsigned char *dest, unsigned long *destLen, const unsigned char *source, unsigned long sourceLen);
** right out of zlib, useful for decompressing zlibbed data.
*)
{ [Saivert] Here I have a function prototype suitable for use in Delphi: }
type
TFNuncompress = function(dest: PChar; var destLen: Integer; source: PChar; sourceLen: Longint): Integer; stdcall;
Pwa_inflate_struct = ^Twa_inflate_struct;
Twa_inflate_struct = record
inflateReset : function(strm : Pointer) : integer; cdecl;
inflateInit_ : function(strm : Pointer;version : pchar;stream_size : integer) : integer; cdecl;
inflate : function(strm : Pointer;flush : integer) : integer; cdecl;
inflateEnd : function(strm : Pointer) : integer; cdecl;
crc32 : function(crc : DWORD;buf : Pointer;len : DWORD) : DWORD; cdecl;
end;
{ [Saivert] Please read my comments about IPC_ADD_PREFS_DLG below }
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,Integer(@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.
**
*)
(* [Saivert] original c statement kept for reference
typedef struct _prefsDlgRec {
HINSTANCE hInst;
int dlgID;
void *proc;
char *name;
int where; // 0 for options, tho we need to define more
int _id;
struct _prefsDlgRec *next;
} prefsDlgRec;
*)
type
PprefsDlgRec = ^TprefsDlgRec;
TprefsDlgRec = record
_hInst: HINST;
dlgID: Integer;
proc: Pointer;
name: PChar;
where: Integer; {0 for options, though we they need to define more}
_id: Integer;
_prefsDlgRec: PprefsDlgRec;
end;
const
IPC_GETINIFILE = 334; {returns a pointer to winamp.ini}
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 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 }
(*
typedef struct
{
HWND me; //hwnd of the window
int flags;
RECT r;
void *user_ptr; // for application use
int extra_data[64]; // for internal winamp use
} embedWindowState;
*)
IPC_EMBED_ENUM = 532;
IPC_EMBED_ISVALID = 533;
type
PembedWindowState = ^TembedWindowState;
TembedWindowState = record
me: HWND;
flags: Integer;
r: TRect;
user_ptr: Pointer;
extra_data: array[0..65] of Integer;
end;
{ Here is a function prototype for IPC_GET_EMBEDIF }
TembedWindow = function(ews: PembedWindowState): HWND; cdecl;
PembedEnumStruct = ^TembedEnumStruct;
TembedEnumStruct = record
enumProc : function(ws : PembedWindowState;param : PembedEnumStruct) : integer; cdecl;
user_data : integer;
end;
const
EMBED_FLAGS_NORESIZE = 1; { set this bit in embedWindowState.flags to keep window from being resizable}
{ 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+2;
{ Still to be converted, do it yourself if you like. }
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;
//// video stuff
const
IPC_GET_IVIDEOOUTPUT = 500; { see below for IVideoOutput interface }
{ VIDEO_MAKETYPE(A,B,C,D) ((A) | ((B)<<8) | ((C)<<16) | ((D)<<24)) }
{ There is no MACRO equivalent in Pascal, so here is a function which does the same: }
function Video_MakeType(A, B, C, D: Integer): Integer;
const
VIDUSER_SET_INFOSTRING = $1000;
VIDUSER_GET_VIDEOHWND = $1001;
VIDUSER_SET_VFLIP = $1002;
type
PYV12_PLANE = ^TYV12_PLANE;
TYV12_PLANE = record
baseAddr : pchar;
rowBytes : integer;
end;
PYV12_PLANES = ^TYV12_PLANES;
TYV12_PLANES = record
y : TYV12_PLANE;
u : TYV12_PLANE;
v : TYV12_PLANE;
end;
Tmsgcallback = function(token : Pointer;hwnd :THandle;uMsg,wParam,lParam : integer) : HResult; cdecl;
PVideoOutput = ^IVideoOutput;
IVideoOutput = object
procedure DesVideoOutput; virtual; cdecl; abstract;
function open(w,h,vflip : integer;aspectratio : double;fmt : Cardinal) : integer; virtual; cdecl; abstract;
procedure setcallback(func : Tmsgcallback;token : Pointer); virtual; cdecl; abstract;
procedure close; virtual; cdecl; abstract;
procedure draw(frame : Pointer); virtual; cdecl; abstract;
procedure drawSubtitle(item : Pointer); virtual; cdecl; abstract;
procedure showStatusMsg(text : pchar); virtual; cdecl; abstract;
function get_latency : integer; virtual; cdecl; abstract;
procedure notifyBufferState(bufferstate : integer); virtual; cdecl; abstract;
function extended(param1,param2,param3 : integer) : integer; virtual; cdecl; abstract;
end;
{ these messages are callbacks that you can grab by subclassing the winamp window }
{ wParam = }
const
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_ONSHOWWND = 600;
IPC_CB_ONHIDEWND = 601;
IPC_PLAYING_FILE = 3003;
(*
[Saivert]
The new feature where you can add your own page to the prefs in Winamp,
only supports native Windows dialogs. So to add a TForm based window to
the preferences dialog in winamp, you have to manually create a resource
script containing these lines:
your_id DIALOG 0 0 144 154
STYLE WS_CHILD
BEGIN
END
where your_id must be a number not used by any other DIALOG resource.
Save this as a text file named something like "myprefs.rc" and save it
in the same folder as your project.
This file has to be compiled into a binary resource form.
To do this type at the command prompt:
(you must CD to your projects directory, and it assumes
that your Delphi program directory is in the path)
brcc32 myprefs.rc <ENTER>
or if that didn't work...
brc32 -r myprefs.rc <ENTER>
This creates a file called "myprefs.res".
Now it is time to import this resource into your Delphi project.
Add a line anywhere in your source (e.g. your .DPR file) that looks like
this:
{$R myprefs.res}
Now when you have set up a dialog resource and imported it into your project,
it is time to write the code that actually make it work. Here it goes:
Prepare your form for use in the prefs dialog. Be sure...
...that all controls fits within a rectangle of 287x309 in size.
...that the form is not loaded automatically at startup.
E.g.: "Application.CreateForm(yourform, Tyourform)" does not exist.
Now assuming your form is "yourform" write this window procedure:
function myprefsDlgProc(dlg: HWND; msg: UINT; wParam: WPARAM; lParam: LPARAM): BOOL; stdcall; {very important with stdcall calling convention}
begin
result := False;
case msg of
WM_INITDIALOG: begin
yourform := Tyourform.Create(nil);
SetParent(yourform.Handle, dlg);
yourform.BorderStyle := bsNone;
SetWindowPos(yourform.Handle, 0, 0, 0, 287, 309, SWP_NOZORDER);
ConfigForm.Show;
result := False;
end;
WM_DESTROY: yourform.Free;
end;
end;
Set up a TprefsDlgRec record (must be in a interface section):
var
myprefsRec: TprefsDlgRec;
Fill the members of the record
(do this in a Plugin initialization function):
with myprefsrec do
begin
_hInst := HInstance; { or This_Mod^.hDLLInstance }
dlgID := your_id; { set to id specified in resource script, must be a number }
proc := @myprefsDlgProc;
name := 'My Prefs'; {page name}
where := 0; {0 means to place it under "Options". More to come...}
{ do not care about _id and/or _prefsDlgRec which is handled by Winamp }
end;
Now it is time to put it into winamp's preferences dialog, call this:
SendMessage(hwnd_winamp,WM_WA_IPC,Integer(@myprefsrec),IPC_ADD_PREFS_DLG);
That's it!
PS! Any OnMouseEnter and OnMouseLeave events associated with VCL controls,
won't be triggered because of compatibility issues, sorry!
*)
implementation
{ VIDEO_MAKETYPE(A,B,C,D) ((A) | ((B)<<8) | ((C)<<16) | ((D)<<24)) }
{ There is no MACRO equivalent in Pascal, so here is a function which does the same: }
function Video_MakeType(A, B, C, D: Integer): Integer;
begin
Result:= A or (B shl 8) or (C shl 16) or (D shl 24);
end;
end.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -