📄 jvwinampapi.pas
字号:
{-----------------------------------------------------------------------------
The contents of this file are subject to the Mozilla Public License
Version 1.1 (the "License"); you may not use this file except in compliance
with the License. You may obtain a copy of the License at
http://www.mozilla.org/MPL/MPL-1.1.html
Software distributed under the License is distributed on an "AS IS" basis,
WITHOUT WARRANTY OF ANY KIND, either expressed or implied. See the License for
the specific language governing rights and limitations under the License.
The Original Code is: JvWinampApi.PAS, released on 2001-02-28.
The Initial Developer of the Original Code is S閎astien Buysse [sbuysse att buypin dott com]
Portions created by S閎astien Buysse are Copyright (C) 2001 S閎astien Buysse.
All Rights Reserved.
Contributor(s): Michael Beck [mbeck att bigfoot dott com].
Last Modified: 2000-02-28
You may retrieve the latest version of this file at the Project JEDI's JVCL home page,
located at http://jvcl.sourceforge.net
Known Issues:
-----------------------------------------------------------------------------}
{$I JVCL.INC}
unit JvWinampApi;
interface
uses
Windows, Messages, SysUtils, Classes, Controls,
Winamp,
JvTypes, JvComponent;
type
TWStatus = (wsNotAvailable, wsStopped, wsPlaying, wsPaused);
TWinampEqualizer = record
Bands: array [0..9] of Integer;
Preamp: Integer;
Enabled, AutoLoad: Boolean;
end;
TJvPlayOption = (poRepeat, poShuffle);
TJvPlayOptions = set of TJvPlayOption;
TJvWinampApi = class(TJvComponent)
private
FWinampHandle: THandle;
FDummy: Boolean;
FDummyI: Integer;
FDummyW: TWStatus;
FDummyT: TTime;
function GetBitRate: Integer;
function GetChannels: Integer;
function GetListLength: Integer;
function GetMajorVersion: Integer;
function GetMinorVersion: Integer;
function GetPlaylistPos: Integer;
function GetPlayOptions: TJvPlayOptions;
function GetSampleRate: Integer;
function GetEqualizer: TWinampEqualizer;
function GetSongLength: TTime;
function GetSongPosition: TTime;
function GetWinampHandle: THandle;
function GetWinampPresent: Boolean;
function GetWinampStatus: TWStatus;
procedure SetEqualizer(const Value: TWinampEqualizer);
procedure SetPlaylistPos(const Value: Integer);
procedure SetPlayOptions(const Value: TJvPlayOptions);
procedure SetSongPosition(const Value: TTime);
function CheckWinampHigher(Major, Minor: Integer): Boolean;
procedure SendCommand(Value: Integer);
protected
{ Refreshes the winamp handle }
procedure RefreshHandle;
{ Raises an error when the winamp handle = 0 }
procedure CheckHandle;
// (rom) added helper
procedure RefreshAndCheckHandle;
public
procedure ClearPlaylist;
procedure SavePlaylist;
procedure Play;
procedure SetVolume(Value: Byte = 122);
procedure SetPanning(Value: Byte = 122);
procedure ShowOptions;
procedure ShowAbout;
procedure OpenFiles;
procedure ToggleAlwaysOnTop;
procedure ToggleEqualizer;
procedure TogglePlaylist;
procedure OpenFile(FileName: string);
procedure SetDirectory(Directory: string);
procedure VolumeInc;
procedure VolumeDec;
procedure FastForward;
procedure FastRewind;
procedure OpenLocation;
procedure PreviousTrack;
procedure NextTrack;
procedure Stop;
procedure Pause;
procedure StartOfList;
procedure EndOfList;
procedure StopWithFadeout;
property WinampHandle: THandle read GetWinampHandle;
property Equalizer: TWinampEqualizer read GetEqualizer write SetEqualizer;
published
property WinampPresent: Boolean read GetWinampPresent write FDummy stored False;
property WinampMajorVersion: Integer read GetMajorVersion write FDummyI stored False;
property WinampMinorVersion: Integer read GetMinorVersion write FDummyI stored False;
property WinampStatus: TWStatus read GetWinampStatus write FDummyW stored False;
property SongPosition: TTime read GetSongPosition write SetSongPosition stored False;
property SongLength: TTime read GetSongLength write FDummyT stored False;
property PlaylistPos: Integer read GetPlaylistPos write SetPlaylistPos stored False;
property SampleRate: Integer read GetSampleRate write FDummyI stored False;
property BitRate: Integer read GetBitRate write FDummyI stored False;
property Channels: Integer read GetChannels write FDummyI stored False;
property ListLength: Integer read GetListLength write FDummyI stored False;
property PlayOptions: TJvPlayOptions read GetPlayOptions write SetPlayOptions stored False;
end;
EWinampError = class(EJVCLException);
implementation
resourcestring
{ (rb) prefix resourcestrings consistently }
RC_WinampWindow = 'Winamp v1.x';
RC_WinampFormat = 'You must have Winamp %d.%d or higher to execute this Api';
RC_ErrorFinding = 'Could not find winamp window';
procedure TJvWinampApi.ClearPlaylist;
begin
RefreshAndCheckHandle;
SendMessage(WinampHandle, WM_WA_IPC, 0, IPC_DELETE);
end;
function TJvWinampApi.GetBitRate: Integer;
begin
if WinampPresent then
Result := SendMessage(WinampHandle, WM_WA_IPC, 1, IPC_GETINFO)
else
Result := 0;
end;
function TJvWinampApi.GetChannels: Integer;
begin
if WinampPresent then
Result := SendMessage(WinampHandle, WM_WA_IPC, 2, IPC_GETINFO)
else
Result := 0;
end;
function TJvWinampApi.GetSongLength: TTime;
var
I: Longint;
TimeStamp: TTimeStamp;
begin
TimeStamp.Time := 0;
TimeStamp.Date := 1;
if WinampPresent then
begin
I := SendMessage(WinampHandle, WM_WA_IPC, 1, IPC_GETOUTPUTTIME);
if I <> -1 then
TimeStamp.Time := I * 1000;
end;
Result := TimeStampToDateTime(TimeStamp);
end;
function TJvWinampApi.GetMajorVersion: Integer;
var
I: Longint;
begin
if WinampPresent then
begin
I := SendMessage(WinampHandle, WM_WA_IPC, 0, IPC_GETVERSION);
Result := (I and $F000) div $1000;
end
else
Result := -1;
end;
function TJvWinampApi.GetMinorVersion: Integer;
var
I: Longint;
begin
if WinampPresent then
begin
I := SendMessage(WinampHandle, WM_WA_IPC, 0, IPC_GETVERSION);
if WinampMajorVersion = 1 then
Result := ((I and $0F00) div (16 * 16 * 16)) * 10 + (I and $000F)
else
Result := StrToInt(IntToHex(((I div 16) and $00FF), 2));
end
else
Result := -1;
end;
function TJvWinampApi.GetPlaylistPos: Integer;
begin
if WinampPresent then
Result := SendMessage(WinampHandle, WM_WA_IPC, 0, IPC_GETLISTPOS)
else
Result := -1;
end;
function TJvWinampApi.GetSampleRate: Integer;
begin
if WinampPresent then
Result := SendMessage(WinampHandle, WM_WA_IPC, 0, IPC_GETINFO)
else
Result := 0;
end;
function TJvWinampApi.GetSongPosition: TTime;
var
I: Longint;
TimeStamp: TTimeStamp;
begin
TimeStamp.Time := 0;
TimeStamp.Date := 1;
if WinampPresent then
begin
I := SendMessage(WinampHandle, WM_WA_IPC, 0, IPC_GETOUTPUTTIME);
if I <> -1 then
TimeStamp.Time := I;
end;
Result := TimeStampToDateTime(TimeStamp);
end;
function TJvWinampApi.GetWinampPresent: Boolean;
begin
RefreshHandle;
Result := FWinampHandle <> 0;
end;
function TJvWinampApi.GetWinampStatus: TWStatus;
var
I: Longint;
begin
if WinampPresent then
begin
I := SendMessage(WinampHandle, WM_WA_IPC, 0, IPC_ISPLAYING);
case I of
0:
Result := wsStopped;
1:
Result := wsPlaying;
3:
Result := wsPaused;
else
Result := wsNotAvailable;
end;
end
else
Result := wsNotAvailable;
end;
procedure TJvWinampApi.Play;
begin
RefreshAndCheckHandle;
SendMessage(WinampHandle, WM_WA_IPC, 0, IPC_STARTPLAY)
end;
procedure TJvWinampApi.SavePlaylist;
begin
RefreshAndCheckHandle;
if CheckWinampHigher(1, 66) then
SendMessage(WinampHandle, WM_WA_IPC, 0, IPC_WRITEPLAYLIST);
end;
procedure TJvWinampApi.SetPlaylistPos(const Value: Integer);
begin
if WinampPresent and CheckWinampHigher(2, 0) then
SendMessage(WinampHandle, WM_WA_IPC, Value, IPC_SETPLAYLISTPOS);
end;
procedure TJvWinampApi.SetPanning(Value: Byte);
begin
RefreshAndCheckHandle;
if CheckWinampHigher(2, 0) then
SendMessage(WinampHandle, WM_WA_IPC, Value, IPC_SETPANNING);
end;
procedure TJvWinampApi.SetSongPosition(const Value: TTime);
var
TimeStamp: TTimeStamp;
begin
TimeStamp := DateTimeToTimeStamp(Value);
if WinampPresent and CheckWinampHigher(1, 60) then
SendMessage(WinampHandle, WM_WA_IPC, TimeStamp.Time, IPC_JUMPTOTIME);
end;
procedure TJvWinampApi.SetVolume(Value: Byte);
begin
RefreshAndCheckHandle;
if CheckWinampHigher(2, 0) then
SendMessage(WinampHandle, WM_WA_IPC, Value, IPC_SETVOLUME);
end;
function TJvWinampApi.CheckWinampHigher(Major, Minor: Integer): Boolean;
begin
Result := (WinampMajorVersion > Major) or
((WinampMajorVersion = Major) and (WinampMinorVersion >= Minor));
if not Result and not (csDesigning in ComponentState) then
raise EWinampError.Create(Format(RC_WinampFormat, [Major, Minor]));
end;
function TJvWinampApi.GetListLength: Integer;
begin
if WinampPresent and CheckWinampHigher(2, 0) then
Result := SendMessage(WinampHandle, WM_WA_IPC, 0, IPC_GETLISTLENGTH)
else
Result := 0;
end;
procedure TJvWinampApi.ShowAbout;
begin
SendCommand(WINAMP_HELP_ABOUT);
end;
procedure TJvWinampApi.ShowOptions;
begin
SendCommand(WINAMP_OPTIONS_PREFS);
end;
procedure TJvWinampApi.OpenFiles;
begin
SendCommand(WINAMP_FILE_PLAY);
end;
procedure TJvWinampApi.ToggleAlwaysOnTop;
begin
SendCommand(WINAMP_OPTIONS_AOT);
end;
procedure TJvWinampApi.ToggleEqualizer;
begin
SendCommand(WINAMP_OPTIONS_EQ);
end;
procedure TJvWinampApi.TogglePlaylist;
begin
SendCommand(WINAMP_OPTIONS_PLEDIT);
end;
procedure TJvWinampApi.OpenFile(FileName: string);
var
CopyData: TCopyDataStruct;
Data: array [0..255] of Char;
begin
RefreshAndCheckHandle;
CopyData.dwData := IPC_PLAYFILE;
FillChar(Data, SizeOf(Data), 0); // (ahuser) otherwise WinAmp will get strange symbols
StrPCopy(Data, FileName);
CopyData.lpData := @Data;
CopyData.cbData := Length(FileName);
SendMessage(WinampHandle, WM_COPYDATA, 0, Longint(@CopyData))
end;
procedure TJvWinampApi.SetDirectory(Directory: string);
var
CopyData: TCopyDataStruct;
Data: array [0..255] of Char;
begin
RefreshAndCheckHandle;
CopyData.dwData := IPC_CHDIR;
StrPCopy(Data, Directory);
CopyData.lpData := @Data;
CopyData.cbData := Length(Directory);
SendMessage(WinampHandle, WM_COPYDATA, 0, Longint(@CopyData))
end;
procedure TJvWinampApi.VolumeDec;
begin
SendCommand(WINAMP_VOLUMEDOWN);
end;
procedure TJvWinampApi.VolumeInc;
begin
SendCommand(WINAMP_VOLUMEUP);
end;
procedure TJvWinampApi.FastForward;
begin
SendCommand(WINAMP_FFWD5S);
end;
procedure TJvWinampApi.FastRewind;
begin
SendCommand(WINAMP_REW5S);
end;
procedure TJvWinampApi.OpenLocation;
begin
SendCommand(WINAMP_BUTTON2_CTRL);
end;
procedure TJvWinampApi.NextTrack;
begin
SendCommand(WINAMP_BUTTON5);
end;
procedure TJvWinampApi.PreviousTrack;
begin
SendCommand(WINAMP_BUTTON1);
end;
procedure TJvWinampApi.Pause;
begin
SendCommand(WINAMP_BUTTON3);
end;
procedure TJvWinampApi.Stop;
begin
SendCommand(WINAMP_BUTTON4);
end;
procedure TJvWinampApi.EndOfList;
begin
SendCommand(WINAMP_BUTTON5_CTRL);
end;
procedure TJvWinampApi.StartOfList;
begin
SendCommand(WINAMP_BUTTON1_CTRL);
end;
procedure TJvWinampApi.StopWithFadeout;
begin
SendCommand(WINAMP_BUTTON4_SHIFT);
end;
function TJvWinampApi.GetEqualizer: TWinampEqualizer;
var
I: Integer;
begin
RefreshAndCheckHandle;
if CheckWinampHigher(2, 5) then
begin
for I := 0 to 9 do
Result.Bands[I] := SendMessage(WinampHandle, WM_WA_IPC, I, IPC_GETEQDATA);
Result.PreAmp := SendMessage(WinampHandle, WM_WA_IPC, 10, IPC_GETEQDATA);
Result.Enabled := SendMessage(WinampHandle, WM_WA_IPC, 11, IPC_GETEQDATA) <> 0;
Result.AutoLoad := SendMessage(WinampHandle, WM_WA_IPC, 12, IPC_GETEQDATA) <> 0;
end;
end;
procedure TJvWinampApi.SetEqualizer(const Value: TWinampEqualizer);
const
CBool: array [Boolean] of Integer = (0, 1);
var
I: Integer;
begin
RefreshAndCheckHandle;
if not CheckWinampHigher(2, 5) then
Exit;
for I := 0 to 9 do
begin
SendMessage(WinampHandle, WM_WA_IPC, I, IPC_GETEQDATA);
SendMessage(WinampHandle, WM_WA_IPC, Value.Bands[I], IPC_SETEQDATA);
end;
SendMessage(WinampHandle, WM_WA_IPC, 10, IPC_GETEQDATA);
SendMessage(WinampHandle, WM_WA_IPC, Value.PreAmp, IPC_SETEQDATA);
SendMessage(WinampHandle, WM_WA_IPC, 11, IPC_GETEQDATA);
SendMessage(WinampHandle, WM_WA_IPC, CBool[Value.Enabled], IPC_SETEQDATA);
SendMessage(WinampHandle, WM_WA_IPC, 12, IPC_GETEQDATA);
SendMessage(WinampHandle, WM_WA_IPC, CBool[Value.Enabled], IPC_SETEQDATA);
end;
procedure TJvWinampApi.SendCommand(Value: Integer);
begin
RefreshAndCheckHandle;
SendMessage(WinampHandle, WM_COMMAND, Value, 0)
end;
function TJvWinampApi.GetWinampHandle: THandle;
begin
if FWinampHandle = 0 then
RefreshAndCheckHandle;
Result := FWinampHandle;
end;
procedure TJvWinampApi.RefreshHandle;
begin
FWinampHandle := FindWindow(PChar(RC_WinampWindow), nil);
end;
procedure TJvWinampApi.CheckHandle;
begin
if FWinampHandle = 0 then
raise EWinampError.Create(RC_ErrorFinding);
end;
procedure TJvWinampApi.RefreshAndCheckHandle;
begin
RefreshHandle;
CheckHandle;
end;
procedure TJvWinampApi.SetPlayOptions(const Value: TJvPlayOptions);
const
CBool: array [Boolean] of Integer = (0, 1);
begin
CheckWinampHigher(2, 40);
SendMessage(WinampHandle, WM_WA_IPC, CBool[poShuffle in Value], IPC_SET_SHUFFLE);
SendMessage(WinampHandle, WM_WA_IPC, CBool[poRepeat in Value], IPC_SET_REPEAT);
end;
function TJvWinampApi.GetPlayOptions: TJvPlayOptions;
begin
CheckWinampHigher(2, 40);
Result := [];
if SendMessage(WinampHandle, WM_WA_IPC, 0, IPC_GET_SHUFFLE) = 1 then
Include(Result, poShuffle);
if SendMessage(WinampHandle, WM_WA_IPC, 0, IPC_GET_REPEAT) = 1 then
Include(Result, poRepeat);
end;
end.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -