Hier fängt die geschichte an.
Delphi-Quellcode:
// Initialisiert das BASS_WADSP add-on
Function BASS_WADSP_Init(hwndMain: HWND): DWORD; stdcall;
begin
mainhwnd := hwndMain;
Result:= mainhwnd;
end;
Ist OK !!
Plugins werden eingeladen
Delphi-Quellcode:
// Läd ein Winamp DSP Plugin und übergibt das handle
// Koordinaten und ein User Callback können übergeben werden
function BASS_WADSP_Load(
const dspfile: PChar; x, y, Width, Height: integer;
proc: WINAMPWINPROC): HDSP;
stdcall;
var
winampDsp: WINAMPPLUGINPROPDSP;
cnt: integer;
begin
winampDsp := AllocMem(sizeof(WINAMPPLUGINPROPDSP));
FillChar(winampDsp, 0, sizeof(winampDsp));
Saved8087CW := Default8087CW;
//FPU - Exceptions deaktivieren
Set8087CW($133f);
// Library laden
// zuerst mit unicode versuchen
winampDsp^.hDll := LoadLibraryW(PWideChar(dspfile));
if (
not winampDsp^.hDll) <> 0
then
begin
// ansonsten Ansi
winampDsp^.hDll := LoadLibrary(dspfile);
end;
// Exceptions zurück auf Defaultwert
Set8087CW(Saved8087CW);
Result := 0;
if winampDsp^.hDll <> 0
then
begin
FreeMem(winampDsp);
pGetMod := GetProcAddress(winampDsp^.hDll, '
winampDSPGetHeader2');
if pGetMod <>
nil then
begin
// Fake Winamp Window erstellen
if (Create_Winamp_Window(winampDsp, x, y, Width, Height, proc)) = True
then
begin
cnt := 0;
winampDsp^.pModule := pGetMod;
if winampDsp^.pModule <>
nil then
begin
// Schleife durchlaufen bis kein Modul mehr gefunden wurde
repeat
Inc(cnt);
until winampDsp^.pModule^.getModule(cnt) =
nil;
// Anzahl der Module speichern
winampDsp^.NumberOfModules := cnt;
winampDsp^.module := -1;
InitializeCriticalSection(winampDsp^.csh);
// Addiere ein neues Winamp DSP Plugin
AddDSP(winampDsp);
// Übergebe das Handle
Result := winampDsp^.handle
end else
// Bei Fehler Winamp Fake Window beenden
Destroy_Winamp_Window(winampDsp);
end else
// Library freigeben
FreeLibrary(winampDsp^.hDll);
end
end
end;
Ist OK !!
FakeWindow wird erstellt! Für jedes Plugin einzeln.
Delphi-Quellcode:
// Erstellt ein Fake Winamp window
function Create_Winamp_Window(winampDsp: WINAMPPLUGINPROPDSP; x, y, width, height: integer; proc: WINAMPWINPROC): Boolean; stdcall;
var
wndclass: WNDCLASSEX;
dspCount : DWORD;
AppClass : Pchar;
begin
dspCount := GetActiveDSPs;
if dspCount > 0 then
begin
AppClass := PChar(Format(Pchar('Winamp v1.x : %d'), [winampDSPcounter + 1]));
end else
AppClass := 'Winamp v1.x';
Inst := GetModuleHandle(nil);
with wndclass do
begin
cbSize := sizeof(wndclass);
style := CS_PARENTDC or CS_VREDRAW;
cbClsExtra := 0;
cbWndExtra := 0;
hInstance := Inst;
hIcon := 0;
hCursor := LoadCursor(0, IDC_ARROW);
hbrBackground := 0;
lpszMenuName := nil;
lpszClassName := AppClass;
if proc = 0 then
lpfnWndProc := @WinampWndProc
else
lpfnWndProc := @proc;
hIconSm := 0;
end;
winampDsp^.DSP_Atom_Emu := RegisterClassEx(wndclass);
if winampDsp^.DSP_Atom_Emu <> 0 then
winampDsp^.DSP_Atom_Emu := CreateWindowEx(0, // DWORD dwExStyle
AppClass, // LPCTSTR lpClassName
'Winamp 2.40', // LPCTSTR lpWindowName
WS_POPUP, // DWORD dwStyle
x, // int x
y, // int y
width, // int nWidth
height, // int nHeight
mainhwnd, // HWND hWndParent
0, // HMENU hMenu
Inst, // // HINSTANCE hInstance
nil); // LPVOID lpParam
if winampDsp^.DSP_Window_Emu = 0 then
begin
UnRegisterClass(PChar(WORD(winampDsp^.DSP_Atom_Emu)), Inst);
MessageBox(mainhwnd, 'Unable to emulate Winamp Window!', 'BASS DSP Error!', MB_ICONEXCLAMATION or MB_ICONWARNING);
Result := false
end
else
Result := true;
end;
Ist OK!
Aus der Winproc wird die Funktion GetActiveDSPs aufgerufen welche
den Counter hochzählt und abhängig davon den ClassenNamen ändert
AppClass := PChar(Format(Pchar('Winamp v1.x : %d'), [winampDSPcounter + 1]));
damit nicht zwei die gleichen Windows erstellt werden.
Delphi-Quellcode:
function GetActiveDSPs(): DWORD; stdcall;
var
a: DWORD;
cnt: DWORD;
winampDSP: WINAMPPLUGINPROPDSP;
begin
cnt := 0;
if Winamp_DSP <> nil then
for a := 0 to winampDSPcounter do
begin
winampDSP := Winamp_DSP[a];
if winampDSP <> nil then
Inc(cnt);
end;
Result := cnt;
end;
Das ist auch in Ornung!
Dann wir das gewählte Plugin addiert.
Delphi-Quellcode:
Procedure AddDSP(winampDsp: WINAMPPLUGINPROPDSP);
stdcall;
var
a: DWORD;
begin
Winamp_DSP := DspPtrArray(winampDsp);
for a := 0
to winampDSPcounter
do
if not Assigned(Winamp_DSP[a])
then
Break;
if a = winampDSPcounter
then
begin
// Array nicht leer, füge ein neues hinzu
ReallocMem(Winamp_DSP, (winampDSPcounter + 1) * SizeOf(WINAMPPLUGINPROPDSP));
Dec(winampDSPcounter);
end;
Inc(winampDSPhandle);
winampDsp^.handle := winampDSPhandle;
// addiere ein Winamp DSP Plugin zum Array
Winamp_DSP[a] := winampDsp;
end;
Scheint OK zu sein. Obwohl bisher noch nie in ReallocMem reingesprungen wurde.
Nun wird der Name des Moduls übergeben
Delphi-Quellcode:
// Returns the name of a loaded Winamp DSP plugin
function BASS_WADSP_GetName(plugin: HDSP): LPTSTR; stdcall;
Var
strRet: PChar;
winampDSP: WINAMPPLUGINPROPDSP;
begin
strRet := nil;
winampDsp := GetDSP(plugin);
if winampDsp <> nil then
begin
strRet := winampDsp^.pModule^.description;
end;
Result := strRet;
end;
ist auch OK!
GetDSP übergibt den wert aus dem ArrayWinamp_DSP[a]
Delphi-Quellcode:
function GetDSP(
handle: DWORD): WINAMPPLUGINPROPDSP;
var
a: DWORD;
begin
if handle <> 0
then
for a := 0
to Pred(winampDSPcounter)
do
begin
Result := Winamp_DSP[a];
if Assigned(Result)
and (Result^.handle =
handle)
then Exit;
end;
Result :=
nil;
end;
ist auch in Ordnung!
Dann wird das Plugin entladen und das nächste eingeladen falls vorhanden.
Delphi-Quellcode:
// Entlade das übergebene Winamp DSP Plugin
Procedure BASS_WADSP_FreeDSP(plugin: HDSP); stdcall ;
begin
FreeDSP(plugin);
end;
So bis hier ist alles OK!
gruß