📄 frontend.cpp
字号:
/********************************************************************
Created : 2001/07/19 10:03:52
FileName : frontend.cpp
Author : xhy
Purpose :
*********************************************************************/
// #ifndef _WAFE_H_
// #define _WAFE_H_
/*
** Winamp frontend/plug-in control API documentation v1.1.
** By Justin Frankel. Updates by Christophe Thibault.
** Copyright (C) 1997-2000, Nullsoft Inc.
** Last updated: JUL.12.2000.
**
** Introduction
** -----------------------
** This file describes a means to easily communicate to Winamp
** via the classic Win32 Message API.
**
** These definitions/code assume C/C++. Porting to VB/Delphi shouldn't
** be too hard.
**
** 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:
**
** HWND hwnd_winamp = FindWindow("Winamp v1.x",NULL);
**
** (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.
*/
// #define WM_WA_IPC WM_USER
/**************************************************************************/
#include "windows.h"
#include "frontend.h"
#define _IsCharEqual(ch1, ch2) ( (ch | ('z' - 'Z')) != (ch2 | ('z' - 'Z') ))
// #define WA_ERR_TIMEOUT
// #define WA_ERR_SUCCESS
// #define WA_ERR_FAILED
// PURPOSE:
// Get current playing song
// COMMENT:
// we use GetWindowText to get Winamp window title,
// then analyse the title,
// WARRNING:
// 在取得标题时可能正在卷动标题
// exp. mp[PAUSED] *** 1. 追梦人 - Wina
// ----> *** 1. 追梦人 - Winamp[PAUSED]
BOOL WAGetPlayingSongByWndTitle(HWND hwndWinamp, TCHAR szSong[])
{
/*
char this_title[2048],*p;
GetWindowText(hwndWinamp,this_title,sizeof(this_title));
p = this_title+strlen(this_title)-8;
while (p >= this_title)
{
if (!strnicmp(p,"- Winamp",8)) break;
p--;
}
if (p >= this_title) p--;
while (p >= this_title && *p == ' ') p--;
*++p=0;*/
int len;
TCHAR szTitle[MAX_PATH];
len = GetWindowText(hwndWinamp, szTitle, MAX_PATH);
if (len < 15)
return FALSE;
int i, n;
int nEndPos;
// search to *** 1.
for (n = 0; n < len + 3; n ++)
{
for (i = n; i < n + 3; i ++)
{
if (szTitle[i % len] != '*')
break;
}
if (i == n + 3) // ok find
break;
}
nEndPos = n;
if (n == len + 3) // winamp does not scroll title
{
n = 0;
nEndPos = 0;
}
else
n = n + 3;
// seek to '.'
for (i = n; i < n + 8; i ++)
{
if (szTitle[i % len] == '.')
break;
}
if (i == n + 8)
return FALSE;
n = i + 1;
if (szTitle[n % len] == ' ')
n++;
// ok copy song title
if (nEndPos < n)
nEndPos += len;
i = 0;
while (n < nEndPos)
{
szSong[i] = szTitle[n % len];
i ++;
n ++;
}
szSong[i] = '\0';
// remove ' - Winamp'
// exp. 追梦人 - Winamp[Stopped]
// OUT: 追梦人
len = strlen(szSong);
len --;
while (len >= 0 && szSong[len] != '-')
len --;
if (len <= 0) // include ==
return FALSE;
szSong[len - 1] = '\0';
return TRUE;
}
char *strcpy_safe(char *strDestination, int nLenMax, const char *strSource);
BOOL WAGetPlayingSong(HWND hwndWinamp, TCHAR szSong[])
{
DWORD dwPos = 0, dwLength = 0;
//
// 通过从列表中取得歌曲的方式
if (WAGetListLength(hwndWinamp, dwLength) && WAGetListPos(hwndWinamp, dwPos))
{
if (dwPos < dwLength)
{
LPTSTR szTitle = NULL;
if (WAGetPlayListTitle(hwndWinamp, dwPos, szTitle))
{
if (szTitle)
{
strcpy_safe(szSong, 256, szTitle);
return TRUE;
}
}
}
}
//
// 如列表中没有歌曲,则使用标题栏的方式取得歌曲标题
return WAGetPlayingSongByWndTitle(hwndWinamp, szSong);
}
// #define IPC_GETVERSION 0
BOOL WAGetVersion(HWND hwndWinamp, DWORD &dwVersion)
{
return SendMessageTimeout(hwndWinamp, WM_WA_IPC, 0, IPC_GETVERSION,
SMTO_ABORTIFHUNG | SMTO_NORMAL, SM_WINAMP_TIMEOUT, &dwVersion);
}
/*
** int 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:
** int result=SendMessage(hwnd_winamp,WM_WA_IPC,command_data,command);
** (for the version check, command_data is 0).
*/
// #define IPC_DELETE 101
BOOL WAClearPlayList(HWND hwndWinamp)
{
DWORD dwResult;
return SendMessageTimeout(hwndWinamp, WM_WA_IPC, 0, IPC_DELETE,
SMTO_ABORTIFHUNG | SMTO_NORMAL, SM_WINAMP_TIMEOUT, &dwResult);
}
/*
** SendMessage(hwnd_winamp,WM_WA_IPC,0,IPC_DELETE);
**
** You can use IPC_DELETE to clear Winamp's internal playlist.
*/
// 发送Prev消息
BOOL WAPrev(HWND hwndWinamp)
{
DWORD dwResult;
return SendMessageTimeout(hwndWinamp, WM_COMMAND, WINAMP_BUTTON1, 0,
SMTO_ABORTIFHUNG | SMTO_NORMAL, SM_WINAMP_TIMEOUT, &dwResult);
}
// 发送暂停/继续消息
BOOL WAPlayPause(HWND hwndWinamp)
{
DWORD dwResult;
return SendMessageTimeout(hwndWinamp, WM_COMMAND, WINAMP_BUTTON3, 0,
SMTO_ABORTIFHUNG | SMTO_NORMAL, SM_WINAMP_TIMEOUT, &dwResult);
}
// 发送停止消息
BOOL WAStop(HWND hwndWinamp)
{
DWORD dwResult;
return SendMessageTimeout(hwndWinamp, WM_COMMAND, WINAMP_BUTTON4, 0,
SMTO_ABORTIFHUNG | SMTO_NORMAL, SM_WINAMP_TIMEOUT, &dwResult);
}
// 发送Prev消息
BOOL WANext(HWND hwndWinamp)
{
DWORD dwResult;
return SendMessageTimeout(hwndWinamp, WM_COMMAND, WINAMP_BUTTON5, 0,
SMTO_ABORTIFHUNG | SMTO_NORMAL, SM_WINAMP_TIMEOUT, &dwResult);
}
// #define IPC_STARTPLAY 102
BOOL WAPlay(HWND hwndWinamp)
{
DWORD dwResult;
return SendMessageTimeout(hwndWinamp, WM_COMMAND, WINAMP_BUTTON2, 0,
SMTO_ABORTIFHUNG | SMTO_NORMAL, SM_WINAMP_TIMEOUT, &dwResult);
// DWORD dwResult;
// return SendMessageTimeout(hwndWinamp, WM_WA_IPC, 0, IPC_STARTPLAY,
// SMTO_ABORTIFHUNG | SMTO_NORMAL, SM_WINAMP_TIMEOUT, &dwResult);
}
/*
** SendMessage(hwnd_winamp,WM_WA_IPC,0,IPC_STARTPLAY);
**
** Using IPC_STARTPLAY is like hitting 'Play' in Winamp, mostly.
*/
// #define IPC_ISPLAYING 104
BOOL WAIsPlaying(HWND hwndWinamp, int &nPlayState)
{
return SendMessageTimeout(hwndWinamp, WM_WA_IPC, 0, IPC_ISPLAYING,
SMTO_ABORTIFHUNG | SMTO_NORMAL, SM_WINAMP_TIMEOUT, (LPDWORD)&nPlayState);
}
/*
** int res = 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.
*/
// #define IPC_GETOUTPUTTIME 105
BOOL WAGetCurSongPos(HWND hwndWinamp, DWORD &dwCurPos)
{
// return (int)SendMessage(hwndWinamp, WM_WA_IPC, 0, IPC_GETOUTPUTTIME);
return SendMessageTimeout(hwndWinamp, WM_WA_IPC, 0, IPC_GETOUTPUTTIME,
SMTO_ABORTIFHUNG | SMTO_NORMAL, SM_WINAMP_TIMEOUT, &dwCurPos);
}
BOOL WAGetCurSongLength(HWND hwndWinamp, DWORD &dwLength)
{
return SendMessageTimeout(hwndWinamp, WM_WA_IPC, 1, IPC_GETOUTPUTTIME,
SMTO_ABORTIFHUNG | SMTO_NORMAL, SM_WINAMP_TIMEOUT, &dwLength);
}
/*
** int res = 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.
*/
// #define IPC_JUMPTOTIME 106
BOOL WAJumpToTime(HWND hwndWinamp, DWORD msPos, int &nResult)
{
return SendMessageTimeout(hwndWinamp, WM_WA_IPC, msPos, IPC_JUMPTOTIME,
SMTO_ABORTIFHUNG | SMTO_NORMAL, SM_WINAMP_TIMEOUT, (LPDWORD)&nResult);
}
/* (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
*/
// #define IPC_WRITEPLAYLIST 120
BOOL WAWritePlayList(HWND hwndWinamp)
{
DWORD dwResult;
return SendMessageTimeout(hwndWinamp, WM_WA_IPC, 0, IPC_WRITEPLAYLIST,
SMTO_ABORTIFHUNG | SMTO_NORMAL, SM_WINAMP_TIMEOUT, &dwResult);
}
/* (requires Winamp 1.666+)
** SendMessage(hwnd_winamp,WM_WA_IPC,0,IPC_WRITEPLAYLIST);
**
** IPC_WRITEPLAYLIST writes the current playlist to <winampdir>\\Winamp.m3u,
** 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)
*/
// #define IPC_SETPLAYLISTPOS 121
BOOL WASetPlayListPos(HWND hwndWinamp, int position)
{
DWORD dwResult;
return SendMessageTimeout(hwndWinamp, WM_WA_IPC, position, IPC_SETPLAYLISTPOS,
SMTO_ABORTIFHUNG | SMTO_NORMAL, SM_WINAMP_TIMEOUT, &dwResult);
}
/* (requires Winamp 2.0+)
** SendMessage(hwnd_winamp,WM_WA_IPC,position,IPC_SETPLAYLISTPOS)
**
** IPC_SETPLAYLISTPOS sets the playlsit position to 'position'.
*/
// #define IPC_SETVOLUME 122
BOOL WASetVolume(HWND hwndWinamp, int volume)
{
DWORD dwResult;
return SendMessageTimeout(hwndWinamp, WM_WA_IPC, volume, IPC_SETVOLUME,
SMTO_ABORTIFHUNG | SMTO_NORMAL, SM_WINAMP_TIMEOUT, &dwResult);
}
/* (requires Winamp 2.0+)
** SendMessage(hwnd_winamp,WM_WA_IPC,volume,IPC_SETVOLUME);
**
** IPC_SETVOLUME sets the volume of Winamp (from 0-255).
*/
// #define IPC_SETPANNING 123
BOOL WASetPanning(HWND hwndWinamp, int panning)
{
DWORD dwResult;
return SendMessageTimeout(hwndWinamp, WM_WA_IPC, panning, IPC_SETPANNING,
SMTO_ABORTIFHUNG | SMTO_NORMAL, SM_WINAMP_TIMEOUT, &dwResult);
}
/* (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)).
*/
// #define IPC_GETLISTLENGTH 124
BOOL WAGetListLength(HWND hwndWinamp, DWORD &dwLength)
{
return SendMessageTimeout(hwndWinamp, WM_WA_IPC, 0, IPC_GETLISTLENGTH,
SMTO_ABORTIFHUNG | SMTO_NORMAL, SM_WINAMP_TIMEOUT, &dwLength);
}
/* (requires Winamp 2.0+)
** int length = SendMessage(hwnd_winamp,WM_WA_IPC,0,IPC_GETLISTLENGTH);
**
** IPC_GETLISTLENGTH returns the length of the current playlist, in
** tracks.
*/
// #define IPC_SETSKIN 200
BOOL WASetSkin(HWND hwndWinamp, LPTSTR szSkin)
{
DWORD dwResult;
return SendMessageTimeout(hwndWinamp, WM_WA_IPC, (WPARAM)szSkin, IPC_SETSKIN,
SMTO_ABORTIFHUNG | SMTO_NORMAL, SM_WINAMP_TIMEOUT, &dwResult);
}
/* (requires Winamp 2.04+, only usable from plug-ins (not external apps))
** SendMessage(hwnd_winamp,WM_WA_IPC,(WPARAM)"skinname",IPC_SETSKIN);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -