当前位置:文档之家› 音乐播放器源码

音乐播放器源码


/*
* 音乐播放器
* 本程序基于EGE(Easy Graphics Engine)13.03 开发
*功能:
上一首、下一首、暂停、播放、临时播放(可设为默认播放器)、浏览电脑上的歌曲(MP3、wav、amr)
播放进度调节、音量调节、歌曲列表、路径列表、列表上右键菜单、
添加移除歌曲或路径、更新路径、播放状态保存、精灵、
快捷键(ctrl+left、ctrl+right、ctrl+up、ctrl+down、ctrl+M)
*修复恢复列表播放时的歌曲不匹问题
*/

#include //包涵EGE图形库
#include
#include
#include
#include

#define PLAY_FONT "宋体"
#define MAXSIZE 1000 //列表最多允许有MAXSIZE首歌
#define MAXFOLDER 500 //最多能允许从MAXFOLDER个路劲读取歌曲
/*
*用于记录每首歌的名字及路径的线性表
*/
typedef struct LIST{
char name[MAXSIZE+1][128]; //歌曲名称
char folder[MAXSIZE+1][256]; //文件路径
int length;
int lastLength;
int frlength;
}LIST;

/*
*用于记录播放器播放歌曲的所有路径的线性表
*/
typedef struct _folderlist{
char folder[MAXFOLDER][256];//路径长度最长为255个字符,超过长度出错
int length;
}FOLDER;

/*
*用于记录播放器部分功状态的结构体,成员值为1表示处于该成员表示的状态
*/
typedef struct _playstate{
int music_play; //值为1表示歌曲正在播放,值为0表示歌曲暂停或停止
int music_pause; //暂态
int music_stop;
int music_length; //当前歌曲时长,以毫秒(ms)为单位
int music_pos; //当前播放个曲播放到的位置,以毫秒(ms)为单位
float music_vol; //当前要设置的声音大小
float music_last_vol; //当前实际声音大小
int music_id; //当前播放的歌曲编号(从0到歌曲曲总数减1)
int last_music_id; //上一次列表里的播放编号
int music_open; //记录当前编号的歌曲是否打开,值为1打开,值为0未打开(系统还没对该文件打开或打开失败)
int prompt[10]; //提示编号
int ptLength;
int addfolder; //是否打开文件浏览添加功能
int musiclist; //是否打开歌曲列表
int playway; //播放方式
int mute; //静音
int wondowsState; //标记窗口最大化或者最小化
}PSTATE;

/*
*记录界面上的按键状态,除鼠标相关外成员值为1表示鼠标放在对应按键上,成员值为2表示鼠标左键点击对应按键,并激发对应功能
*/
typedef struct _key{
int mlist; //列表按钮
int addfr; //添加播放文件的路径按钮
int addThis; //用于右键功能触发添加当前选中的路径或歌曲的功能
int set; //设置按钮
int playway; //设置播放方式按钮
int play; //播放按钮
int pause; //暂停按钮
int stop; //停止按钮
int sys; //上一首按钮
int xys; //下一首按钮
int volbar; //鼠标放

在声音调节条上的位置
int playbar; //鼠标放在播放进度条上的位置
int mleft; //鼠标左键被按下一次(值为1时)
int mright; //鼠标右键被按下一次(值为1时)
int mleftpress; //鼠标左键被按着(值为1时)
int mrightpress;//鼠标右键被按着(值为1时)
int mute; //静音键
int mmove; //鼠标箭头移动(值为1时)
int enter;
int pressEnter;
int pressControl;
int pressLeft;
int pressRight;
int pressUp;
int pressDown;
}KEY;

enum _play_function{STOP,PLAY,PAUSE,SYS,XYS};//枚举(停止,播放,暂停,上一首,下一首)
enum _play_way{LIST_SEQUENTIAL, LIST_RANDOM, SINGLE_CYCLE, LIST_CYCLE};//{顺序播放,随机播放,单曲循环,列表循环}

/*定义全局变量*/
LIST musiclist; //存放歌曲列表
FOLDER folderlist; //存放文件路劲
FOLDER folder; //存放当前路劲的文件夹
char sysOpName[256] = {0};
LIST file; //https://www.doczj.com/doc/1915032836.html, //存放当前路径的歌曲名,file.folder存放已打开的每一级路径
HWND hwnd; //存放窗口句柄
MUSIC music; //存放当前播放歌曲
PSTATE pstate = {0}; //定义并初始化存放播放器部分状态的混合类型变量
PSTATE lastSong = {0};
KEY key = {0}; //定义并初始化存放按键状态的混合类型变量
mouse_msg msg = {0}; //定义并初始化鼠标变量
int function = -1, SCh,SCw; //存放要执行的和播放功能有关的功能编号,屏幕分辨率

void init_player(); //初始化播放器(检查列表存档文件是否存在,存在则载入数据,否则从默认路径查找支持类型的歌曲,并列表写入列表文件)
FOLDER init_folder();
void draw_folderIcon(int x, int y, int selected); //绘制文件夹图形
void draw_addfolderIcon(); //绘制没有歌曲时显示的大文件图标
void draw_fileIcon(int x, int y, int selected); //绘制文件图标
void AddSignIcon(int x, int y, int selected); //画添加图标
void drawComputerIcon(int x, int y); //绘制我的电脑的图标
void play(); //播放
void pause(); //暂停
void stop(); //停止
void sys(); //上一首
void xys(); //下一首
void setvol(); //设置音量
void ReListPlay(); //临时播放结束时恢复列表播放
void change_play_music();
void show_play_way();
void set_play_way();
void pset(); //设置
void SystemOpen(int argc, char *argv[]); //windows资源管理器调用此程序打开歌曲时使用
void set_play_function(); //设置要执行的功能(停止,播放,暂停,上一首,下一首)
void run_play_function(); //执行(停止,播放,暂停,上一首,下一首)中一种功能和音量设置功能
void run(int argc, char *argv[]); //功能组合(总循环)
void gui_msg(); //绘制主界面图形界面
void text_msg(); //显示部分文字
void GetFileList(char route[], FOLDER *folder, LIST *file); //获取指定路径的子目录及支持的音频文件

列表
void show_music_list(); //显示播放列表
void show_file_list(FOLDER, LIST *, char *, int showfolder, int first); //显示浏览路径里的文件夹及支持的音频文件
void addfolder(); //添加播放路径
int add_route(char *route);
void back(LIST *file, char *route); //放回上一级目录
int alreadyAdd(char *str); //检测路径是否添加过
int noMusicToAdd(); //记录的路径没有歌曲时执行该功能,提示添加路径
int saveFolder(); //保存添加的路径
int saveList(); //保存歌曲列表
void show_driver(int type, int y); //显示驱动器类型
void List_delete(int i); //移除一首歌****************当前未调用
void prompt(); //各种提示
void ele_key(); //检测部分按钮是否被鼠标选中
int ele_pos(int length); //显示歌曲列表时返回鼠标选中的歌曲列表位置
void mouse(); //检测鼠标状态
void init_key(); //复位按键状态
BOOL IsBeforAlreadyRun(int argc,char *argv[]);
int continue_add(int way); //way = 1 显示“再添加”,way = 2 显示“计算机”
int key_move_list(int s, int pos, int length); //通过上下键上下移动歌曲列表
int mouse_move_list(int s, int length); //通过鼠标滚轮或拖动条上下移动歌曲列表
void show_box(int pos, int length); //显示光标在当前鼠标选中的歌曲列表上
void DEL_A_List(int i, int way); //way = 1删除一个数据编号为i的歌曲列表,way = 2删除一个数据编号为i的以添加的播放路径
int mright_FN(int x, int y, int i, int way); //右键功能
void updataThisRoute(int i);
void AddASong(char *route);
void save_state();
void read_state();
void move_window();//移动窗体
void WindowMaxMin();//最小化窗口
void ShowMyMouse(); //系统鼠标被隐藏,使用实时绘制的鼠标(取反色)
void quit(); //关闭
void SetTransparent(HWND hwnd,UINT alpha); //半透明窗体


void main(int argc,char *argv[])
{
if(IsBeforAlreadyRun(argc, argv))
exit(0);
HDC screenDC = CreateDC("DISPLAY",NULL,NULL,NULL);
SCw = GetDeviceCaps(screenDC,HORZRES);// 屏幕宽
SCh = GetDeviceCaps(screenDC,VERTRES);// 屏幕高
setinitmode(1|16, (SCw-250)/2,30); //设置窗口显示位置及模式
initgraph(252,150); //初始化窗口
setcaption("简约音乐");
hwnd = FindWindow(NULL, "简约音乐"); //获取窗口句柄
// DragAcceptFiles(hwnd, false); //设置窗口不接收拖拽文件
HRGN hr = CreateRoundRectRgn(0,0,252,150,4,4);
SetWindowRgn(hwnd,hr,1);
SetTransparent(hwnd,215); //半透明窗口
SetCursorPos((SCw-180)/2,45); //设置启动程序时鼠标箭头位置
ShowWindow(hwnd, SW_SHOWMAXIMIZED); //使以后在最大化的时候不会把窗口从位置不为(0,0)移(0,0)
MoveWindow(hwnd, (SCw-250)/2,30, 252,150, 0);
showmouse(0); //隐藏鼠标
randomize(); //初始化随机种子
setbkcolor(EGERGB(40,120,180)); //设置背景颜色
setbkmode(TRANSPARENT);
setcolor(0); //设置

绘制文字和图形的颜色
setfont(16,0,PLAY_FONT); //设置字体大小和风格
init_player(); //初始化播放器
run(argc, argv); //运行播放器
}

void SetTransparent(HWND hwnd, UINT alpha)
{
typedef BOOL (FAR PASCAL*LAYERFUNC)(HWND,COLORREF,BYTE,DWORD);
LAYERFUNC SetLayer;
HMODULE hmod=LoadLibrary("user32.dll");
SetWindowLong(hwnd,GWL_EXSTYLE,GetWindowLong(hwnd,GWL_EXSTYLE)|0x80000L);
SetLayer=(LAYERFUNC)GetProcAddress(hmod, "SetLayeredWindowAttributes");
if(0 == alpha)
{
setbkcolor(BLACK);
SetLayer(hwnd, BLACK, 255, 0x3);
cleardevice();
}
else
SetLayer(hwnd, 0, alpha, 0x2);
FreeLibrary(hmod);
}

/*
BOOL IsBeforAlreadyRun(char *argv[])
{
//先用?CreateToolhelp32Snapshot?将当前系统的进程、线程、DLL、堆的信息保存到一个缓冲区,这就是一个系统快照。
//如果你只是对进程信息感兴趣,那么只要包含?TH32CS_SNAPPROCESS?标志即可。
BOOL flags = false;
HANDLE procSnap=CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);

if(procSnap==INVALID_HANDLE_VALUE)
{
MessageBox(hwnd, (LPCSTR)GetLastError(), TEXT("提示"),0);
return false;
}
PROCESSENTRY32 procEntry={0};
procEntry.dwSize=sizeof(PROCESSENTRY32);
//调用一次?Process32First?函数,从快照中获取第一个进程,然后重复调用?Process32Next,直到函数返回?FALSE?为止。
//遍历快照中进程列表,两个参数分别是快照句柄和一个?PROCESSENTRY32?结构。
BOOL bRet=Process32First(procSnap,&procEntry); //对进程快照

char *thisPmNmae,//指向存储当前程序的文件名的内存空间的字符指针
sum = 0;
int i = 0, pos = 0, len = strlen(argv[0]);
for(i = 0; i < len; i++)//在完整文件路径中定位文件名开始的位置 pos
{
if(argv[0][i] == '\\')
pos = i+1;
}

thisPmNmae = (char *)malloc(sizeof(char) * (len - pos + 2)); //根据当前程序的文件名长度向系统申请够用的内存空间
memset(thisPmNmae, 0, len - pos + 2);

for(i = pos; i < len; i++)
thisPmNmae[i - pos] = argv[0][i];

while(bRet) //遍历进程表查找出和当前程序名一样的进程有几个,如果超过一个则视为本程序已经执行
{
if(strcmp(procEntry.szExeFile, thisPmNmae) == 0)
sum++;
if(sum >= 2)
{
flags = true;
WPARAM wparam = 65;
SetWindowText(hwnd, "简约音乐2");
HWND hWnd = FindWindow(NULL,"简约音乐");
SetWindowText(hWnd, argv[1]);
break;
}
bRet=Process32Next(procSnap,&procEntry);
}
//在调用?Process32First()?之前,要将?PROCESSENTRY32?结构的?dwSize?成员设置成?sizeof(PROCESSENTRY32)。?
//然后再用?Process32First、Process32Next?来枚举进程。使用结束后要调用?CloseHandle?来释放保存的系统快照。
CloseHandle(procSnap);
if(thisPmNmae != NULL)
free(thisPmNmae);
return flags;
}
*/



BOOL IsBeforAlreadyRun(int argc,char *argv[])
{
BOOL flags = false;
HWND hWnd = Fin

dWindow(NULL, "简约音乐");
if(hWnd != 0)
{
if(argc > 1)
SetWindowText(hWnd, argv[1]);
else
SetWindowText(hWnd, "FLASH");
flags = true;
}
return flags;
}

void init_player()
{
FILE *fpa, *fpb;
static int first = 1;
int i,updata = 0,count = 0;
static char defaultFolder[2][128] = {"D:\\My music\\","C:\\Users\\Public\\Music\\"}; //默认播放歌曲的路径

/*检测D:My Music是否存在,如果不存在创建该文件夹,并设置为当前工作目录*/
if(_chdir("D:\\My music")!=0)
if(_mkdir("D:\\My music")==0)//创建文件夹
_chdir("D:\\My music");

if((fpa = fopen("folderlist.dat","rb"))!=NULL)/*判断存储播放路径的文件是否存在和正确,如不正确则设置updata值为1(标记要重新创建并初始化该文件)*/
{
fseek(fpa,0,2);
if(ftell(fpa)==sizeof(FOLDER))
{
fseek(fpa,0,0);
if(fread(&folderlist,sizeof(FOLDER),1,fpa)!=1 || folderlist.length <= 0) //读入添加过的播放路径
updata = 1;
}
else
updata = 1;
fclose(fpa);
}
else
updata = 1;


if(updata == 1)
{
/*删除,重新创建并初始化存储播放路径的文件*/
folderlist.length = 0;
for(; folderlist.length < 2; folderlist.length++) //添加默认路径到 已添加路径列表
strcpy(folderlist.folder[folderlist.length],defaultFolder[folderlist.length]);

_unlink("folderlist.dat");
if((fpa = fopen("folderlist.dat","wb"))!=NULL)
fwrite(&folderlist,sizeof(FOLDER),1,fpa);
fclose(fpa);
}

musiclist.length = 0;//设置线性表长度为0
updata = 0;
if((fpb = fopen("MyMusicList.dat","rb"))==NULL)/*判断存储播放列表的文件是否存在和正确,如不正确则设置updata值为1(标记要重新创建并初始化该文件)*/
{
updata = 1;
}
else
{
fseek(fpb,0,2);
if(ftell(fpb)==sizeof(LIST))
{
fseek(fpb, 0, 0);
if(fread(&musiclist,sizeof(LIST),1,fpb)!=1 || 0 >= musiclist.length)
updata = 1;//标记需要更新文件
}
else
{
updata = 1;
}
fclose(fpb);
}

if(updata == 1)
{
/*删除,重新创建并初始化存储播放列表的文件*/
for(i=0; iGetFileList(folderlist.folder[i], NULL, &musiclist); //从指定路径获得歌曲列表存入list线性表
_unlink("Mymusiclist.dat"); //删除列表文件
if((fpb = fopen("D:\\My music\\Mymusiclist.dat","wb"))!=NULL)
{
fwrite(&musiclist,sizeof(LIST),1,fpb); //把列表list线性表存入列表文件
fclose(fpb);
}
}
read_state();
}

void GetFileList(char *route, FOLDER *thisFolder, LIST *file)
{
char openroute[512], szFileName[512], form[5][6] = {"*.*", "*.mp3", "*.wav", "*.wma"};
int i = 0, j=0, type = 0;
WIN32_FIND_DATA findData;
HANDLE hFindFile;

strcpy(openroute, route);
if(openroute[strlen(openroute)-1] != '\\')
strcat(openroute, "\\");

for(i = 0; i < 4; i++)//循环搜索每种格式的歌曲(第一次获

得文件夹列表)
{
strcpy(szFileName, openroute);
strcat(szFileName, form[i]);//构建文件路径
hFindFile=::FindFirstFile(szFileName,&findData);//获得文件列表
if(0 == i && route[1] == ':' && strlen(route) == 3)
{
type = GetDriveType(route);
if(type != 3 && hFindFile == INVALID_HANDLE_VALUE)
{
(*file).frlength = 0;
route[0] = 0;
break;
}
}

if(hFindFile!=INVALID_HANDLE_VALUE)//判断hFindFile是否有效
{
do
{
if(findData.cFileName[0]=='.')//跳过“.”或“..”文件夹
continue;
if(0 == i && findData.dwFileAttributes&FILE_ATTRIBUTE_DIRECTORY)//从文件列表中提出文件夹
{
if(thisFolder != NULL && thisFolder->length < MAXFOLDER)
{
strcpy(thisFolder->folder[thisFolder->length], findData.cFileName);
thisFolder->length++;
if(thisFolder->length == MAXFOLDER)
{
pstate.prompt[pstate.ptLength++] = 10;
break;
}
}
}
else if(i != 0)
{
if(file != NULL && (*file).length < MAXSIZE)
{
if(thisFolder == NULL)
strcpy((*file).folder[(*file).length], openroute);
strcpy((*file).name[(*file).length], findData.cFileName);
(*file).length++;
if((*file).length == MAXSIZE)
{
pstate.prompt[pstate.ptLength++] = 10;
break;
}
}

}
}while(::FindNextFile(hFindFile,&findData));
}
}
}

void init_key()
{
//还原按键,等待重新检测按键是否被鼠标选中
key.mlist = 0;
key.addfr = 0;
key.set = 0;
key.playway = 0;
key.volbar = -1;
key.playbar = -1;
key.mute = 0;
key.play = 0;
key.pause = 0;
key.stop = 0;
key.sys = 0;
key.xys = 0;
key.mleft = 0;
key.mright = 0;
msg.wheel = 0;
key.mmove = 0;
}

void mouse()
{
/*EGE鼠标检测函数不能直接满足使用需求(比如不能检测鼠标按键是否一直按着,移动鼠标时按键值变为零,
is_move成员只能检测鼠标是否在没有按按键时是否移动过,不能检测鼠标是否停止移动),故写此函数,此函数放在void init_key()后使用才行*/
static int mx,my;
while (mousemsg()) //判断是否有鼠标消息
msg = getmouse(); //把鼠标消息放进msg结构体

if(msg.is_left() && msg.is_down())//满足条件则设标记标左键为按着状态
{
if(0 == key.mleftpress)
key.mleft = 1;
key.mleftpress = 1;
}
if(key.mleftpress == 1 && keystate(1) == 0)
key.mleftpress = 0;
if(msg.is_left() && msg.is_up())//满足条件则标记左键为没按着状态
key.mleftpress = 0;

/*右键、中键与左键同理*/
if(msg.is_right() && msg.is_down())
{
if(0 == key.mrightpress)
key.mright = 1;
key.mrightpress = 1;
}
if(msg.is_right() && msg.is_up())
key.mrightpress = 0;

if(mx != msg.x || my != msg.y)//判断鼠标是否移动
{
mx = msg.x;
my = msg.y;
key.mmove = 1;
}
}

void Sh

owMyMouse(int way)
{
color_t cr;
int col = 1, mx = msg.x, my = msg.y;

switch(way)
{
case 0:
break;
case 1:
for(int i = 0; i < 17; i++)
{
for(int j = 0; j < col; j++)
{
cr = getpixel(mx+j,my+i);
putpixel(mx+j, my+i, EGERGB(255-EGEGET_R(cr), 255-EGEGET_G(cr), 255-EGEGET_B(cr)));
}
if(i < 10)
col++;
if(i == 10)
col = 5;
if(i > 10)
col--;
}
break;
case 2:
for(int i = -8; i < 9; i++)
{
cr = getpixel(msg.x+i,msg.y);
putpixel(msg.x+i, msg.y, EGERGB(255-EGEGET_R(cr), 255-EGEGET_G(cr), 255-EGEGET_B(cr)));
cr = getpixel(msg.x,msg.y+i);
putpixel(msg.x, msg.y+i, EGERGB(255-EGEGET_R(cr), 255-EGEGET_G(cr), 255-EGEGET_B(cr)));
}
}
}

void ele_key()
{
if(msg.y>4 && msg.y<22)
{
if(msg.x>25 && msg.x<45) //列表按钮
key.mlist = 1;
else if(msg.x>48 && msg.x<68) //添加路径按钮
key.addfr = 1;
else if(msg.x>100 && msg.x<115) //设置功能按钮
key.set = 1;
}
if(msg.x>25 && msg.x<226 && msg.y>99 && msg.y<116) //播放进度条
key.playbar = msg.x-25;

if(msg.y>120 && msg.y<135)
{
if(msg.x>25 && msg.x<40)
key.stop = 1;
if(msg.x>55 && msg.x<70)
{
if(pstate.music_play == 1)
key.pause = 1;
else if(pstate.music_pause == 1)
key.play = 1;
}

if(msg.x > 143 && msg.x < 157) //静音
key.mute = 1;
else if(msg.x>=160 && msg.x<225) //调音量
{
key.volbar = msg.x - 163;
if(key.volbar<0)
key.volbar = 0;
else if(key.volbar>60)
key.volbar = 60;
}

if(msg.x>85 && msg.x<100) //上一曲
key.sys = 1;
else if(msg.x>115 && msg.x<130) //下一曲
key.xys = 1;
}

}

void play()
{
char openfile[512] = {0};
if(music.GetPlayStatus() == MUSIC_MODE_NOT_OPEN)
{
strcpy(openfile, musiclist.folder[pstate.music_id]);
if(openfile[strlen(openfile)-1] != '\\')
strcat(openfile, "\\");
strcat(openfile, https://www.doczj.com/doc/1915032836.html,[pstate.music_id]); //构建打开文件路径
music.OpenFile(openfile);
https://www.doczj.com/doc/1915032836.html,st_music_id = pstate.music_id;
}
if(music.GetPlayStatus() == MUSIC_MODE_NOT_OPEN)//判断是否成功打开歌曲
{
pstate.music_open = 0;
pstate.prompt[pstate.ptLength++] = 1;
pstate.music_length = 0;
pstate.music_pause = 1;
pstate.music_play = 0;
pstate.music_stop = 1;
}
else
{
pstate.music_open = 1;
pstate.music_length = music.GetLength(); //得到当前播放歌曲总时长,单位毫秒
if(!pstate.music_play)
music.SetVolume(0);
music.Play(pstate.music_pos); //播放打开的歌曲

if(music.GetPlayStatus() == MUSIC_MODE_PLAY)
{
if(!pstate.music_play)
pstate.music_last_vol = 0; //设置声音大小表示方块的位置在声音静音处(声音条的最左边)
pstate.music_play = 1;
pstate.music_pause = 0;
pstate.music_stop = 0;
}
}
save_state();
function = -1;
}

void pause()
{
if(pstate.music_play == 1)
{
music.Pause();
if(musi

c.GetPlayStatus() != MUSIC_MODE_PLAY) //暂停成功的话就把播放状态标记为pstate.music_pause = 1,暂停
{
pstate.music_play = 0;
pstate.music_pause = 1;
}
}
function = -1;
}

void stop()
{
function = -1;
if(pstate.music_open == 1)
{
music.Stop();
music.Close();
}
pstate.music_open = 0;
pstate.music_stop = 1;
pstate.music_play = 0;
pstate.music_pause = 1;
pstate.music_pos = 0;
}

void sys()
{
function = -1;
stop();
if(pstate.playway == LIST_RANDOM)
pstate.music_id = random(musiclist.length);
else
pstate.music_id--;
if(pstate.music_id < 0)
pstate.music_id = musiclist.length - 1;
function = PLAY;
}

void xys()
{
function = -1;
stop();
if(pstate.playway == LIST_RANDOM)
pstate.music_id = random(musiclist.length);
else
pstate.music_id++;
if(pstate.music_id >= musiclist.length)
pstate.music_id = 0;
function = PLAY;
}

void change_play_music()
{
int id;
if(pstate.music_pos == pstate.music_length && pstate.music_pos != 0) //按当前列表循环方式播放
{
if(pstate.music_id == MAXSIZE)
{
function = STOP;
return;
}

if(pstate.music_id >= musiclist.length)
pstate.music_id = 0;
else
{
switch(pstate.playway)
{
case LIST_SEQUENTIAL: //顺序播放
if(pstate.music_id < musiclist.length-1)
function = XYS;
else
function = STOP;
break;
case LIST_RANDOM: //随机播放
stop();
id = random(musiclist.length);
if(id == pstate.music_id && musiclist.length > 1)
pstate.music_id += (2*random(2)-1);
else
pstate.music_id = id;
function = PLAY;
break;
case SINGLE_CYCLE: //单曲循环
music.Play(0);
break;
case LIST_CYCLE: //列表循环
function = XYS;
}
}
}
}

void show_play_way()
{
int pta[] = {225,63, 223,61, 223,65};
int ptb[] = {225,69, 223,67, 223,71};
int ptc[] = {225,75, 223,73, 223,77};
int ptd[] = {221,63, 219,61, 219,65};
int pte[] = {208,75, 209,73, 209,77};
static int t;
if(key.playway == 1 && key.mleft == 1) //鼠标点击播放方式的图标
t = 45;
if(t%15 > 7 || (t == 0&& key.playway == 1)) //通过变量 t 控制播放方式显示两种颜色的哪一种,实现闪烁效果
{
setcolor(EGERGB(180,255,252));
setfillcolor(EGERGB(180,255,252));
}
else
{
setcolor(EGERGB(20,200,200));
setfillcolor(EGERGB(20,200,200));
}
switch(pstate.playway)
{
case LIST_SEQUENTIAL: //绘制顺序播放图标
line(201,63, 223,63);
line(201,69, 223,69);
line(201,75, 223,75);
fillpoly(3,pta);
fillpoly(3,ptb);
fillpoly(3,ptc);
break;
case LIST_RANDOM: //绘制随机播放图标
line(201,63, 210,63);
line(217,63, 223,63);
line(201,75, 210,75);
line(217,75, 223,75);
line(210,63, 217,76);
line(210,75, 217,62);
fillpoly(3,pta);
fillpoly(3,ptc);
break;
case SINGLE_CYCLE: //绘制单曲循环播放图标
line(203,63

, 220,63);
line(203,75, 217,75);
line(203,63, 203,75);
line(225,63, 225,76);
line(219,70, 219,76);
putpixel(218,70, EGERGB(20,200,200));
putpixel(224,75, EGERGB(20,200,200));
fillpoly(3,ptd);
break;
case LIST_CYCLE: //绘制列表循环播放图标
line(203,63, 220,63);
line(210,75, 225,75);
line(203,63, 203,75);
line(225,63, 225,76);
fillpoly(3,ptd);
fillpoly(3,pte);
}
if(t > 0)
t--;
}

void set_play_way()
{
static char str[10] = {0};
static int t;
if(musiclist.length == 0)
return;
if(msg.x > 200 && msg.x < 230 && msg.y > 60 && msg.y < 80)
{
key.playway = 1;
if(key.mleft == 1)
{
pstate.playway++;
if(pstate.playway > 3)
pstate.playway = 0;
}
if(key.mleft == 1 || str[0] == 0)
{
switch(pstate.playway)
{
case LIST_SEQUENTIAL:
strcpy(str, "顺序播放");
break;
case LIST_RANDOM:
strcpy(str, "随机播放");
break;
case SINGLE_CYCLE:
strcpy(str, "单曲循环");
break;
case LIST_CYCLE:
strcpy(str, "列表循环");
}
t = 100;
}
if(t < 0)
t = 100;
}
else if(t == 0)
t = -1;
if(t > 0)
{
t--;

setfillcolor(EGERGB(40,90,190));
bar(130,61, 196, 82);
setfillcolor(EGERGB(100,100,200));
bar(127,58, 193, 79);
setcolor(EGERGB(20,200,200));
xyprintf(128,60, "%s",str);
}
}

void setvol()
{
/*声音范围0.000000-1.000000,本程序去0-0.5*/
/*如果当前声音不等于要设置的音量,则让声音渐渐接近要设置的音量,直到相等*/
if(pstate.music_vol == 0)
pstate.mute = 1;
if(pstate.mute == 1)
{
if(pstate.music_last_vol != 0)
{
music.SetVolume(0);
pstate.music_last_vol = 0;
}
}
else if(pstate.music_vol != pstate.music_last_vol) //控制条音量是音量渐变,以变加速度方式渐变
{

if(pstate.music_vol<0)pstate.music_vol = 0;
if(pstate.music_vol>0.5)pstate.music_vol = 0.5;

if(pstate.music_vol - pstate.music_last_vol >= (pstate.music_last_vol * 0.02 + 0.001))
pstate.music_last_vol += (pstate.music_last_vol * 0.02 + 0.001);//音量渐加
else if(pstate.music_last_vol - pstate.music_vol >= (pstate.music_last_vol * 0.02 + 0.001))
pstate.music_last_vol -= (pstate.music_last_vol * 0.02 + 0.001);//音量渐减
else
pstate.music_last_vol = pstate.music_vol;
music.SetVolume(pstate.music_last_vol); //设置音量
}
}

void pset() //设置(待完成功能)
{
if(key.set != 2)
return;
setfont(16,0,PLAY_FONT);
}

void prompt() //提示功能
{
static int t = 0,fw = 16,loyal; //loyal为要显示几贞的时间
static char ptstrA[30] = {0},ptstrB[30] = {0};
int i;
if(pstate.ptLength > 4) //限制消息队列最多4个消息,后来者挤掉最先来的
{
for(i = 0; i < pstate.ptLength-1; i++)
pstate.prompt[i] = pstate.prompt[i+1];
pstate.ptLength--;
}

switch(pstate.prompt[0])
{
case 1:
fw = 20; //控制字体大小

loyal = 300;
strcpy(ptstrA, "打开歌曲失败!"); //把字符串"打开歌曲失败!"赋给ptstr
t=2;
break;
case 2:
fw = 18;
loyal = 500;
strcpy(ptstrA, "此路径已添加过!");
t = 2;
break;
case 3:
fw = 20;
loyal = 300;
strcpy(ptstrA, "保存失败!");
t = 2;
break;
case 4:
fw = 24;
loyal = 260;
strcpy(ptstrA, "添加成功!");
t = 2;
break;
case 5:
fw = 24;
loyal = 300;
strcpy(ptstrA, "移除成功!");
t = 2;
break;
case 6:
fw = 20;
loyal = 300;
strcpy(ptstrA, "恢复列表播放!");
t = 2;
break;
case 7:
fw = 24;
loyal = 300;
strcpy(ptstrA, "临时播放!");
t = 2;
break;
case 8:
fw = 20;
loyal = 300;
strcpy(ptstrA, "此歌曲已添加过了!");
t = 2;
break;
case 9:
fw = 16;
loyal = 500;
strcpy(ptstrA, "已达到最大歌曲数目");
strcpy(ptstrB, "不能再添加了!");
t = 2;
break;
case 10:
fw = 16;
loyal = 500;
strcpy(ptstrA, "项目个数太多");
strcpy(ptstrB, "未能装载所有!");
t = 2;
break;
}

pstate.prompt[0] = 0;

if(t>0 && t{
/*
先控制滤镜效果的透明度从全透明到不透明的渐变
在控制滤镜效果从不透明到全透明
通过上面两步实现淡入淡出的效果

(loyal+0.01) 防止除数为零
(loyal/2-t)/(loyal+0.01)的值[0,0.5)
510 * (loyal/2-t)/(loyal+0.01)的值[0,255)
t的值渐增,增量为不定由 loyal 的值和 t 本身的值决定,loyal为延时贞数
t的增量不定实现透明度渐变速度的控制,以便实现更好的视觉效果
(t < loyal/2)时510 * (loyal/2-t)/(loyal+0.01) + 1的值从255-1
(t > loyal/2)时510 * (loyal/2-t)/(loyal+0.01) + 1的值从1-255
*/
int alpha; //控制滤镜效果透明度的整形变量,值(0-255)
if(t < loyal/2)
alpha = 510 * (loyal/2-t)/(loyal+0.01) + 1;
else
alpha = 510 * (t-loyal/2)/(loyal+0.01) + 1;

//alpha值越接近255,透明度越高
imagefilter_blurring(NULL, 100,alpha, 35,50, 180,50); //在35,50, 180,50矩形区域进行滤镜效果
settextjustify(CENTER_TEXT, CENTER_TEXT); //设置字体以中间对齐方式对齐
setcolor(EGERGB(70, 150, 100));
setfont(fw,0, "楷体");
setcolor(EGERGB(60,130,180));
if(ptstrB[0] == 0) //提示只有一行
outtextxy(125,75, ptstrA);
else //提示有两行
{
outtextxy(125,65, ptstrA);
outtextxy(125,85, ptstrB);
}
settextjustify(LEFT_TEXT, TOP_TEXT); //设置字体以左对齐方式对齐,恢复默认对齐方式
setfont(16,0, "宋体");
int step = 2; //变量 t 的增量
if(loyal > 200 && (t < 100 || t > loyal - 100)) //根据情况改变控制透明度渐变速度的变量 t 的增量 step 的值
step = 3;
else if(loyal > 100 && (t < 50 || t > loyal - 50))
step = 4;

t+=step;
if(t >= loyal)//移动消息队列
{
t = 0;
ptstrA[

0] = ptstrB[0] = 0;
for(i = 0; i < pstate.ptLength-1; i++)
pstate.prompt[i] = pstate.prompt[i+1];
if(pstate.ptLength > 0)
pstate.ptLength--;
}
}
}


void set_function()
{
static int t, list;

if(GetAsyncKeyState(VK_CONTROL)) //Ctrl键按下则标记 key.pressControl = 1;
key.pressControl = 1;
else
key.pressControl = 0;

if(GetAsyncKeyState(VK_LEFT)) //Left键按下则标记 key.pressLeft = 1;
key.pressLeft = 1;
else
key.pressLeft = 0;

if(GetAsyncKeyState(VK_RIGHT)) //Right键按下则标记 key.pressRight = 1;
key.pressRight = 1;
else
key.pressRight = 0;

if(GetAsyncKeyState(VK_UP)) //Up键按下则标记 key.pressUp = 1;
key.pressUp = 1;
else
key.pressUp = 0;

if(GetAsyncKeyState(VK_DOWN)) //Down键按下则标记 key.pressDown = 1;
key.pressDown = 1;
else
key.pressDown = 0;

if(keystate('l') || keystate('L')) //Ctrl+L打开列表
{
if(!t)
{
key.mlist = 1;
pstate.musiclist = !pstate.musiclist;
}
t = 1;
}
else if(key.pressControl)
{

if(key.pressLeft) //Ctrl+left 上一首
{
if(!t)
{
key.sys = 1;
function = SYS;
t = 60;
}
t--;
}
else if(key.pressRight) //Ctrl+right 下一首
{
if(!t)
{
key.xys = 1;
function = XYS;
t = 60;
}
t--;
}
else
t = 0;
if(key.pressUp) //Ctrl+up 音量加
{
pstate.music_vol+=0.005;
pstate.mute = 0;
}
if(key.pressDown) //Ctrl+down 音量减
{
pstate.music_vol-=0.005;
pstate.mute = 0;
}

if(pstate.music_vol<0) //纠正可能超越范围的音量值
pstate.music_vol = 0;
if(pstate.music_vol > 0.5)
pstate.music_vol = 0.5;
}
else
t = 0;

/*当鼠标在音量条上,并按住鼠标左键时
根据音量条上的滑块位置计算出设置的音量值
音量条长度为60像素,volbar的值为[0,60]
(float)key.volbar/120 的值在[0, 0.5]内,对应音量调节的值的范围
*/
if(key.mleftpress == 1 && key.volbar >= 0)
{
pstate.music_vol = (float)key.volbar/120;
pstate.mute = 0;
}

if(key.mleft == 1) //按下左键时设置被鼠标选中的按钮值为2从而激活对应功能
{
if(key.stop == 1)
function = STOP;
if(key.sys == 1)
function = SYS;
if(key.xys == 1)
function = XYS;
if(key.pause == 1)
function = PAUSE;
if(key.play == 1)
function = PLAY;
if(key.mute == 1 && pstate.mute == 0) //设置为静音
pstate.mute = 1;
else if(key.mute == 1 && pstate.mute == 1) //解除静音状态
pstate.mute = 0;
if(key.mlist == 1) //打开歌曲列表,如果文件浏览功能打开则关闭文件浏览功能
{
pstate.musiclist = !pstate.musiclist;
pstate.addfolder = 0;
}
else if(key.addfr == 1) //打开歌文件浏览,如果歌曲列表打开则关闭歌曲列表
{
pstate.addfolder = !pstate.addfolder;
pstate.musiclist = 0;
}

if(key.playbar >= 0)
{
/

/歌曲进度调节,根据key.playbar的值,歌曲进度条长为200像素
pstate.music_pos = key.playbar/200.0 * pstate.music_length; //计算出歌曲应跳到的位置,单位:毫秒
pstate.music_play = 2;
function = PLAY;
}
}

if(keystate(13)) //确认键按下
key.pressEnter++;
else
key.pressEnter = 0;

if(key.pressEnter == 1) //确认键按下瞬间
key.enter = 1;
}

void ReListPlay() //临时播放结束时恢复列表播放
{
if(pstate.music_id == MAXSIZE && (function == STOP || function == SYS || function == XYS))
{
function = -1;
stop();
pstate.music_id = lastSong.music_id;
pstate.music_length = lastSong.music_length;
pstate.music_pos = lastSong.music_pos;
if(lastSong.music_play == 1)
function = PLAY;
pstate.prompt[pstate.ptLength++] = 6;
}
}

int DelayVolumeToZero()
{
/*进行停止、上一曲、下一曲操作时,
设置音量逐渐趋近零,并返回1告诉 run_play_function()函数中断它的执行
当音量为零时再进行操作
*/
static int step;
static float delay;
if(pstate.music_pos == pstate.music_length)
return 0;
if(delay == 0 && pstate.music_play && (function == STOP || function == SYS || function == XYS))
{
delay = pstate.music_last_vol/0.01;
step = pstate.music_pos / delay;
}

if(delay > 0)
{
delay--;
pstate.music_pos -= step;
pstate.music_last_vol -= 0.01;
if(pstate.music_last_vol >= 0)
music.SetVolume(pstate.music_last_vol);
else
delay = 0;
if(delay > 0)
return 1;
}
return 0;
}

void run_play_function()
{
static int s_x_function,
t;//t用于打开音乐失败时延时
static float volumeStep;
ReListPlay();
if(musiclist.length == 0 && pstate.music_id != MAXSIZE)
return;
if(musiclist.length != https://www.doczj.com/doc/1915032836.html,stLength)
{
save_state();
https://www.doczj.com/doc/1915032836.html,stLength = musiclist.length;
}
if(DelayVolumeToZero())
return;
switch(function)
{
case PLAY:
play();
if(pstate.music_id != MAXSIZE && musiclist.length > 0 && pstate.music_open == 0)
t = 80;
else
t = 0;
break;
case PAUSE:
pause();
break;
case STOP:
stop();
t = 0;
break;
case SYS:
s_x_function = SYS;
sys();
t = 0;
break;
case XYS:
s_x_function = XYS;
xys();
t = 0;
break;
}
if(t == 20)
{
if(s_x_function == SYS)
function = SYS;
else
function = XYS;
}
if(pstate.music_play == 1 && t == 0)
pstate.music_pos = music.GetPosition(); //得到当前播放歌曲播放到的时长,单位毫秒

if(t > 0)
t--;
setvol();
change_play_music();

}

void SystemOpen(int argc, char *argv[])
{
static int first = 1, t = 0;
int updata = 0, len = 0;
char musicRoute[256] = {0};
if(first && argc == 2)
{
strcpy(musicRoute, argv[1]);
len = strlen(musicRoute);
if(len > 4 && len < 255)
updata = 1;
first = 0;
}
GetWindowText(hwnd, musicRoute, 255);

if(strcmp(musicRoute, "简

约音乐"))
{
SetWindowText(hwnd, "简约音乐");
if(strcmp(musicRoute, "FLASH") == 0)
{
t = 80;
ShowWindow(hwnd, SW_SHOWMINIMIZED);
ShowWindow(hwnd, SW_SHOWMAXIMIZED);
MessageBeep(0);
}
else
{
t = 0;
len = strlen(musicRoute);
if(len > 4 && len < 255)
updata = 1;
}
}

if(t < 30)
t++;
else
t--;

if(t > 30 && t % 10 > 4)
{
rectangle(0, 0, 251, (pstate.addfolder | pstate.musiclist) * 175 + 149);
rectangle(1, 1, 250, (pstate.addfolder | pstate.musiclist) * 175 + 148);
}

if(updata == 1)
{
int i = 0, pos = 0;
for(i = 0; i < len; i++)
{
if(musicRoute[i] == '\\')
pos = i+1;
}
for(i = 0; i < pos; i++)
musiclist.folder[MAXSIZE][i] = musicRoute[i];
musiclist.folder[MAXSIZE][i] = 0;

for(i = pos; i < len; i++)
https://www.doczj.com/doc/1915032836.html,[MAXSIZE][i - pos] = musicRoute[i];
https://www.doczj.com/doc/1915032836.html,[MAXSIZE][i - pos] = 0;
if(pos >= len-4)
return;
if(pstate.music_id != MAXSIZE)
lastSong = pstate;
stop();
pstate.music_id = MAXSIZE;
function = PLAY;
pstate.prompt[pstate.ptLength++] = 7;
}
}

void run(int argc, char *argv[])
{
while(1)
{
init_key();
mouse();
ele_key();
set_play_way();
show_play_way();
set_function();
run_play_function();
show_music_list();
addfolder();
gui_msg();
text_msg();
SystemOpen(argc, argv);
pset();
noMusicToAdd();
prompt();
quit();
WindowMaxMin();
move_window();
delay_fps(60);
cleardevice();
}
}

int RunMinimize()
{
int press = 5, pressM = 0, t = 0;
while(1)
{
pressM = 0;
init_key();
set_play_way();
set_function();
run_play_function();
SystemOpen(0, 0);
if(GetAsyncKeyState('M') || GetAsyncKeyState('m'))
pressM = 1;

if(key.pressControl && pressM)
{
if(press == 0)
ShowWindow(hwnd, SW_SHOWMAXIMIZED);
}
else if(press > 0)
press--;

if(t > 10)
{
if(IsZoomed(hwnd))
{
pstate.wondowsState = 1;
return 1;
}
t = 0;
}
t++;
delay_fps(30);
}

return 0;
}

void draw_folderIcon(int x, int y, int ele)
{
if(ele)
{
setcolor(EGERGB(180,255,252));
setfillcolor(EGERGB(40,120,190));
}
else
{
setcolor(EGERGB(20,200,200));
setfillcolor(EGERGB(40,120,190));
}
int ptd[] = {x,y, x+5,y, x+7,y+2, x+14,y+2 ,x+14,y+4, x,y+12};
fillpoly(6, ptd);
int pte[] = {x+1,y+12, x+3,y+4, x+17,y+4, x+14,y+12};
fillpoly(4, pte);
}

void gui_msg()
{
int progess = 198*pstate.music_pos/(pstate.music_length + (pstate.music_length == 0)) + 26;
setcolor(EGERGB(100,200,180));
rectangle(24,99,226,116); //歌曲进度条边框
setcolor(EGERGB(180,200,190));
setfillcolor(EGERGB(150,200,210));
bar(26,101,progess,114); //歌曲进度条
if(key.playbar >= 0)
imagefilter_blurring(NULL, 200, 200, 25, 100, key.playbar, 15);//欲跳到指定进度的显示条

if(key.stop == 1)
setfillcolor(EGERGB(210,255,255));
else

setfillcolor(EGERGB(160,200,190));
bar(25,120,40,135);//停止按钮

if(key.play == 1 || key.pause == 1)
setfillcolor(EGERGB(210,255,255));
else
setfillcolor(EGERGB(160,200,190));
if(pstate.music_play == 0)/*播放按钮*/
{
int ptc[] ={55,120, 68,128, 55,135};
fillpoly(3,ptc);
}
else/*暂停按钮*/
{
bar(55,120,60,135);
bar(64,120,69,135);
}

/*绘制上一首按钮*/
if(key.sys == 1)
setfillcolor(EGERGB(210,255,255));
else
setfillcolor(EGERGB(160,200,190));
bar(86,120,89,135);
int pta[] ={90,128, 100,120, 100,135};
fillpoly(3,pta);

/*绘制下一首按钮*/
if(key.xys == 1)
setfillcolor(EGERGB(210,255,255));
else
setfillcolor(EGERGB(160,200,190));
bar(127,120,130,135);
int ptb[] = {115,120, 115,135, 125,128};
fillpoly(3,ptb);

/*绘制声音控制按钮*/
int ptc[] = {145,125, 145,130, 150,130, 155,135, 155,120, 150,125};
if(key.mute == 1)
setfillcolor(EGERGB(210,255,255));
else
setfillcolor(EGERGB(160,200,190));
fillpoly(6,ptc);//绘制声音喇叭
if(pstate.mute == 1) //绘制静音图标
{
setcolor(RED);
circle(151,128,5);
line(147,125, 155,131);
}
if(key.volbar > 0)
setfillcolor(EGERGB(210,255,255));
else
setfillcolor(EGERGB(160,200,190));
if(key.volbar > 0 && key.mleftpress == 1)
setfillcolor(EGERGB(100,200,200));
else if(key.volbar > 0)
setfillcolor(EGERGB(175,220,255));

bar(160,125,225,130);//绘制声音条
setfillcolor(EGERGB(180,200,190));
bar(160+pstate.music_vol*120.0,121, 165+pstate.music_vol*120.0,134);//绘制一个矩形表示当前用户把声音设为多大
if(pstate.music_vol != pstate.music_last_vol)
{
setfillcolor(EGERGB(150,220,200));
bar(160+pstate.music_last_vol*120.0,121, 165+pstate.music_last_vol*120.0,134);//绘制当前实际声音大小
}
if(key.volbar >= 0)
imagefilter_blurring(NULL, 100,100, 160+key.volbar,121, 5,13);//绘制当前鼠标在声音进度条的位置


/*绘制歌启动曲列表的按钮*/
if(key.mlist)
setcolor(EGERGB(180,255,252));
else
setcolor(EGERGB(20,200,200));
rectangle(24,4,45,22);
line(26,7,43,7);
line(26,10,34,10);
line(36,10,43,10);
line(26,14,43,14);
line(26,16,43,16);

//绘制启动添加歌曲文件夹功能的按钮
if(key.addfr)
draw_folderIcon(50, 7, 1);
else
draw_folderIcon(50, 7, 0);
rectangle(48,4, 70,22);
}

void text_msg()
{
static int dey = 100,mx = 24,i_pos = -1, last_music_pos, t;
static float lastVol;
int name_len,g_all_time,g_now_time, key_time;
char timeStr[8] = {0};

if(pstate.music_id != i_pos)
{
i_pos = pstate.music_id;
dey = 100;
mx = 24;
}
setcolor(EGERGB(0,200,230));
if(pstate.music_id != MAXSIZE)
xyprintf(85,5,"%d/%d",(musiclist.length == 0)?0:pstate.music_id+1,musiclist.length); //正在播放的歌曲/歌曲总数
else
xyprintf(85,5,"临时播放");

name_len = strlen(https://www.doczj.com/doc/1915032836.html,[pstate.music_id]);
g_all_time = pstate.m

usic_length/1000;
g_now_time = pstate.music_pos/1000;

xyprintf(24,82,"%02d:%02d",g_now_time/60,g_now_time%60); //播放到的时间
sprintf(timeStr,"%02d:%02d",g_all_time/60,g_all_time%60);
xyprintf(222-strlen(timeStr)*7,82,"%s",timeStr); //总时间

if(key.playbar >= 0)
{
key_time = (float)key.playbar/200 * g_all_time;
xyprintf(105,82,"%02d:%02d",key_time/60, key_time%60); //鼠标在播放进度条上所指位置的时间,如果此时点鼠标左键跳到这里播放
}

if(lastVol != pstate.music_last_vol)
{
lastVol = pstate.music_last_vol;
t = 60;
}
else if(t > 0)
t--;
if(t > 0)
xyprintf(226,120, "%.f", pstate.music_vol * 200); //播放器要设置到的声音大小
if(key.volbar >= 0)
xyprintf(226,120, "%.f", (float)key.volbar/120.0 * 200); //鼠标在声音条上所指位置声音大小

if(musiclist.length > 0 || pstate.music_id == MAXSIZE)
{
setcolor(EGERGB(200,252,200));
xyprintf(mx,30,"%s",https://www.doczj.com/doc/1915032836.html,[pstate.music_id]); //当前播放的歌曲名字
if(name_len>26)/*如果歌曲名超过25个字符,就滚动显示该歌曲名*/
{
dey--;

xyprintf(mx+name_len*8+20,30,"%s",https://www.doczj.com/doc/1915032836.html,[pstate.music_id]);
if(dey<0)
{
mx--;
if((24-mx) >= name_len*8+20)
{
mx = 24;
dey = 100;
}
}
/*遮盖两端超出范围的文字*/
setfillcolor(EGERGB(40,120,180));
bar(0,30,24,50);
bar(225,30,252,50);
}
else
{
mx = 24;
dey = 100;
}
}
}

int ele_pos(int length)
{
static int pos,t;
if(msg.y > 175 && msg.x < 225 && 1 == key.mmove)
pos = (msg.y-175)/18;
if(!key.pressControl)
{
if(keystate(VK_UP))
{
if(t%10==0)
pos--;
t++;
}
else if(keystate(VK_DOWN))
{
if(t%10==0)
pos++;
t++;
}
else
t = 0;
}
else
t = 0;

if(pos >= length)
pos = length-1;
if(pos < 0)
pos = 0;
if(pos > 7)
pos = 7;

return pos;
}

int mouse_move_list(int s, int length)
{
static int t;
static float td = -1, y;
float bar_hight, maxHeight = 140;
if(length > 8)//当个曲数量大于8时运行
{
/*绘制右侧拖动条*/
setcolor(EGERGB(100,200,250));
rectangle(228,179,249,320); //外框
setfillcolor(EGERGB(40,100,130));
bar(230,181, 247,318);

bar_hight = 1120/length; // 8/length * 140, 计算列表里显示的8首歌占歌曲总数的几分之几从而知道右侧滑块高度占拖动条总长(140)的几分之几,算出高度
if(bar_hight < 5)
{
maxHeight = 135.0 + bar_hight;
bar_hight = 5;
}

if(td >= 0 && 1 == key.mleftpress && msg.y>159 && msg.y<341 && msg.x > 200)
{
setfillcolor(EGERGB(210,230,255));
if(key.mmove == 1)
{
y = msg.y - td;
s = length*(y-180)/maxHeight;

}
}
else
{
td = -1;
y = maxHeight * s/length + 180;
if(msg.x > 225 && msg.y >= y && msg.y <= y+bar_hight)//td使用来记录鼠标左键按住拖动块时鼠

标纵坐标与拖动条的位置(上端)的距离
{
setfillcolor(EGERGB(160,225,252));
if(1 == key.mleft)
td = msg.y-y;
}
else
setfillcolor(EGERGB(100,180,190));
}

if(1 == key.mleftpress && msg.x>225 && msg.y>179 && msg.y<320)/*如果鼠标在拖动条上按住左键,鼠标在滑块上方则下移列表,鼠标在滑块下方则上移列表*/
{
if(t%10 == 0)
{
if(msg.y < y)
s--;
else if(msg.y > y+bar_hight)
s++;
}
t++;
}
else
t = 0;
if(y < 180)
y = 180;
if(y > 319 - bar_hight)
y = 319 - bar_hight;
bar(230,y, 247,y+bar_hight); //绘制拖动滑块

if(msg.wheel < 0)
s+=2;
else if(msg.wheel > 0)
s-=2;
}
if(s >= length - 8) /*如果列表顶端位置被设置在第7行以上,则把顶端设置在第7行(歌曲数目大于等于8时)*/
{
if(length >= 8)
s = length - 8;
else
s = 0;
}
if(s < 0)/*如果列表顶端位置被设置在第0行以下,则把顶端设置在第0行*/
s = 0;
return s;
}

int key_move_list(int s, int pos, int length)
{
static int t,up,down;
if(!key.pressControl)
{
if(up == 1 && key.pressUp)
{
if(t%10 == 1)
s--;
t++;

}
else if(down == 1 && key.pressDown)
{
if(t%10 == 1)
s++;
t++;

}
else
t = 0;

if(pos == 0) /*当光标移到第一行时把up的值设为1从而可以通过上键控制列表向上*/
{
if(up == 0) //当光标是由其它行移到第一行延时大约2秒后可由上键控制列表向上
t = -120;
up = 1;
down = 0;
}
else if(pos == 7) /*当光标移到最后一行时把down的值设为1从而可以通过下键控制列表向下*/
{
if(down == 0) //当光标是由其它行移到最后一行延时大约2秒后可由下键控制列表向下
t = -120;
up = 0;
down = 1;
}
else
up = down = 0;

if(t<0)
t++;

if(s >= length - 8)
{
if(length >= 8)
s = length - 8;
else
s = 0;
}
if(s < 0)
s = 0;
}
return s;
}

void show_box(int pos,int length)
{
static int boxy;
int posy;
if(boxy < 174)
boxy = 174;
if(length > 0)
{
posy = pos*18+174;
if(boxy < posy)
{
boxy = boxy + (posy-boxy)/17 + 1;

}
else if(boxy>posy)
{
boxy = boxy - (boxy-posy)/17 - 1;

}
setcolor(EGERGB(100,255,255));
line(5,boxy, 225,boxy);
line(5,boxy+18, 225,boxy+18);
}
}

void show_music_list()
{
static int s, f = 1, pos,ls, right_fn = 0;
static int dey[8],mx[8];
static HRGN hr;
int i, name_len=0, y, length;

if(1 != pstate.musiclist)
{
f = 1;
s = ls = 0;
return;
}
setfont(14,0,PLAY_FONT);
length = musiclist.length;
if(0 != f)
{
f = 0;
s = pstate.music_id;
}
setfillcolor(EGERGB(50,100,160));
bar(0,154, 255, 173); //绘制列表栏

xyprintf(5,157, "%d/%d",s+pos+1, musiclist.length); //显示列表状态
if(msg.x >

228 && msg.x < 249 && msg.y > 155 && msg.y < 170)
{
if(1 == key.mleft)
pstate.musiclist = 0;
setcolor(EGERGB(255,0,0));//鼠标指针放在关闭按钮上时关闭按钮上的X变成红色
}
else
setcolor(EGERGB(0,200,255));//鼠标指针未放在关闭按钮上时关闭按钮上的X变成RGB(0,200,255)色
/*关闭列表按钮*/
line(232,158, 245,171);
line(232,170, 245,157);
imagefilter_blurring(NULL,100,230, 228,155, 21,18);

if(0 == right_fn || pos >= length)
pos = ele_pos(length);

/*显示歌曲名字*/
for(i = 0; i<8; i++)
{
y = 175+i*18;
setfillcolor(EGERGB(30,75,100)); //文字背景
bar(0,y, 228,y+17);
if(s+i{
if(pstate.music_id == s+i)
setcolor(EGERGB(100,252,50));
else
setcolor(EGERGB(50,200,220));
xyprintf(6+mx[i],y+2,"%s",https://www.doczj.com/doc/1915032836.html,[s+i]);
name_len = strlen(https://www.doczj.com/doc/1915032836.html,[s+i]);
if(name_len>31)
{
if(i == pos)
{
if(dey[i] > 0)
dey[i]--;

if(0 == dey[i])
{
xyprintf(6+mx[i]+name_len*7+20,y+2,"%s",https://www.doczj.com/doc/1915032836.html,[s+i]);
mx[i]--;
if(-mx[i] >= name_len*7+20)
{
mx[i] = 0;
dey[i] = 100;//滚动歌名停止滚动等待100贞后在滚动
}
}
}
if(i != pos || s != ls)
{
ls = s;
mx[i] = 0;
dey[i] = 50;
}
}
else
{
ls = s;
mx[i] = 0;
dey[i] = 50;
}
}
}
setfont(16,0,PLAY_FONT);
setfillcolor(EGERGB(30,75,100));//遮盖两边文字
bar(0,175, 5,320);
bar(224,175, 252,320);
bar(0,173, 252,175);//填充顶部
bar(0,319, 252,325);//填充底部
s = mouse_move_list(s, length);//鼠标移动列表
s = key_move_list(s, pos, length);//键盘鼠标移动列表
show_box(pos, length);

if(right_fn == 0 && msg.y > 175 && msg.y < pos*18+193 && msg.x < 225 && 1 == key.mleft || key.enter)
{
key.enter = 0;
if(length <= 0)
return;
if(pstate.music_id == MAXSIZE)
{
lastSong.music_id = s+i;
lastSong.music_id = s+pos;
lastSong.music_pos = 0;
lastSong.music_play = 1;
function = STOP;
}
else if(pstate.music_id == s+pos)
{
if(pstate.music_play == 1)
function = PAUSE;
else
function = PLAY;
}
else
{
stop();
pstate.music_id = s+pos;
function = PLAY;
}
}
right_fn = mright_FN(msg.x-30, pos*18+175, s+pos, 1);
}


void show_file_list(FOLDER folder, LIST *file, char *route, int showAddFolder, int *first)
{
static int s, pos,ls, right_fn;
static int dey[8],mx[8];
static HRGN hr;
int i, k, name_len=0, y, length = 0;
char str[256] = ".....";

if(1 == *first)
{
*first = 0;
right_fn = s = ls = 0;
}
length = folder.length + (*file).length;
setfont(12,0,PLAY_FONT);

setfillcolor(EGERGB(50,100,160));
bar(0,154, 255, 173); //绘制列表栏
xyprintf(5,157, "%d/%d",(length == 0)?0:(s+pos+1), length); //显示列表状态

if((*file).frlength == 1)
xyprin

tf(70,157, (*file).folder[(*file).frlength-1]);
else
{
name_len = strlen(route);
if(name_len > 23)
{

for(i = 0, k = 0; i <= name_len; i++)
{
if(i > 2 && i < name_len - 17)
continue;
if(k == 3)
k = 5;
str[k++] = route[i];
}
xyprintf(56,157,str);
}
else
xyprintf(56,157,route);
}
if(msg.x > 228 && msg.x < 249 && msg.y > 155 && msg.y < 170)
{
if(1 == key.mleft)
{
*first = 1;
pstate.addfolder = 0;
}
setcolor(EGERGB(255,0,0));//鼠标指针放在关闭按钮上时关闭按钮上的X变成红色
}
else
setcolor(EGERGB(0,200,255));//鼠标指针未放在关闭按钮上时关闭按钮上的X变成RGB(0,200,255)色
/*关闭列表按钮*/
line(232,158, 245,171);
line(232,170, 245,157);
imagefilter_blurring(NULL,100,230, 228,155, 21,18);
if(0 == right_fn || pos >= length)
pos = ele_pos(length);
setfont(14,0,PLAY_FONT);
/*显示歌曲或文件夹名字*/
for(i = 0; i<8; i++)
{
y = 175+i*18;
setfillcolor(EGERGB(30,75,100));
bar(0,y, 228,y+17);
if(s+i{
setcolor(EGERGB(50,200,220));
if(s+i < folder.length)
strcpy(str, folder.folder[s+i]);
else
strcpy(str, (*file).name[s+i-folder.length]);
xyprintf(26+mx[i],y+2,"%s",str);
if((*file).frlength == 1)
show_driver(folder.folder[s+i][254], y+2);
name_len = strlen(str);
if(name_len>29)
{
if(i == pos)
{
if(dey[i] > 0)
dey[i]--;
if(0 == dey[i])
{
xyprintf(26+mx[i]+name_len*7+20,y+2,"%s",str);
mx[i]--;
if(-mx[i] >= name_len*7+20)
{
mx[i] = 0;
dey[i] = 100;//滚动歌名停止滚动等待100贞后在滚动
}
}
}
if(i != pos || s != ls)
{
ls = s;
mx[i] = 0;
dey[i] = 50;
}
}
else
{
ls = s;
mx[i] = 0;
dey[i] = 50;
}

int ele = 0;
if(pos == (y-175)/18)
ele = 1;
if(s+i < folder.length)
draw_folderIcon(5,y+3, ele);
else
draw_fileIcon(6, y+3, ele);
}
}
setfillcolor(EGERGB(30,75,100));//遮盖两边文字
bar(0,175, 5,320);
bar(224,175, 252,320);
bar(0,173, 252,175);//填充顶部
bar(0,319, 252,325);//填充底部
s = mouse_move_list(s, length);//鼠标移动列表
s = key_move_list(s, pos, length);//键盘鼠标移动列表
show_box(pos, length);
setfont(16,0,PLAY_FONT);
if(right_fn == 0 && length > 0 && msg.y > 175 && msg.y < 193+pos*18 && msg.x < 225 && 1 == key.mleft
|| key.enter || key.addThis == 1)
{
key.enter = 0;
if(length <= 0)
return;
if(s+pos < folder.length && (*file).frlength < MAXSIZE)
{
if(folder.folder[s+pos][strlen(folder.folder[s+pos])-1] != '\\')
strcat(folder.folder[s+pos], "\\");
if(key.addThis == 0)
{
strcpy((*file).folder[(*file).frlength++], folder.folder[s+pos]);
}
else if(key.addThis == 1)
{
key.addThis = 2;
}

strcat(route, folder

.folder[s+pos]);
}
else if(s+pos < length && s+pos >= folder.length)
{
if(key.addThis == 0)
{
if(pstate.music_id != MAXSIZE)
{
lastSong = pstate;
save_state();
}
stop();
strcpy(https://www.doczj.com/doc/1915032836.html,[MAXSIZE], (*file).name[s+pos-folder.length]);
strcpy(musiclist.folder[MAXSIZE], route);
pstate.music_id = MAXSIZE;
function = PLAY;
pstate.prompt[pstate.ptLength++] = 7;
}
else if(key.addThis == 1)
{
key.addThis = 2;
strcat(route, (*file).name[s+pos-folder.length]);
}
}
}


int way = 0;
if(length == 0)
way = 0;
else if(showAddFolder && file->frlength == 1)
way = 2;
else if(s+pos < folder.length)
way = 3;
else
way = 4;
right_fn = mright_FN(msg.x-30, pos*18+175, s+pos, way);
}

void show_driver(int type, int y)
{
char str[20] = {0};
if(type > 0)
{
switch(type)
{
case 1:
strcpy(str,"其它");
break;
case 2:
strcpy(str,"USB Driver");
break;
case 3:
strcpy(str,"本地磁盘");
break;
case 4:
strcpy(str,"其它");
break;
case 5:
strcpy(str,"DVD RW");
break;
default:
strcpy(str,"其它");
}
}
xyprintf(50,y, "%s",str);
}

void draw_fileIcon(int x, int y, int selected)
{
if(selected)
{
setcolor(EGERGB(180,255,252));
setfillcolor(EGERGB(40,120,190));
}
else
{
setcolor(EGERGB(50,200,220));
setfillcolor(EGERGB(30,75,100));
}
int pt[] = {x,y+3, x+3,y, x+12,y, x+12,y+12, x,y+12};
fillpoly(5, pt);
line(x+3,y+5, x+10,y+5);
line(x+3,y+7, x+10,y+7);
line(x+3,y+9, x+10,y+9);
}

void draw_addfolder()
{
setcolor(EGERGB(100,90,0));
setfillcolor(EGERGB(240,230,0));
int pta[] = {100,40, 150,40, 150,100, 120,90, 120,110, 100,100};
fillpoly(6,pta);
int ptb[] = {100,40, 122,52, 122,100, 120,102, 120,110, 100,100};
fillpoly(6,ptb);
}

void AddSignIcon(int x, int y, int selected)
{
static int cr;
int i = 0,m = -5;
if(selected || msg.x >= x && msg.x <= x+15 && msg.y > y && msg.y <= y+15)
{
setfillcolor(EGERGB(cr,255-cr,cr));
if(0 == cr || 225 == cr)
m = -m;
cr+=m;
if(keystate(1))
pstate.addfolder = 1;
if(key.mleft == 1)
pstate.addfolder;
}
else
setfillcolor(EGERGB(30,160,0));
bar(x, y+5, x+15, y+10);
bar(x+5, y, x+10, y+15);
}

void drawComputerIcon(int x, int y)
{
if(msg.x >= x && msg.x <= x+18 && msg.y >= y && msg.y <= y+15) //如果鼠标放在图标上则高亮显示图标
{
setfillcolor(EGERGB(30,160,255));
setcolor(EGERGB(100,255,255));
}
else
{
setfillcolor(EGERGB(30,160,0));
setcolor(EGERGB(0,180,220));
}
rectangle(x,y+3, x+3, y+15);
rectangle(x+4, y+1, x+18, y+11);
int pt[] = {x+11,y+10, x+7,y+14, x+15,y+14};
fillpoly(3, pt);
}

int noMusicToAdd()
{

int selected = 0;
if(0 == pstate.addfolder && 0 == musiclist.length && pstate.music_id != MAXSIZE)
{
pstate.musiclist = 0;
imagefilter_blurring(NULL, 50,100, 0,0,

252,150);
setcolor(EGERGB(30,120,230));
xyprintf(15,120,"未找到歌曲,请添加播放路径");
draw_addfolder();
if(msg.x >= 100 && msg.x <= 150 && msg.y >= 40 && msg.y <= 122)
selected = 1;
AddSignIcon(125, 65, selected);
function = STOP;
}
if(0 == musiclist.length)
{
if(pstate.music_id != MAXSIZE) //如果不是临时播放则设置播放状态为当前的合理状态
{
pstate.musiclist = 0;
pstate.music_last_vol = 0;
pstate.music_open = 0;
pstate.music_pause = 1;
pstate.music_pos = 0;
pstate.music_length = 0;
}
return 1;
}
return 0;
}

void addfolder()
{
static char route[256], roughtTemp[256];
static int last_length, show = 1,first;
char szDriver[3] = "C:", i;
int type;
if(pstate.addfolder == 0)
{
show = 1;
first = 1;
file.frlength = 0;
route[0] = 0;
return;
}

if(0 == file.frlength || route[0] == 0)
{
if(show == 1)
{
strcpy(file.folder[0], "已添加路径");
file.frlength = 1;
folder.length = file.length = 0;
last_length = 1;
folder = folderlist;
}
else
{
strcpy(file.folder[0], "计算机");
file.frlength = 1;
folder.length = file.length = 0;
last_length = 1;
for(i = 'A'; i <= 'Z' && folder.length <= 26; i++)
{
szDriver[0] = i;
type = GetDriveType(szDriver);
if(type > 1)
{
strcpy(folder.folder[folder.length], szDriver);
folder.folder[folder.length][254] = type;
folder.length++;
}
}
}
}
strcpy(roughtTemp, route);
show_file_list(folder, &file, route, show, &first);

if(file.frlength > 0 && file.frlength != last_length) //当路径有变时扫描新路径
{
last_length = file.frlength;
folder.length = file.length = 0;
GetFileList(route, &folder, &file);
}

if(show == 1 && continue_add(file.frlength))
{
file.frlength = 0;
route[0] = 0;
show = 0;
}
if(file.frlength > 1)
{
back(&file, route); //返回上一级路径
if(route[strlen(route)-1] == '\\')
{
if(add_route(route))
{
file.frlength = 0;
route[0] = 0;
}
}
else if(key.addThis == 2)
AddASong(route);

if(key.addThis == 2)
{
key.addThis = 0;
strcpy(route, roughtTemp);
}
}
}

void AddASong(char *route)
{
char fileRoute[256] = {0}, fileName[256] = {0};
int pos = 0, len = strlen(route), i;
if(musiclist.length == MAXSIZE-1)
{
pstate.prompt[pstate.ptLength++] = 9;
return;
}
for(i = 0; i < len; i++)
{
if(route[i] == '\\')
pos = i+1;
}
for(i = 0; i < pos; i++)
{
fileRoute[i] = route[i];
}
for(i = pos; i < len; i++)
{
fileName[i-pos] = route[i];
}

for(i = 0; i < folderlist.length; i++)
{
if(strcmp(fileRoute, folderlist.folder[i]) == 0)
break;
}
if(i == folderlist.length)
{
if(folderlist.length >= MAXFOLDER)
{
pstate.prompt[pstate.ptLength++] = 10;
return;
}
strcpy(folderlist.folder[folderlist.l

相关主题
文本预览
相关文档 最新文档