mirror of
https://github.com/chibicitiberiu/rainmeter-studio.git
synced 2024-02-24 04:33:31 +00:00
NowPlayingPlugin:
- Fixed that PlayerName=, TrackChangeAction=, and DisableLeadingZero= were global (i.e. only usable from the first loaded skin) - Code refactoring and cleanup
This commit is contained in:
parent
67cc4c7c6c
commit
6aa004eb22
332
Plugins/PluginNowPlaying/Cover.cpp
Normal file
332
Plugins/PluginNowPlaying/Cover.cpp
Normal file
@ -0,0 +1,332 @@
|
|||||||
|
/*
|
||||||
|
Copyright (C) 2011 Birunthan Mohanathas (www.poiru.net)
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or
|
||||||
|
modify it under the terms of the GNU General Public License
|
||||||
|
as published by the Free Software Foundation; either version 2
|
||||||
|
of the License, or (at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "StdAfx.h"
|
||||||
|
#include "Cover.h"
|
||||||
|
|
||||||
|
extern std::wstring g_CachePath;
|
||||||
|
|
||||||
|
/*
|
||||||
|
** GetCover
|
||||||
|
**
|
||||||
|
** Default implementation for getting cover.
|
||||||
|
**
|
||||||
|
*/
|
||||||
|
void CCover::GetCover(const std::wstring& artist, const std::wstring& title, const std::wstring& file, std::wstring& target)
|
||||||
|
{
|
||||||
|
if (!GetCachedCover(artist, title, target))
|
||||||
|
{
|
||||||
|
TagLib::FileRef fr(file.c_str());
|
||||||
|
if (fr.isNull() || !fr.tag() || !GetEmbeddedCover(fr, target))
|
||||||
|
{
|
||||||
|
std::wstring trackFolder = GetFileFolder(file);
|
||||||
|
|
||||||
|
if (!GetLocalCover(L"cover", trackFolder, target) &&
|
||||||
|
!GetLocalCover(L"folder", trackFolder, target))
|
||||||
|
{
|
||||||
|
// Nothing found
|
||||||
|
target.clear();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
** GetCachedArt
|
||||||
|
**
|
||||||
|
** Checks if cover art is in cache.
|
||||||
|
**
|
||||||
|
*/
|
||||||
|
bool CCover::GetCachedCover(const std::wstring& artist, const std::wstring& title, std::wstring& target)
|
||||||
|
{
|
||||||
|
target = g_CachePath;
|
||||||
|
if (artist.empty() || title.empty())
|
||||||
|
{
|
||||||
|
target += L"temp.art";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Otherwise, save it as "Artist - Title.art"
|
||||||
|
std::wstring name = artist;
|
||||||
|
name += L" - ";
|
||||||
|
name += title;
|
||||||
|
|
||||||
|
// Replace reserved chars with _
|
||||||
|
std::wstring::size_type pos = 0;
|
||||||
|
while ((pos = name.find_first_of(L"\\/:*?\"<>|", pos)) != std::wstring::npos) name[pos] = L'_';
|
||||||
|
|
||||||
|
target += name;
|
||||||
|
target += L".art";
|
||||||
|
if (_waccess(target.c_str(), 0) == 0)
|
||||||
|
{
|
||||||
|
// Art found in cache
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
** GetLocalArt
|
||||||
|
**
|
||||||
|
** Attemps to find local cover art in various formats.
|
||||||
|
**
|
||||||
|
*/
|
||||||
|
bool CCover::GetLocalCover(std::wstring filename, const std::wstring& folder, std::wstring& target)
|
||||||
|
{
|
||||||
|
std::wstring testPath = folder;
|
||||||
|
testPath += filename;
|
||||||
|
testPath += L".";
|
||||||
|
std::wstring::size_type origLen = testPath.length();
|
||||||
|
|
||||||
|
const int extCount = 4;
|
||||||
|
LPCTSTR extName[extCount] = { L"jpg", L"jpeg", L"png", L"bmp" };
|
||||||
|
|
||||||
|
for (int i = 0; i < extCount; ++i)
|
||||||
|
{
|
||||||
|
testPath += extName[i];
|
||||||
|
if (_waccess(testPath.c_str(), 0) == 0)
|
||||||
|
{
|
||||||
|
target = testPath;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Get rid of the added extension
|
||||||
|
testPath.resize(origLen);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
** GetEmbeddedArt
|
||||||
|
**
|
||||||
|
** Attempts to extract cover art from audio files.
|
||||||
|
**
|
||||||
|
*/
|
||||||
|
bool CCover::GetEmbeddedCover(const TagLib::FileRef& fr, std::wstring& target)
|
||||||
|
{
|
||||||
|
bool found = false;
|
||||||
|
|
||||||
|
if (TagLib::MPEG::File* file = dynamic_cast<TagLib::MPEG::File*>(fr.file()))
|
||||||
|
{
|
||||||
|
if (file->ID3v2Tag())
|
||||||
|
{
|
||||||
|
found = ExtractID3(file->ID3v2Tag(), target);
|
||||||
|
}
|
||||||
|
if (!found && file->APETag())
|
||||||
|
{
|
||||||
|
found = ExtractAPE(file->APETag(), target);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (TagLib::MP4::File* file = dynamic_cast<TagLib::MP4::File*>(fr.file()))
|
||||||
|
{
|
||||||
|
if (file->tag())
|
||||||
|
{
|
||||||
|
found = ExtractMP4(file, target);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (TagLib::FLAC::File* file = dynamic_cast<TagLib::FLAC::File*>(fr.file()))
|
||||||
|
{
|
||||||
|
found = ExtractFLAC(file, target);
|
||||||
|
|
||||||
|
if (!found && file->ID3v2Tag())
|
||||||
|
{
|
||||||
|
found = ExtractID3(file->ID3v2Tag(), target);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (TagLib::ASF::File* file = dynamic_cast<TagLib::ASF::File*>(fr.file()))
|
||||||
|
{
|
||||||
|
found = ExtractASF(file, target);
|
||||||
|
}
|
||||||
|
else if (TagLib::APE::File* file = dynamic_cast<TagLib::APE::File*>(fr.file()))
|
||||||
|
{
|
||||||
|
if (file->APETag())
|
||||||
|
{
|
||||||
|
found = ExtractAPE(file->APETag(), target);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (TagLib::MPC::File* file = dynamic_cast<TagLib::MPC::File*>(fr.file()))
|
||||||
|
{
|
||||||
|
if (file->APETag())
|
||||||
|
{
|
||||||
|
found = ExtractAPE(file->APETag(), target);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (TagLib::WavPack::File* file = dynamic_cast<TagLib::WavPack::File*>(fr.file()))
|
||||||
|
{
|
||||||
|
if (file->APETag())
|
||||||
|
{
|
||||||
|
found = ExtractAPE(file->APETag(), target);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return found;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
** GetFileFolder
|
||||||
|
**
|
||||||
|
** Returns path without filename.
|
||||||
|
**
|
||||||
|
*/
|
||||||
|
std::wstring CCover::GetFileFolder(const std::wstring& file)
|
||||||
|
{
|
||||||
|
std::wstring::size_type pos = file.find_last_of(L'\\');
|
||||||
|
if (pos != std::wstring::npos)
|
||||||
|
{
|
||||||
|
return file.substr(0, ++pos);
|
||||||
|
}
|
||||||
|
|
||||||
|
return file;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
** ExtractAPE
|
||||||
|
**
|
||||||
|
** Extracts cover art embedded in APE tags.
|
||||||
|
**
|
||||||
|
*/
|
||||||
|
bool CCover::ExtractAPE(TagLib::APE::Tag* tag, const std::wstring& target)
|
||||||
|
{
|
||||||
|
const TagLib::APE::ItemListMap& listMap = tag->itemListMap();
|
||||||
|
if (listMap.contains("COVER ART (FRONT)"))
|
||||||
|
{
|
||||||
|
const TagLib::ByteVector nullStringTerminator(1, 0);
|
||||||
|
|
||||||
|
TagLib::ByteVector item = listMap["COVER ART (FRONT)"].value();
|
||||||
|
int pos = item.find(nullStringTerminator); // Skip the filename
|
||||||
|
|
||||||
|
if (++pos > 0)
|
||||||
|
{
|
||||||
|
const TagLib::ByteVector& pic = item.mid(pos);
|
||||||
|
return WriteCover(pic, target);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
** ExtractID3
|
||||||
|
**
|
||||||
|
** Extracts cover art embedded in ID3v2 tags.
|
||||||
|
**
|
||||||
|
*/
|
||||||
|
bool CCover::ExtractID3(TagLib::ID3v2::Tag* tag, const std::wstring& target)
|
||||||
|
{
|
||||||
|
const TagLib::ID3v2::FrameList& frameList = tag->frameList("APIC");
|
||||||
|
if (!frameList.isEmpty())
|
||||||
|
{
|
||||||
|
// Grab the first image
|
||||||
|
TagLib::ID3v2::AttachedPictureFrame* frame = static_cast<TagLib::ID3v2::AttachedPictureFrame*>(frameList.front());
|
||||||
|
return WriteCover(frame->picture(), target);
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
** ExtractASF
|
||||||
|
**
|
||||||
|
** Extracts cover art embedded in ASF/WMA files.
|
||||||
|
**
|
||||||
|
*/
|
||||||
|
bool CCover::ExtractASF(TagLib::ASF::File* file, const std::wstring& target)
|
||||||
|
{
|
||||||
|
const TagLib::ASF::AttributeListMap& attrListMap = file->tag()->attributeListMap();
|
||||||
|
if (attrListMap.contains("WM/Picture"))
|
||||||
|
{
|
||||||
|
const TagLib::ASF::AttributeList& attrList = attrListMap["WM/Picture"];
|
||||||
|
|
||||||
|
if (!attrList.isEmpty())
|
||||||
|
{
|
||||||
|
// Let's grab the first cover. TODO: Check/loop for correct type
|
||||||
|
TagLib::ASF::Picture wmpic = attrList[0].toPicture();
|
||||||
|
if (wmpic.isValid())
|
||||||
|
{
|
||||||
|
return WriteCover(wmpic.picture(), target);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
** ExtractFLAC
|
||||||
|
**
|
||||||
|
** Extracts cover art embedded in FLAC files.
|
||||||
|
**
|
||||||
|
*/
|
||||||
|
bool CCover::ExtractFLAC(TagLib::FLAC::File* file, const std::wstring& target)
|
||||||
|
{
|
||||||
|
const TagLib::List<TagLib::FLAC::Picture*>& picList = file->pictureList();
|
||||||
|
if (!picList.isEmpty())
|
||||||
|
{
|
||||||
|
// Let's grab the first image
|
||||||
|
TagLib::FLAC::Picture* pic = picList[0];
|
||||||
|
return WriteCover(pic->data(), target);
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
** ExtractMP4
|
||||||
|
**
|
||||||
|
** Extracts cover art embedded in MP4-like files.
|
||||||
|
**
|
||||||
|
*/
|
||||||
|
bool CCover::ExtractMP4(TagLib::MP4::File* file, const std::wstring& target)
|
||||||
|
{
|
||||||
|
TagLib::MP4::Tag* tag = file->tag();
|
||||||
|
if (tag->itemListMap().contains("covr"))
|
||||||
|
{
|
||||||
|
TagLib::MP4::CoverArtList coverList = tag->itemListMap()["covr"].toCoverArtList();
|
||||||
|
if (coverList[0].data().size() > 0)
|
||||||
|
{
|
||||||
|
return WriteCover(coverList[0].data(), target);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
** WriteCover
|
||||||
|
**
|
||||||
|
** Write cover data to file.
|
||||||
|
**
|
||||||
|
*/
|
||||||
|
bool CCover::WriteCover(const TagLib::ByteVector& data, const std::wstring& target)
|
||||||
|
{
|
||||||
|
bool written = false;
|
||||||
|
|
||||||
|
FILE* f = _wfopen(target.c_str(), L"wb");
|
||||||
|
if (f)
|
||||||
|
{
|
||||||
|
written = (fwrite(data.data(), 1, data.size(), f) == data.size());
|
||||||
|
fclose(f);
|
||||||
|
}
|
||||||
|
|
||||||
|
return written;
|
||||||
|
}
|
58
Plugins/PluginNowPlaying/Cover.h
Normal file
58
Plugins/PluginNowPlaying/Cover.h
Normal file
@ -0,0 +1,58 @@
|
|||||||
|
/*
|
||||||
|
Copyright (C) 2011 Birunthan Mohanathas (www.poiru.net)
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or
|
||||||
|
modify it under the terms of the GNU General Public License
|
||||||
|
as published by the Free Software Foundation; either version 2
|
||||||
|
of the License, or (at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __COVER_H__
|
||||||
|
#define __COVER_H__
|
||||||
|
|
||||||
|
#include "apefile.h"
|
||||||
|
#include "apetag.h"
|
||||||
|
#include "asffile.h"
|
||||||
|
#include "attachedpictureframe.h"
|
||||||
|
#include "commentsframe.h"
|
||||||
|
#include "flacfile.h"
|
||||||
|
#include "id3v1genres.h"
|
||||||
|
#include "id3v2tag.h"
|
||||||
|
#include "mpcfile.h"
|
||||||
|
#include "mp4file.h"
|
||||||
|
#include "mpegfile.h"
|
||||||
|
#include "tag.h"
|
||||||
|
#include "taglib.h"
|
||||||
|
#include "textidentificationframe.h"
|
||||||
|
#include "tstring.h"
|
||||||
|
#include "vorbisfile.h"
|
||||||
|
#include "wavpackfile.h"
|
||||||
|
|
||||||
|
class CCover
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
static void GetCover(const std::wstring& artist, const std::wstring& title, const std::wstring& file, std::wstring& target);
|
||||||
|
static bool GetCachedCover(const std::wstring& artist, const std::wstring& title, std::wstring& target);
|
||||||
|
static bool GetLocalCover(std::wstring filename, const std::wstring& folder, std::wstring& target);
|
||||||
|
static bool GetEmbeddedCover(const TagLib::FileRef& fr, std::wstring& target);
|
||||||
|
static std::wstring GetFileFolder(const std::wstring& file);
|
||||||
|
|
||||||
|
private:
|
||||||
|
static bool ExtractAPE(TagLib::APE::Tag* tag, const std::wstring& target);
|
||||||
|
static bool ExtractID3(TagLib::ID3v2::Tag* tag, const std::wstring& target);
|
||||||
|
static bool ExtractASF(TagLib::ASF::File* file, const std::wstring& target);
|
||||||
|
static bool ExtractFLAC(TagLib::FLAC::File* file, const std::wstring& target);
|
||||||
|
static bool ExtractMP4(TagLib::MP4::File* file, const std::wstring& target);
|
||||||
|
static bool WriteCover(const TagLib::ByteVector& data, const std::wstring& target);
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
@ -37,31 +37,11 @@ CPlayer* g_Winamp = NULL;
|
|||||||
CPlayer* g_WLM = NULL;
|
CPlayer* g_WLM = NULL;
|
||||||
CPlayer* g_WMP = NULL;
|
CPlayer* g_WMP = NULL;
|
||||||
|
|
||||||
static MeasureMap g_Values;
|
static std::map<UINT, ChildMeasure*> g_Measures;
|
||||||
static bool g_DisableLeazingZero = false;
|
static bool g_DisableLeazingZero = false;
|
||||||
std::wstring g_CachePath;
|
std::wstring g_CachePath;
|
||||||
std::wstring g_SettingsFile;
|
std::wstring g_SettingsFile;
|
||||||
|
|
||||||
void SecondsToTime(UINT seconds, WCHAR* buffer)
|
|
||||||
{
|
|
||||||
int hours = seconds;
|
|
||||||
int mins = seconds;
|
|
||||||
hours /= 3600;
|
|
||||||
mins %= 3600;
|
|
||||||
int secs = mins;
|
|
||||||
mins /= 60;
|
|
||||||
secs %= 60;
|
|
||||||
|
|
||||||
if (hours)
|
|
||||||
{
|
|
||||||
_snwprintf_s(buffer, 32, _TRUNCATE, g_DisableLeazingZero ? L"%i:%02i:%02i" : L"%02i:%02i:%02i", hours, mins, secs);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
_snwprintf_s(buffer, 32, _TRUNCATE, g_DisableLeazingZero ? L"%i:%02i" : L"%02i:%02i", mins, secs);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** Initialize
|
** Initialize
|
||||||
**
|
**
|
||||||
@ -70,7 +50,7 @@ void SecondsToTime(UINT seconds, WCHAR* buffer)
|
|||||||
*/
|
*/
|
||||||
UINT Initialize(HMODULE instance, LPCTSTR iniFile, LPCTSTR section, UINT id)
|
UINT Initialize(HMODULE instance, LPCTSTR iniFile, LPCTSTR section, UINT id)
|
||||||
{
|
{
|
||||||
if (g_Values.empty())
|
if (g_Measures.empty())
|
||||||
{
|
{
|
||||||
// Get path to temporary folder (for cover art cache)
|
// Get path to temporary folder (for cover art cache)
|
||||||
WCHAR buffer[MAX_PATH];
|
WCHAR buffer[MAX_PATH];
|
||||||
@ -87,10 +67,17 @@ UINT Initialize(HMODULE instance, LPCTSTR iniFile, LPCTSTR section, UINT id)
|
|||||||
g_SettingsFile = PluginBridge(L"getvariable", str.c_str());
|
g_SettingsFile = PluginBridge(L"getvariable", str.c_str());
|
||||||
g_SettingsFile += L"Plugins.ini";
|
g_SettingsFile += L"Plugins.ini";
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
LSLog(LOG_ERROR, L"Rainmeter", L"NowPlayingPlugin: Unable to get path to Plugins.ini.");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Data is stored in two structs: ChildMeasure and ParentMeasure. ParentMeasure is created for measures
|
||||||
|
// with PlayerName=someplayer. ChildMeasure is created for all measures and points to ParentMeasure as
|
||||||
|
// referenced in PlayerName=[section].
|
||||||
|
ChildMeasure* child = new ChildMeasure;
|
||||||
UINT maxValue = 0;
|
UINT maxValue = 0;
|
||||||
MeasureData* data = new MeasureData;
|
|
||||||
|
|
||||||
// Read settings from the ini-file
|
// Read settings from the ini-file
|
||||||
LPCTSTR str = ReadConfigString(section, L"PlayerName", NULL);
|
LPCTSTR str = ReadConfigString(section, L"PlayerName", NULL);
|
||||||
@ -98,36 +85,43 @@ UINT Initialize(HMODULE instance, LPCTSTR iniFile, LPCTSTR section, UINT id)
|
|||||||
{
|
{
|
||||||
if (str[0] == L'[')
|
if (str[0] == L'[')
|
||||||
{
|
{
|
||||||
|
// PlayerName starts with [ so use referenced section
|
||||||
int len = wcslen(str) - 2;
|
int len = wcslen(str) - 2;
|
||||||
if (len > 0)
|
if (len > 0)
|
||||||
{
|
{
|
||||||
MeasureMap::iterator it = g_Values.begin();
|
std::map<UINT, ChildMeasure*>::iterator it = g_Measures.begin();
|
||||||
for ( ; it != g_Values.end(); ++it)
|
for ( ; it != g_Measures.end(); ++it)
|
||||||
{
|
{
|
||||||
if (wcsncmp(&str[1], it->second->section.c_str(), len) == 0 &&
|
if (wcsncmp(&str[1], it->second->parent->name.c_str(), len) == 0 &&
|
||||||
wcscmp(iniFile, it->second->iniFile.c_str()) == 0)
|
wcscmp(iniFile, it->second->parent->iniFile.c_str()) == 0)
|
||||||
{
|
{
|
||||||
// Use same player instance as pointed section
|
// Use same ParentMeasure as referenced section
|
||||||
data->player = it->second->player;
|
child->parent = it->second->parent;
|
||||||
|
++child->parent->childCount;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!data->player)
|
if (!child->parent)
|
||||||
{
|
{
|
||||||
|
// The referenced section doesn't exist
|
||||||
std::wstring error = L"NowPlayingPlugin: PlayerName=";
|
std::wstring error = L"NowPlayingPlugin: PlayerName=";
|
||||||
error += str;
|
error += str;
|
||||||
error += L" in section [";
|
error += L" in [";
|
||||||
error += section;
|
error += section;
|
||||||
error += L"] does not exist.";
|
error += L"] does not exist.";
|
||||||
LSLog(LOG_WARNING, L"Rainmeter", error.c_str());
|
LSLog(LOG_WARNING, L"Rainmeter", error.c_str());
|
||||||
|
delete child;
|
||||||
return maxValue;
|
return maxValue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
data->section = section;
|
// ParentMeasure is created when PlayerName is an actual player (and not a reference)
|
||||||
data->iniFile = iniFile;
|
ParentMeasure* parent = new ParentMeasure;
|
||||||
|
parent->name = section;
|
||||||
|
parent->iniFile = iniFile;
|
||||||
|
|
||||||
if (_wcsicmp(L"AIMP", str) == 0)
|
if (_wcsicmp(L"AIMP", str) == 0)
|
||||||
{
|
{
|
||||||
@ -135,7 +129,7 @@ UINT Initialize(HMODULE instance, LPCTSTR iniFile, LPCTSTR section, UINT id)
|
|||||||
{
|
{
|
||||||
g_AIMP = new CPlayerAIMP();
|
g_AIMP = new CPlayerAIMP();
|
||||||
}
|
}
|
||||||
data->player = g_AIMP;
|
parent->player = g_AIMP;
|
||||||
}
|
}
|
||||||
else if (_wcsicmp(L"CAD", str) == 0)
|
else if (_wcsicmp(L"CAD", str) == 0)
|
||||||
{
|
{
|
||||||
@ -143,7 +137,7 @@ UINT Initialize(HMODULE instance, LPCTSTR iniFile, LPCTSTR section, UINT id)
|
|||||||
{
|
{
|
||||||
g_CAD = new CPlayerCAD();
|
g_CAD = new CPlayerCAD();
|
||||||
}
|
}
|
||||||
data->player = g_CAD;
|
parent->player = g_CAD;
|
||||||
}
|
}
|
||||||
else if (_wcsicmp(L"foobar2000", str) == 0)
|
else if (_wcsicmp(L"foobar2000", str) == 0)
|
||||||
{
|
{
|
||||||
@ -151,7 +145,7 @@ UINT Initialize(HMODULE instance, LPCTSTR iniFile, LPCTSTR section, UINT id)
|
|||||||
{
|
{
|
||||||
g_Foobar = new CPlayerFoobar();
|
g_Foobar = new CPlayerFoobar();
|
||||||
}
|
}
|
||||||
data->player = g_Foobar;
|
parent->player = g_Foobar;
|
||||||
}
|
}
|
||||||
else if (_wcsicmp(L"iTunes", str) == 0)
|
else if (_wcsicmp(L"iTunes", str) == 0)
|
||||||
{
|
{
|
||||||
@ -159,7 +153,7 @@ UINT Initialize(HMODULE instance, LPCTSTR iniFile, LPCTSTR section, UINT id)
|
|||||||
{
|
{
|
||||||
g_iTunes = new CPlayerITunes();
|
g_iTunes = new CPlayerITunes();
|
||||||
}
|
}
|
||||||
data->player = g_iTunes;
|
parent->player = g_iTunes;
|
||||||
}
|
}
|
||||||
else if (_wcsicmp(L"MediaMonkey", str) == 0)
|
else if (_wcsicmp(L"MediaMonkey", str) == 0)
|
||||||
{
|
{
|
||||||
@ -167,7 +161,7 @@ UINT Initialize(HMODULE instance, LPCTSTR iniFile, LPCTSTR section, UINT id)
|
|||||||
{
|
{
|
||||||
g_Winamp = new CPlayerWinamp(WA_MEDIAMONKEY);
|
g_Winamp = new CPlayerWinamp(WA_MEDIAMONKEY);
|
||||||
}
|
}
|
||||||
data->player = g_Winamp;
|
parent->player = g_Winamp;
|
||||||
}
|
}
|
||||||
else if (_wcsicmp(L"Spotify", str) == 0)
|
else if (_wcsicmp(L"Spotify", str) == 0)
|
||||||
{
|
{
|
||||||
@ -175,7 +169,7 @@ UINT Initialize(HMODULE instance, LPCTSTR iniFile, LPCTSTR section, UINT id)
|
|||||||
{
|
{
|
||||||
g_Spotify = new CPlayerSpotify();
|
g_Spotify = new CPlayerSpotify();
|
||||||
}
|
}
|
||||||
data->player = g_Spotify;
|
parent->player = g_Spotify;
|
||||||
}
|
}
|
||||||
else if (_wcsicmp(L"WinAmp", str) == 0)
|
else if (_wcsicmp(L"WinAmp", str) == 0)
|
||||||
{
|
{
|
||||||
@ -183,7 +177,7 @@ UINT Initialize(HMODULE instance, LPCTSTR iniFile, LPCTSTR section, UINT id)
|
|||||||
{
|
{
|
||||||
g_Winamp = new CPlayerWinamp(WA_WINAMP);
|
g_Winamp = new CPlayerWinamp(WA_WINAMP);
|
||||||
}
|
}
|
||||||
data->player = g_Winamp;
|
parent->player = g_Winamp;
|
||||||
}
|
}
|
||||||
else if (_wcsicmp(L"WLM", str) == 0)
|
else if (_wcsicmp(L"WLM", str) == 0)
|
||||||
{
|
{
|
||||||
@ -191,7 +185,7 @@ UINT Initialize(HMODULE instance, LPCTSTR iniFile, LPCTSTR section, UINT id)
|
|||||||
{
|
{
|
||||||
g_WLM = new CPlayerWLM();
|
g_WLM = new CPlayerWLM();
|
||||||
}
|
}
|
||||||
data->player = g_WLM;
|
parent->player = g_WLM;
|
||||||
}
|
}
|
||||||
else if (_wcsicmp(L"WMP", str) == 0)
|
else if (_wcsicmp(L"WMP", str) == 0)
|
||||||
{
|
{
|
||||||
@ -199,7 +193,7 @@ UINT Initialize(HMODULE instance, LPCTSTR iniFile, LPCTSTR section, UINT id)
|
|||||||
{
|
{
|
||||||
g_WMP = new CPlayerWMP();
|
g_WMP = new CPlayerWMP();
|
||||||
}
|
}
|
||||||
data->player = g_WMP;
|
parent->player = g_WMP;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -215,27 +209,31 @@ UINT Initialize(HMODULE instance, LPCTSTR iniFile, LPCTSTR section, UINT id)
|
|||||||
error += section;
|
error += section;
|
||||||
error += L"] is not valid.";
|
error += L"] is not valid.";
|
||||||
LSLog(LOG_ERROR, L"Rainmeter", error.c_str());
|
LSLog(LOG_ERROR, L"Rainmeter", error.c_str());
|
||||||
delete data;
|
delete parent;
|
||||||
|
delete child;
|
||||||
return maxValue;
|
return maxValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
str = ReadConfigString(section, L"PlayerPath", NULL);
|
parent->id = id;
|
||||||
if (str && *str)
|
parent->childCount = 1;
|
||||||
|
parent->player->AddInstance();
|
||||||
|
parent->playerPath = ReadConfigString(section, L"PlayerPath", L"");
|
||||||
|
parent->trackChangeAction = ReadConfigString(section, L"TrackChangeAction", L"");
|
||||||
|
|
||||||
|
if (!parent->trackChangeAction.empty())
|
||||||
{
|
{
|
||||||
data->player->SetPlayerPath(str);
|
// Get window handle to send the bang later on
|
||||||
|
parent->window = FindMeterWindow(parent->iniFile);
|
||||||
|
parent->trackCount = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
str = ReadConfigString(section, L"DisableLeadingZero", NULL);
|
str = ReadConfigString(section, L"DisableLeadingZero", L"0");
|
||||||
if (str && *str)
|
if (str)
|
||||||
{
|
{
|
||||||
g_DisableLeazingZero = (1 == _wtoi(str));
|
parent->disableLeadingZero = (1 == _wtoi(str));
|
||||||
}
|
}
|
||||||
|
|
||||||
str = ReadConfigString(section, L"TrackChangeAction", NULL);
|
child->parent = parent;
|
||||||
if (str && *str)
|
|
||||||
{
|
|
||||||
data->player->SetTrackChangeAction(str);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -244,55 +242,69 @@ UINT Initialize(HMODULE instance, LPCTSTR iniFile, LPCTSTR section, UINT id)
|
|||||||
{
|
{
|
||||||
if (_wcsicmp(L"ARTIST", str) == 0)
|
if (_wcsicmp(L"ARTIST", str) == 0)
|
||||||
{
|
{
|
||||||
data->measure = MEASURE_ARTIST;
|
child->type = MEASURE_ARTIST;
|
||||||
}
|
}
|
||||||
else if (_wcsicmp(L"TITLE", str) == 0)
|
else if (_wcsicmp(L"TITLE", str) == 0)
|
||||||
{
|
{
|
||||||
data->measure = MEASURE_TITLE;
|
child->type = MEASURE_TITLE;
|
||||||
}
|
}
|
||||||
else if (_wcsicmp(L"ALBUM", str) == 0)
|
else if (_wcsicmp(L"ALBUM", str) == 0)
|
||||||
{
|
{
|
||||||
data->measure = MEASURE_ALBUM;
|
child->type = MEASURE_ALBUM;
|
||||||
|
}
|
||||||
|
else if (_wcsicmp(L"LYRICS", str) == 0)
|
||||||
|
{
|
||||||
|
child->type = MEASURE_LYRICS;
|
||||||
}
|
}
|
||||||
else if (_wcsicmp(L"COVER", str) == 0)
|
else if (_wcsicmp(L"COVER", str) == 0)
|
||||||
{
|
{
|
||||||
data->measure = MEASURE_COVER;
|
child->type = MEASURE_COVER;
|
||||||
}
|
}
|
||||||
else if (_wcsicmp(L"DURATION", str) == 0)
|
else if (_wcsicmp(L"DURATION", str) == 0)
|
||||||
{
|
{
|
||||||
data->measure = MEASURE_DURATION;
|
child->type = MEASURE_DURATION;
|
||||||
}
|
}
|
||||||
else if (_wcsicmp(L"POSITION", str) == 0)
|
else if (_wcsicmp(L"POSITION", str) == 0)
|
||||||
{
|
{
|
||||||
data->measure = MEASURE_POSITION;
|
child->type = MEASURE_POSITION;
|
||||||
}
|
}
|
||||||
else if (_wcsicmp(L"PROGRESS", str) == 0)
|
else if (_wcsicmp(L"PROGRESS", str) == 0)
|
||||||
{
|
{
|
||||||
data->measure = MEASURE_PROGRESS;
|
child->type = MEASURE_PROGRESS;
|
||||||
maxValue = 100;
|
maxValue = 100;
|
||||||
}
|
}
|
||||||
else if (_wcsicmp(L"RATING", str) == 0)
|
else if (_wcsicmp(L"RATING", str) == 0)
|
||||||
{
|
{
|
||||||
data->measure = MEASURE_RATING;
|
child->type = MEASURE_RATING;
|
||||||
maxValue = 5;
|
maxValue = 5;
|
||||||
}
|
}
|
||||||
else if (_wcsicmp(L"STATE", str) == 0)
|
else if (_wcsicmp(L"STATE", str) == 0)
|
||||||
{
|
{
|
||||||
data->measure = MEASURE_STATE;
|
child->type = MEASURE_STATE;
|
||||||
}
|
}
|
||||||
else if (_wcsicmp(L"VOLUME", str) == 0)
|
else if (_wcsicmp(L"VOLUME", str) == 0)
|
||||||
{
|
{
|
||||||
data->measure = MEASURE_VOLUME;
|
child->type = MEASURE_VOLUME;
|
||||||
maxValue = 100;
|
maxValue = 100;
|
||||||
}
|
}
|
||||||
else if (_wcsicmp(L"FILE", str) == 0)
|
else if (_wcsicmp(L"FILE", str) == 0)
|
||||||
{
|
{
|
||||||
data->measure = MEASURE_FILE;
|
child->type = MEASURE_FILE;
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
std::wstring error = L"NowPlayingPlugin: PlayerType=";
|
||||||
|
error += str;
|
||||||
|
error += L" in section [";
|
||||||
|
error += section;
|
||||||
|
error += L"] is not valid.";
|
||||||
|
LSLog(LOG_WARNING, L"Rainmeter", error.c_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
child->parent->player->AddMeasure(child->type);
|
||||||
}
|
}
|
||||||
|
|
||||||
data->player->AddInstance(data->measure);
|
g_Measures[id] = child;
|
||||||
g_Values[id] = data;
|
|
||||||
return maxValue;
|
return maxValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -304,16 +316,26 @@ UINT Initialize(HMODULE instance, LPCTSTR iniFile, LPCTSTR section, UINT id)
|
|||||||
*/
|
*/
|
||||||
void Finalize(HMODULE instance, UINT id)
|
void Finalize(HMODULE instance, UINT id)
|
||||||
{
|
{
|
||||||
MeasureMap::iterator i = g_Values.find(id);
|
std::map<UINT, ChildMeasure*>::iterator i = g_Measures.find(id);
|
||||||
if (i != g_Values.end())
|
if (i != g_Measures.end())
|
||||||
{
|
{
|
||||||
(*i).second->player->RemoveInstance();
|
ChildMeasure* child = (*i).second;
|
||||||
delete (*i).second;
|
ParentMeasure* parent = child->parent;
|
||||||
g_Values.erase(i);
|
CPlayer* player = parent->player;
|
||||||
|
|
||||||
|
if (--parent->childCount == 0)
|
||||||
|
{
|
||||||
|
player->RemoveInstance();
|
||||||
|
delete parent;
|
||||||
|
}
|
||||||
|
|
||||||
|
delete child;
|
||||||
|
g_Measures.erase(i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
||||||
** Update
|
** Update
|
||||||
**
|
**
|
||||||
** Called on each update.
|
** Called on each update.
|
||||||
@ -321,18 +343,29 @@ void Finalize(HMODULE instance, UINT id)
|
|||||||
*/
|
*/
|
||||||
UINT Update(UINT id)
|
UINT Update(UINT id)
|
||||||
{
|
{
|
||||||
MeasureMap::iterator i = g_Values.find(id);
|
std::map<UINT, ChildMeasure*>::iterator i = g_Measures.find(id);
|
||||||
if (i != g_Values.end())
|
if (i != g_Measures.end())
|
||||||
{
|
{
|
||||||
if (!(*i).second->section.empty())
|
ChildMeasure* child = (*i).second;
|
||||||
|
ParentMeasure* parent = child->parent;
|
||||||
|
CPlayer* player = parent->player;
|
||||||
|
|
||||||
|
if (parent->id == id)
|
||||||
{
|
{
|
||||||
// Only allow main measure to update
|
player->UpdateMeasure();
|
||||||
(*i).second->player->UpdateData();
|
|
||||||
|
// Execute TrackChangeAction= if necessary
|
||||||
|
if (!parent->trackChangeAction.empty() &&
|
||||||
|
parent->trackCount != player->GetTrackCount())
|
||||||
|
{
|
||||||
|
ExecuteCommand(parent->trackChangeAction, parent->window);
|
||||||
|
|
||||||
|
// TODO: First is true..
|
||||||
|
parent->trackCount = player->GetTrackCount();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
CPlayer* player = (*i).second->player;
|
switch (child->type)
|
||||||
|
|
||||||
switch ((*i).second->measure)
|
|
||||||
{
|
{
|
||||||
case MEASURE_DURATION:
|
case MEASURE_DURATION:
|
||||||
return player->GetDuration();
|
return player->GetDuration();
|
||||||
@ -351,7 +384,7 @@ UINT Update(UINT id)
|
|||||||
return player->GetRating();
|
return player->GetRating();
|
||||||
|
|
||||||
case MEASURE_STATE:
|
case MEASURE_STATE:
|
||||||
return (int)player->GetState();
|
return (UINT)player->GetState();
|
||||||
|
|
||||||
case MEASURE_VOLUME:
|
case MEASURE_VOLUME:
|
||||||
return player->GetVolume();
|
return player->GetVolume();
|
||||||
@ -371,13 +404,15 @@ UINT Update(UINT id)
|
|||||||
*/
|
*/
|
||||||
LPCTSTR GetString(UINT id, UINT flags)
|
LPCTSTR GetString(UINT id, UINT flags)
|
||||||
{
|
{
|
||||||
MeasureMap::iterator i = g_Values.find(id);
|
std::map<UINT, ChildMeasure*>::iterator i = g_Measures.find(id);
|
||||||
if (i != g_Values.end())
|
if (i != g_Measures.end())
|
||||||
{
|
{
|
||||||
CPlayer* player = (*i).second->player;
|
ChildMeasure* child = (*i).second;
|
||||||
|
ParentMeasure* parent = child->parent;
|
||||||
|
CPlayer* player = parent->player;
|
||||||
static WCHAR buffer[32];
|
static WCHAR buffer[32];
|
||||||
|
|
||||||
switch ((*i).second->measure)
|
switch (child->type)
|
||||||
{
|
{
|
||||||
case MEASURE_ARTIST:
|
case MEASURE_ARTIST:
|
||||||
return player->GetArtist();
|
return player->GetArtist();
|
||||||
@ -392,21 +427,16 @@ LPCTSTR GetString(UINT id, UINT flags)
|
|||||||
return player->GetCoverPath();
|
return player->GetCoverPath();
|
||||||
|
|
||||||
case MEASURE_DURATION:
|
case MEASURE_DURATION:
|
||||||
SecondsToTime(player->GetDuration(), buffer);
|
SecondsToTime(player->GetDuration(), parent->disableLeadingZero, buffer);
|
||||||
return buffer;
|
return buffer;
|
||||||
|
|
||||||
case MEASURE_POSITION:
|
case MEASURE_POSITION:
|
||||||
SecondsToTime(player->GetPosition(), buffer);
|
SecondsToTime(player->GetPosition(), parent->disableLeadingZero, buffer);
|
||||||
return buffer;
|
return buffer;
|
||||||
|
|
||||||
case MEASURE_PROGRESS:
|
case MEASURE_PROGRESS:
|
||||||
if (player->GetDuration())
|
_itow(player->GetDuration() ? ((player->GetPosition() * 100) / player->GetDuration()) : 0, buffer, 10);
|
||||||
{
|
return buffer;
|
||||||
int res = (player->GetPosition() * 100) / player->GetDuration();
|
|
||||||
_itow(res, buffer, 10);
|
|
||||||
return buffer;
|
|
||||||
}
|
|
||||||
return L"0";
|
|
||||||
|
|
||||||
case MEASURE_RATING:
|
case MEASURE_RATING:
|
||||||
_itow(player->GetRating(), buffer, 10);
|
_itow(player->GetRating(), buffer, 10);
|
||||||
@ -426,8 +456,7 @@ LPCTSTR GetString(UINT id, UINT flags)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// For invalid PlayerName=
|
return L"Error: Invalid player.";
|
||||||
return L"0";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return L"";
|
return L"";
|
||||||
@ -441,12 +470,21 @@ LPCTSTR GetString(UINT id, UINT flags)
|
|||||||
*/
|
*/
|
||||||
void ExecuteBang(LPCTSTR bang, UINT id)
|
void ExecuteBang(LPCTSTR bang, UINT id)
|
||||||
{
|
{
|
||||||
MeasureMap::iterator i = g_Values.find(id);
|
std::map<UINT, ChildMeasure*>::iterator i = g_Measures.find(id);
|
||||||
if (i != g_Values.end())
|
if (i != g_Measures.end())
|
||||||
{
|
{
|
||||||
CPlayer* player = (*i).second->player;
|
ChildMeasure* child = (*i).second;
|
||||||
|
ParentMeasure* parent = child->parent;
|
||||||
|
CPlayer* player = parent->player;
|
||||||
|
|
||||||
if (_wcsicmp(bang, L"Pause") == 0)
|
if (!player->IsInitialized())
|
||||||
|
{
|
||||||
|
if (_wcsicmp(bang, L"OpenPlayer") == 0 || _wcsicmp(bang, L"TogglePlayer") == 0)
|
||||||
|
{
|
||||||
|
player->OpenPlayer(parent->playerPath);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (_wcsicmp(bang, L"Pause") == 0)
|
||||||
{
|
{
|
||||||
player->Pause();
|
player->Pause();
|
||||||
}
|
}
|
||||||
@ -456,7 +494,7 @@ void ExecuteBang(LPCTSTR bang, UINT id)
|
|||||||
}
|
}
|
||||||
else if (_wcsicmp(bang, L"PlayPause") == 0)
|
else if (_wcsicmp(bang, L"PlayPause") == 0)
|
||||||
{
|
{
|
||||||
player->PlayPause();
|
(player->GetState() != PLAYER_PLAYING) ? player->Play() : player->Pause();
|
||||||
}
|
}
|
||||||
else if (_wcsicmp(bang, L"Stop") == 0)
|
else if (_wcsicmp(bang, L"Stop") == 0)
|
||||||
{
|
{
|
||||||
@ -470,24 +508,18 @@ void ExecuteBang(LPCTSTR bang, UINT id)
|
|||||||
{
|
{
|
||||||
player->Previous();
|
player->Previous();
|
||||||
}
|
}
|
||||||
else if (_wcsicmp(bang, L"ClosePlayer") == 0)
|
else if (_wcsicmp(bang, L"ClosePlayer") == 0 || _wcsicmp(bang, L"TogglePlayer") == 0)
|
||||||
{
|
{
|
||||||
player->ClosePlayer();
|
player->ClosePlayer();
|
||||||
}
|
}
|
||||||
else if (_wcsicmp(bang, L"OpenPlayer") == 0)
|
|
||||||
{
|
|
||||||
player->OpenPlayer();
|
|
||||||
}
|
|
||||||
else if (_wcsicmp(bang, L"TogglePlayer") == 0)
|
|
||||||
{
|
|
||||||
player->TogglePlayer();
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
LPCTSTR arg = wcschr(bang, L' ');
|
LPCTSTR arg = wcschr(bang, L' ');
|
||||||
|
|
||||||
if (++arg) // Skip the space
|
if (arg)
|
||||||
{
|
{
|
||||||
|
++arg; // Skip the space
|
||||||
|
|
||||||
if (wcsnicmp(bang, L"SetPosition", 11) == 0)
|
if (wcsnicmp(bang, L"SetPosition", 11) == 0)
|
||||||
{
|
{
|
||||||
int position = (_wtoi(arg) * player->GetDuration()) / 100;
|
int position = (_wtoi(arg) * player->GetDuration()) / 100;
|
||||||
@ -544,3 +576,71 @@ LPCTSTR GetPluginAuthor()
|
|||||||
{
|
{
|
||||||
return L"Birunthan Mohanathas (www.poiru.net)";
|
return L"Birunthan Mohanathas (www.poiru.net)";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SecondsToTime(UINT seconds, bool leadingZero, WCHAR* buffer)
|
||||||
|
{
|
||||||
|
int hours = seconds;
|
||||||
|
int mins = seconds;
|
||||||
|
hours /= 3600;
|
||||||
|
mins %= 3600;
|
||||||
|
int secs = mins;
|
||||||
|
mins /= 60;
|
||||||
|
secs %= 60;
|
||||||
|
|
||||||
|
if (hours)
|
||||||
|
{
|
||||||
|
_snwprintf_s(buffer, 32, _TRUNCATE, leadingZero ? L"%i:%02i:%02i" : L"%02i:%02i:%02i", hours, mins, secs);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_snwprintf_s(buffer, 32, _TRUNCATE, leadingZero ? L"%i:%02i" : L"%02i:%02i", mins, secs);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ExecuteCommand(std::wstring& command, HWND wnd)
|
||||||
|
{
|
||||||
|
COPYDATASTRUCT cds;
|
||||||
|
cds.dwData = 1;
|
||||||
|
cds.cbData = (DWORD)(command.size() + 1) * sizeof(WCHAR);
|
||||||
|
cds.lpData = (void*)command.c_str();
|
||||||
|
|
||||||
|
// Send bang to the Rainmeter window
|
||||||
|
SendMessage(wnd, WM_COPYDATA, (WPARAM)NULL, (LPARAM)&cds);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool BelongToSameProcess(HWND wnd)
|
||||||
|
{
|
||||||
|
DWORD procId = 0;
|
||||||
|
GetWindowThreadProcessId(wnd, &procId);
|
||||||
|
|
||||||
|
return (procId == GetCurrentProcessId());
|
||||||
|
}
|
||||||
|
|
||||||
|
HWND FindMeterWindow(HWND parent)
|
||||||
|
{
|
||||||
|
HWND wnd = NULL;
|
||||||
|
while (wnd = FindWindowEx(parent, wnd, L"RainmeterMeterWindow", NULL))
|
||||||
|
{
|
||||||
|
if (BelongToSameProcess(wnd))
|
||||||
|
{
|
||||||
|
return wnd;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
HWND FindMeterWindow(const std::wstring& iniFile)
|
||||||
|
{
|
||||||
|
std::wstring str = PluginBridge(L"getconfig", iniFile.c_str());
|
||||||
|
if (!str.empty())
|
||||||
|
{
|
||||||
|
str = PluginBridge(L"getwindow", str.c_str());
|
||||||
|
if (str != L"error")
|
||||||
|
{
|
||||||
|
return (HWND)UlongToPtr(wcstoul(str.c_str(), NULL, 10));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return FindMeterWindow(NULL); // Use old way to find
|
||||||
|
}
|
||||||
|
@ -21,20 +21,36 @@
|
|||||||
|
|
||||||
#include "Player.h"
|
#include "Player.h"
|
||||||
|
|
||||||
struct MeasureData
|
struct ParentMeasure
|
||||||
{
|
{
|
||||||
std::wstring iniFile;
|
UINT id;
|
||||||
std::wstring section;
|
UINT childCount;
|
||||||
MEASURETYPE measure;
|
UINT trackCount;
|
||||||
CPlayer* player;
|
CPlayer* player;
|
||||||
|
HANDLE thread;
|
||||||
|
HWND window;
|
||||||
|
std::wstring name;
|
||||||
|
std::wstring iniFile;
|
||||||
|
std::wstring trackChangeAction;
|
||||||
|
std::wstring playerPath;
|
||||||
|
bool disableLeadingZero;
|
||||||
|
|
||||||
MeasureData() :
|
ParentMeasure() : player(NULL), thread(NULL) {}
|
||||||
player(NULL)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef std::map<UINT, MeasureData*> MeasureMap;
|
struct ChildMeasure
|
||||||
|
{
|
||||||
|
MEASURETYPE type;
|
||||||
|
ParentMeasure* parent;
|
||||||
|
|
||||||
|
ChildMeasure() : parent(NULL) {}
|
||||||
|
};
|
||||||
|
|
||||||
|
void SecondsToTime(UINT seconds, bool leadingZero, WCHAR* buffer);
|
||||||
|
void ExecuteCommand(std::wstring& command, HWND wnd);
|
||||||
|
bool BelongToSameProcess(HWND wnd);
|
||||||
|
HWND FindMeterWindow(HWND parent);
|
||||||
|
HWND FindMeterWindow(const std::wstring& iniFile);
|
||||||
|
|
||||||
/* The exported functions */
|
/* The exported functions */
|
||||||
extern "C"
|
extern "C"
|
||||||
|
@ -16,13 +16,9 @@
|
|||||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
// Common functions for the players
|
|
||||||
|
|
||||||
#include "StdAfx.h"
|
#include "StdAfx.h"
|
||||||
#include "Player.h"
|
#include "Player.h"
|
||||||
|
|
||||||
extern std::wstring g_CachePath;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** CPlayer
|
** CPlayer
|
||||||
**
|
**
|
||||||
@ -30,13 +26,17 @@ extern std::wstring g_CachePath;
|
|||||||
**
|
**
|
||||||
*/
|
*/
|
||||||
CPlayer::CPlayer() :
|
CPlayer::CPlayer() :
|
||||||
|
m_Initialized(false),
|
||||||
|
m_HasCoverMeasure(false),
|
||||||
|
m_HasLyricsMeasure(false),
|
||||||
m_InstanceCount(),
|
m_InstanceCount(),
|
||||||
|
m_UpdateCount(),
|
||||||
|
m_TrackCount(),
|
||||||
m_State(),
|
m_State(),
|
||||||
m_Duration(),
|
m_Duration(),
|
||||||
m_Position(),
|
m_Position(),
|
||||||
m_Rating(),
|
m_Rating(),
|
||||||
m_Volume(),
|
m_Volume()
|
||||||
m_TrackChanged(false)
|
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -51,35 +51,72 @@ CPlayer::~CPlayer()
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** ExecuteTrackChangeAction
|
** AddInstance
|
||||||
**
|
**
|
||||||
** Called from player implementation on track change.
|
** Called during initialization of main measure.
|
||||||
**
|
**
|
||||||
*/
|
*/
|
||||||
void CPlayer::ExecuteTrackChangeAction()
|
void CPlayer::AddInstance()
|
||||||
{
|
{
|
||||||
if (!m_TrackChangeAction.empty())
|
++m_InstanceCount;
|
||||||
{
|
}
|
||||||
HWND wnd = FindWindow(L"RainmeterMeterWindow", NULL);
|
|
||||||
if (wnd != NULL)
|
|
||||||
{
|
|
||||||
COPYDATASTRUCT cds;
|
|
||||||
cds.dwData = 1;
|
|
||||||
cds.cbData = (DWORD)(m_TrackChangeAction.size() + 1) * sizeof(WCHAR);
|
|
||||||
cds.lpData = (void*)m_TrackChangeAction.c_str();
|
|
||||||
|
|
||||||
// Send the bang to the Rainmeter window
|
/*
|
||||||
SendMessage(wnd, WM_COPYDATA, (WPARAM)NULL, (LPARAM)&cds);
|
** RemoveInstance
|
||||||
}
|
**
|
||||||
|
** Called during destruction of main measure.
|
||||||
|
**
|
||||||
|
*/
|
||||||
|
void CPlayer::RemoveInstance()
|
||||||
|
{
|
||||||
|
if (--m_InstanceCount == 0)
|
||||||
|
{
|
||||||
|
delete this;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** ClearInfo
|
** AddMeasure
|
||||||
|
**
|
||||||
|
** Called during initialization of any measure.
|
||||||
|
**
|
||||||
|
*/
|
||||||
|
void CPlayer::AddMeasure(MEASURETYPE measure)
|
||||||
|
{
|
||||||
|
switch (measure)
|
||||||
|
{
|
||||||
|
case MEASURE_LYRICS:
|
||||||
|
m_HasLyricsMeasure = true;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case MEASURE_COVER:
|
||||||
|
m_HasCoverMeasure = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
** UpdateMeasure
|
||||||
|
**
|
||||||
|
** Called during update of main measure.
|
||||||
|
**
|
||||||
|
*/
|
||||||
|
void CPlayer::UpdateMeasure()
|
||||||
|
{
|
||||||
|
if (++m_UpdateCount == m_InstanceCount)
|
||||||
|
{
|
||||||
|
UpdateData();
|
||||||
|
m_UpdateCount = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
** ClearData
|
||||||
**
|
**
|
||||||
** Clear track information.
|
** Clear track information.
|
||||||
**
|
**
|
||||||
*/
|
*/
|
||||||
void CPlayer::ClearInfo()
|
void CPlayer::ClearData()
|
||||||
{
|
{
|
||||||
m_Duration = 0;
|
m_Duration = 0;
|
||||||
m_Position = 0;
|
m_Position = 0;
|
||||||
@ -91,297 +128,3 @@ void CPlayer::ClearInfo()
|
|||||||
m_FilePath.clear();
|
m_FilePath.clear();
|
||||||
m_CoverPath.clear();
|
m_CoverPath.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
** GetCachedArt
|
|
||||||
**
|
|
||||||
** Checks if cover art is in cache.
|
|
||||||
**
|
|
||||||
*/
|
|
||||||
bool CPlayer::GetCachedArt()
|
|
||||||
{
|
|
||||||
m_CoverPath = g_CachePath;
|
|
||||||
if (m_Artist.empty() || m_Title.empty())
|
|
||||||
{
|
|
||||||
m_CoverPath += L"temp.art";
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// Otherwise, save it as "Artist - Title.art"
|
|
||||||
std::wstring name = m_Artist;
|
|
||||||
name += L" - ";
|
|
||||||
name += m_Title;
|
|
||||||
|
|
||||||
// Replace reserved chars with _
|
|
||||||
std::wstring::size_type pos = 0;
|
|
||||||
while ((pos = name.find_first_of(L"\\/:*?\"<>|", pos)) != std::wstring::npos) name[pos] = L'_';
|
|
||||||
|
|
||||||
m_CoverPath += name;
|
|
||||||
m_CoverPath += L".art";
|
|
||||||
if (_waccess(m_CoverPath.c_str(), 0) == 0)
|
|
||||||
{
|
|
||||||
// Art found in cache
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
** GetLocalArt
|
|
||||||
**
|
|
||||||
** Attemps to find local cover art in various formats.
|
|
||||||
**
|
|
||||||
*/
|
|
||||||
bool CPlayer::GetLocalArt(std::wstring& folder, std::wstring filename)
|
|
||||||
{
|
|
||||||
std::wstring testPath = folder;
|
|
||||||
testPath += filename;
|
|
||||||
testPath += L".";
|
|
||||||
std::wstring::size_type origLen = testPath.length();
|
|
||||||
|
|
||||||
const int extCount = 4;
|
|
||||||
LPCTSTR extName[extCount] = { L"jpg", L"jpeg", L"png", L"bmp" };
|
|
||||||
|
|
||||||
for (int i = 0; i < extCount; ++i)
|
|
||||||
{
|
|
||||||
testPath += extName[i];
|
|
||||||
if (_waccess(testPath.c_str(), 0) == 0)
|
|
||||||
{
|
|
||||||
m_CoverPath = testPath;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// Get rid of the added extension
|
|
||||||
testPath.resize(origLen);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
** GetEmbeddedArt
|
|
||||||
**
|
|
||||||
** Attempts to extract cover art from audio files.
|
|
||||||
**
|
|
||||||
*/
|
|
||||||
bool CPlayer::GetEmbeddedArt(const TagLib::FileRef& fr)
|
|
||||||
{
|
|
||||||
bool found = false;
|
|
||||||
|
|
||||||
if (TagLib::MPEG::File* file = dynamic_cast<TagLib::MPEG::File*>(fr.file()))
|
|
||||||
{
|
|
||||||
if (file->ID3v2Tag())
|
|
||||||
{
|
|
||||||
found = GetArtID3(file->ID3v2Tag());
|
|
||||||
}
|
|
||||||
if (!found && file->APETag())
|
|
||||||
{
|
|
||||||
found = GetArtAPE(file->APETag());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (TagLib::MP4::File* file = dynamic_cast<TagLib::MP4::File*>(fr.file()))
|
|
||||||
{
|
|
||||||
if (file->tag())
|
|
||||||
{
|
|
||||||
found = GetArtMP4(file);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (TagLib::FLAC::File* file = dynamic_cast<TagLib::FLAC::File*>(fr.file()))
|
|
||||||
{
|
|
||||||
found = GetArtFLAC(file);
|
|
||||||
|
|
||||||
if (!found && file->ID3v2Tag())
|
|
||||||
{
|
|
||||||
found = GetArtID3(file->ID3v2Tag());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (TagLib::ASF::File* file = dynamic_cast<TagLib::ASF::File*>(fr.file()))
|
|
||||||
{
|
|
||||||
found = GetArtASF(file);
|
|
||||||
}
|
|
||||||
else if (TagLib::APE::File* file = dynamic_cast<TagLib::APE::File*>(fr.file()))
|
|
||||||
{
|
|
||||||
if (file->APETag())
|
|
||||||
{
|
|
||||||
found = GetArtAPE(file->APETag());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (TagLib::MPC::File* file = dynamic_cast<TagLib::MPC::File*>(fr.file()))
|
|
||||||
{
|
|
||||||
if (file->APETag())
|
|
||||||
{
|
|
||||||
found = GetArtAPE(file->APETag());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (TagLib::WavPack::File* file = dynamic_cast<TagLib::WavPack::File*>(fr.file()))
|
|
||||||
{
|
|
||||||
if (file->APETag())
|
|
||||||
{
|
|
||||||
found = GetArtAPE(file->APETag());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return found;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
** GetArtAPE
|
|
||||||
**
|
|
||||||
** Extracts cover art embedded in APE tags.
|
|
||||||
**
|
|
||||||
*/
|
|
||||||
bool CPlayer::GetArtAPE(TagLib::APE::Tag* tag)
|
|
||||||
{
|
|
||||||
bool ret = false;
|
|
||||||
const TagLib::APE::ItemListMap& listMap = tag->itemListMap();
|
|
||||||
|
|
||||||
if (listMap.contains("COVER ART (FRONT)"))
|
|
||||||
{
|
|
||||||
const TagLib::ByteVector nullStringTerminator(1, 0);
|
|
||||||
|
|
||||||
TagLib::ByteVector item = listMap["COVER ART (FRONT)"].value();
|
|
||||||
int pos = item.find(nullStringTerminator); // Skip the filename
|
|
||||||
|
|
||||||
if (++pos > 0)
|
|
||||||
{
|
|
||||||
const TagLib::ByteVector& pic = item.mid(pos);
|
|
||||||
|
|
||||||
FILE* f = _wfopen(m_CoverPath.c_str(), L"wb");
|
|
||||||
if (f)
|
|
||||||
{
|
|
||||||
ret = (fwrite(pic.data(), 1, pic.size(), f) == pic.size());
|
|
||||||
fclose(f);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
** GetArtID3
|
|
||||||
**
|
|
||||||
** Extracts cover art embedded in ID3v2 tags.
|
|
||||||
**
|
|
||||||
*/
|
|
||||||
bool CPlayer::GetArtID3(TagLib::ID3v2::Tag* tag)
|
|
||||||
{
|
|
||||||
bool ret = false;
|
|
||||||
|
|
||||||
const TagLib::ID3v2::FrameList& frameList = tag->frameList("APIC");
|
|
||||||
if (!frameList.isEmpty())
|
|
||||||
{
|
|
||||||
// Grab the first image
|
|
||||||
TagLib::ID3v2::AttachedPictureFrame* frame = static_cast<TagLib::ID3v2::AttachedPictureFrame*>(frameList.front());
|
|
||||||
TagLib::uint size = frame->picture().size();
|
|
||||||
|
|
||||||
if (size > 0)
|
|
||||||
{
|
|
||||||
FILE* f = _wfopen(m_CoverPath.c_str(), L"wb");
|
|
||||||
if (f)
|
|
||||||
{
|
|
||||||
ret = (fwrite(frame->picture().data(), 1, size, f) == size);
|
|
||||||
fclose(f);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
** GetArtASF
|
|
||||||
**
|
|
||||||
** Extracts cover art embedded in ASF/WMA files.
|
|
||||||
**
|
|
||||||
*/
|
|
||||||
bool CPlayer::GetArtASF(TagLib::ASF::File* file)
|
|
||||||
{
|
|
||||||
bool ret = false;
|
|
||||||
|
|
||||||
const TagLib::ASF::AttributeListMap& attrListMap = file->tag()->attributeListMap();
|
|
||||||
|
|
||||||
if (attrListMap.contains("WM/Picture"))
|
|
||||||
{
|
|
||||||
const TagLib::ASF::AttributeList& attrList = attrListMap["WM/Picture"];
|
|
||||||
|
|
||||||
if (!attrList.isEmpty())
|
|
||||||
{
|
|
||||||
// Let's grab the first cover. TODO: Check/loop for correct type
|
|
||||||
TagLib::ASF::Picture wmpic = attrList[0].toPicture();
|
|
||||||
|
|
||||||
if (wmpic.isValid())
|
|
||||||
{
|
|
||||||
FILE* f = _wfopen(m_CoverPath.c_str(), L"wb");
|
|
||||||
if (f)
|
|
||||||
{
|
|
||||||
ret = (fwrite(wmpic.picture().data(), 1, wmpic.picture().size(), f) == wmpic.picture().size());
|
|
||||||
fclose(f);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
** GetArtFLAC
|
|
||||||
**
|
|
||||||
** Extracts cover art embedded in FLAC files.
|
|
||||||
**
|
|
||||||
*/
|
|
||||||
bool CPlayer::GetArtFLAC(TagLib::FLAC::File* file)
|
|
||||||
{
|
|
||||||
bool ret = false;
|
|
||||||
|
|
||||||
const TagLib::List<TagLib::FLAC::Picture*>& picList = file->pictureList();
|
|
||||||
if (!picList.isEmpty())
|
|
||||||
{
|
|
||||||
// Let's grab the first image
|
|
||||||
TagLib::FLAC::Picture* pic = picList[0];
|
|
||||||
|
|
||||||
FILE* f = _wfopen(m_CoverPath.c_str(), L"wb");
|
|
||||||
if (f)
|
|
||||||
{
|
|
||||||
ret = (fwrite(pic->data().data(), 1, pic->data().size(), f) == pic->data().size());
|
|
||||||
fclose(f);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
** GetArtMP4
|
|
||||||
**
|
|
||||||
** Extracts cover art embedded in MP4-like files.
|
|
||||||
**
|
|
||||||
*/
|
|
||||||
bool CPlayer::GetArtMP4(TagLib::MP4::File* file)
|
|
||||||
{
|
|
||||||
bool ret = false;
|
|
||||||
|
|
||||||
TagLib::MP4::Tag* tag = file->tag();
|
|
||||||
if (tag->itemListMap().contains("covr"))
|
|
||||||
{
|
|
||||||
TagLib::MP4::CoverArtList coverList = tag->itemListMap()["covr"].toCoverArtList();
|
|
||||||
TagLib::uint size = coverList[0].data().size();
|
|
||||||
|
|
||||||
if (size > 0)
|
|
||||||
{
|
|
||||||
FILE* f = _wfopen(m_CoverPath.c_str(), L"wb");
|
|
||||||
if (f)
|
|
||||||
{
|
|
||||||
ret = (fwrite(coverList[0].data().data(), 1, size, f) == size);
|
|
||||||
fclose(f);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
@ -19,26 +19,10 @@
|
|||||||
#ifndef __PLAYER_H__
|
#ifndef __PLAYER_H__
|
||||||
#define __PLAYER_H__
|
#define __PLAYER_H__
|
||||||
|
|
||||||
// TagLib
|
|
||||||
#include "apefile.h"
|
|
||||||
#include "apetag.h"
|
|
||||||
#include "asffile.h"
|
|
||||||
#include "attachedpictureframe.h"
|
|
||||||
#include "commentsframe.h"
|
|
||||||
#include "flacfile.h"
|
|
||||||
#include "id3v1genres.h"
|
|
||||||
#include "id3v2tag.h"
|
|
||||||
#include "mpcfile.h"
|
|
||||||
#include "mp4file.h"
|
|
||||||
#include "mpegfile.h"
|
|
||||||
#include "tag.h"
|
#include "tag.h"
|
||||||
#include "taglib.h"
|
#include "Cover.h"
|
||||||
#include "textidentificationframe.h"
|
|
||||||
#include "tstring.h"
|
|
||||||
#include "vorbisfile.h"
|
|
||||||
#include "wavpackfile.h"
|
|
||||||
|
|
||||||
enum PLAYERSTATE
|
enum PLAYSTATE
|
||||||
{
|
{
|
||||||
PLAYER_STOPPED,
|
PLAYER_STOPPED,
|
||||||
PLAYER_PLAYING,
|
PLAYER_PLAYING,
|
||||||
@ -50,6 +34,7 @@ enum MEASURETYPE
|
|||||||
MEASURE_ARTIST,
|
MEASURE_ARTIST,
|
||||||
MEASURE_TITLE,
|
MEASURE_TITLE,
|
||||||
MEASURE_ALBUM,
|
MEASURE_ALBUM,
|
||||||
|
MEASURE_LYRICS,
|
||||||
MEASURE_COVER,
|
MEASURE_COVER,
|
||||||
MEASURE_DURATION,
|
MEASURE_DURATION,
|
||||||
MEASURE_POSITION,
|
MEASURE_POSITION,
|
||||||
@ -60,72 +45,66 @@ enum MEASURETYPE
|
|||||||
MEASURE_FILE
|
MEASURE_FILE
|
||||||
};
|
};
|
||||||
|
|
||||||
class CPlayer
|
class CPlayer :
|
||||||
|
public CCover
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
CPlayer();
|
CPlayer();
|
||||||
virtual ~CPlayer();
|
virtual ~CPlayer() = 0;
|
||||||
|
|
||||||
|
void AddInstance();
|
||||||
|
void RemoveInstance();
|
||||||
|
void UpdateMeasure();
|
||||||
|
virtual void AddMeasure(MEASURETYPE measure);
|
||||||
|
virtual void UpdateData() = 0;
|
||||||
|
|
||||||
|
bool IsInitialized() { return m_Initialized; }
|
||||||
|
UINT GetTrackCount() { return m_TrackCount; }
|
||||||
|
|
||||||
virtual void Pause() {}
|
virtual void Pause() {}
|
||||||
virtual void Play() {}
|
virtual void Play() {}
|
||||||
virtual void PlayPause() {}
|
|
||||||
virtual void Stop() {}
|
virtual void Stop() {}
|
||||||
virtual void Next() {}
|
virtual void Next() {}
|
||||||
virtual void Previous() {}
|
virtual void Previous() {}
|
||||||
virtual void SetPosition(int position) {}
|
virtual void SetPosition(int position) {}
|
||||||
virtual void SetRating(int rating) {}
|
virtual void SetRating(int rating) {}
|
||||||
virtual void SetVolume(int volume) {}
|
virtual void SetVolume(int volume) {}
|
||||||
virtual void OpenPlayer() {}
|
virtual void OpenPlayer(std::wstring& path) {}
|
||||||
virtual void ClosePlayer() {}
|
virtual void ClosePlayer() {}
|
||||||
virtual void TogglePlayer() {}
|
|
||||||
|
|
||||||
virtual void AddInstance(MEASURETYPE type) = 0;
|
PLAYSTATE GetState() { return m_State; }
|
||||||
virtual void RemoveInstance() = 0;
|
|
||||||
virtual void UpdateData() = 0;
|
|
||||||
|
|
||||||
PLAYERSTATE GetState() { return m_State; }
|
|
||||||
LPCTSTR GetArtist() { return m_Artist.c_str(); }
|
LPCTSTR GetArtist() { return m_Artist.c_str(); }
|
||||||
LPCTSTR GetAlbum() { return m_Album.c_str(); }
|
LPCTSTR GetAlbum() { return m_Album.c_str(); }
|
||||||
LPCTSTR GetTitle() { return m_Title.c_str(); }
|
LPCTSTR GetTitle() { return m_Title.c_str(); }
|
||||||
LPCTSTR GetFilePath() { return m_FilePath.c_str(); }
|
LPCTSTR GetLyrics() { return m_Lyrics.c_str(); }
|
||||||
LPCTSTR GetCoverPath() { return m_CoverPath.c_str(); }
|
LPCTSTR GetCoverPath() { return m_CoverPath.c_str(); }
|
||||||
LPCTSTR GetPlayerPath() { return m_PlayerPath.c_str(); }
|
LPCTSTR GetFilePath() { return m_FilePath.c_str(); }
|
||||||
UINT GetDuration() { return m_Duration; }
|
UINT GetDuration() { return m_Duration; }
|
||||||
UINT GetPosition() { return m_Position; }
|
UINT GetPosition() { return m_Position; }
|
||||||
UINT GetRating() { return m_Rating; }
|
UINT GetRating() { return m_Rating; }
|
||||||
UINT GetVolume() { return m_Volume; }
|
UINT GetVolume() { return m_Volume; }
|
||||||
|
|
||||||
void SetPlayerPath(LPCTSTR path) { m_PlayerPath = path; }
|
|
||||||
void SetTrackChangeAction(LPCTSTR action) { m_TrackChangeAction = action; }
|
|
||||||
void ExecuteTrackChangeAction();
|
|
||||||
void ClearInfo();
|
|
||||||
|
|
||||||
bool GetCachedArt();
|
|
||||||
bool GetLocalArt(std::wstring& folder, std::wstring filename);
|
|
||||||
bool GetEmbeddedArt(const TagLib::FileRef& fr);
|
|
||||||
bool GetArtAPE(TagLib::APE::Tag* tag);
|
|
||||||
bool GetArtID3(TagLib::ID3v2::Tag* tag);
|
|
||||||
bool GetArtASF(TagLib::ASF::File* file);
|
|
||||||
bool GetArtFLAC(TagLib::FLAC::File* file);
|
|
||||||
bool GetArtMP4(TagLib::MP4::File* file);
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
int m_InstanceCount;
|
void ClearData();
|
||||||
bool m_TrackChanged;
|
|
||||||
|
|
||||||
PLAYERSTATE m_State;
|
bool m_Initialized;
|
||||||
|
bool m_HasCoverMeasure;
|
||||||
|
bool m_HasLyricsMeasure;
|
||||||
|
UINT m_InstanceCount;
|
||||||
|
UINT m_UpdateCount;
|
||||||
|
UINT m_TrackCount;
|
||||||
|
|
||||||
|
PLAYSTATE m_State;
|
||||||
std::wstring m_Artist;
|
std::wstring m_Artist;
|
||||||
std::wstring m_Album;
|
|
||||||
std::wstring m_Title;
|
std::wstring m_Title;
|
||||||
std::wstring m_FilePath; // Path to playing file
|
std::wstring m_Album;
|
||||||
|
std::wstring m_Lyrics;
|
||||||
std::wstring m_CoverPath; // Path to cover art image
|
std::wstring m_CoverPath; // Path to cover art image
|
||||||
std::wstring m_PlayerPath; // Path to player executable
|
std::wstring m_FilePath; // Path to playing file
|
||||||
UINT m_Duration; // Track duration in seconds
|
UINT m_Duration; // Track duration in seconds
|
||||||
UINT m_Position; // Current position in seconds
|
UINT m_Position; // Current position in seconds
|
||||||
UINT m_Rating; // Track rating from 0 to 100
|
UINT m_Rating; // Track rating from 0 to 100
|
||||||
UINT m_Volume; // Volume from 0 to 100
|
UINT m_Volume; // Volume from 0 to 100
|
||||||
|
|
||||||
std::wstring m_TrackChangeAction;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
@ -30,7 +30,6 @@ extern CPlayer* g_AIMP;
|
|||||||
**
|
**
|
||||||
*/
|
*/
|
||||||
CPlayerAIMP::CPlayerAIMP() : CPlayer(),
|
CPlayerAIMP::CPlayerAIMP() : CPlayer(),
|
||||||
m_HasCoverMeasure(false),
|
|
||||||
m_FileMap(),
|
m_FileMap(),
|
||||||
m_FileMapHandle(),
|
m_FileMapHandle(),
|
||||||
m_Window(),
|
m_Window(),
|
||||||
@ -46,41 +45,17 @@ CPlayerAIMP::CPlayerAIMP() : CPlayer(),
|
|||||||
*/
|
*/
|
||||||
CPlayerAIMP::~CPlayerAIMP()
|
CPlayerAIMP::~CPlayerAIMP()
|
||||||
{
|
{
|
||||||
|
g_AIMP = NULL;
|
||||||
if (m_FileMap) UnmapViewOfFile(m_FileMap);
|
if (m_FileMap) UnmapViewOfFile(m_FileMap);
|
||||||
if (m_FileMapHandle) CloseHandle(m_FileMapHandle);
|
if (m_FileMapHandle) CloseHandle(m_FileMapHandle);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** AddInstance
|
** Initialize
|
||||||
**
|
**
|
||||||
** Called during initialization of each measure.
|
** Find AIMP window and mapped object.
|
||||||
**
|
**
|
||||||
*/
|
*/
|
||||||
void CPlayerAIMP::AddInstance(MEASURETYPE type)
|
|
||||||
{
|
|
||||||
++m_InstanceCount;
|
|
||||||
|
|
||||||
if (type == MEASURE_COVER)
|
|
||||||
{
|
|
||||||
m_HasCoverMeasure = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
** RemoveInstance
|
|
||||||
**
|
|
||||||
** Called during destruction of each measure.
|
|
||||||
**
|
|
||||||
*/
|
|
||||||
void CPlayerAIMP::RemoveInstance()
|
|
||||||
{
|
|
||||||
if (--m_InstanceCount == 0)
|
|
||||||
{
|
|
||||||
g_AIMP = NULL;
|
|
||||||
delete this;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool CPlayerAIMP::Initialize()
|
bool CPlayerAIMP::Initialize()
|
||||||
{
|
{
|
||||||
m_Window = FindWindow(L"AIMP2_RemoteInfo", L"AIMP2_RemoteInfo");
|
m_Window = FindWindow(L"AIMP2_RemoteInfo", L"AIMP2_RemoteInfo");
|
||||||
@ -118,7 +93,7 @@ bool CPlayerAIMP::CheckActive()
|
|||||||
m_WinampWindow = NULL;
|
m_WinampWindow = NULL;
|
||||||
if (m_FileMap) UnmapViewOfFile(m_FileMap);
|
if (m_FileMap) UnmapViewOfFile(m_FileMap);
|
||||||
if (m_FileMapHandle) CloseHandle(m_FileMapHandle);
|
if (m_FileMapHandle) CloseHandle(m_FileMapHandle);
|
||||||
ClearInfo();
|
ClearData();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -162,24 +137,18 @@ void CPlayerAIMP::UpdateData()
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_State = (PLAYERSTATE)SendMessage(m_Window, WM_AIMP_COMMAND, WM_AIMP_STATUS_GET, AIMP_STS_Player);
|
m_State = (PLAYSTATE)SendMessage(m_Window, WM_AIMP_COMMAND, WM_AIMP_STATUS_GET, AIMP_STS_Player);
|
||||||
if (m_State == PLAYER_STOPPED)
|
if (m_State == PLAYER_STOPPED)
|
||||||
{
|
{
|
||||||
if (oldFileSize != 0)
|
if (oldFileSize != 0)
|
||||||
{
|
{
|
||||||
oldFileSize = 0;
|
oldFileSize = 0;
|
||||||
oldTitleLen = 0;
|
oldTitleLen = 0;
|
||||||
ClearInfo();
|
ClearData();
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_TrackChanged)
|
|
||||||
{
|
|
||||||
ExecuteTrackChangeAction();
|
|
||||||
m_TrackChanged = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
m_Position = SendMessage(m_Window, WM_AIMP_COMMAND, WM_AIMP_STATUS_GET, AIMP_STS_POS);
|
m_Position = SendMessage(m_Window, WM_AIMP_COMMAND, WM_AIMP_STATUS_GET, AIMP_STS_POS);
|
||||||
m_Volume = SendMessage(m_Window, WM_AIMP_COMMAND, WM_AIMP_STATUS_GET, AIMP_STS_VOLUME);
|
m_Volume = SendMessage(m_Window, WM_AIMP_COMMAND, WM_AIMP_STATUS_GET, AIMP_STS_VOLUME);
|
||||||
|
|
||||||
@ -217,37 +186,12 @@ void CPlayerAIMP::UpdateData()
|
|||||||
if (filepath != m_FilePath)
|
if (filepath != m_FilePath)
|
||||||
{
|
{
|
||||||
m_FilePath = filepath;
|
m_FilePath = filepath;
|
||||||
m_TrackChanged = true;
|
++m_TrackCount;
|
||||||
|
|
||||||
|
// Find cover if needed
|
||||||
if (m_HasCoverMeasure)
|
if (m_HasCoverMeasure)
|
||||||
{
|
{
|
||||||
if (GetCachedArt())
|
GetCover(m_Artist, m_Title, m_FilePath, m_CoverPath);
|
||||||
{
|
|
||||||
// Cover is in cache, lets use the that
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
TagLib::FileRef fr(m_FilePath.c_str());
|
|
||||||
if (!fr.isNull() && fr.tag() && GetEmbeddedArt(fr))
|
|
||||||
{
|
|
||||||
// Embedded art found
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get rid of the name and extension from filename
|
|
||||||
std::wstring trackFolder = m_FilePath;
|
|
||||||
std::wstring::size_type pos = trackFolder.find_last_of(L'\\');
|
|
||||||
if (pos == std::wstring::npos) return;
|
|
||||||
trackFolder.resize(++pos);
|
|
||||||
|
|
||||||
if (GetLocalArt(trackFolder, L"cover") || GetLocalArt(trackFolder, L"folder"))
|
|
||||||
{
|
|
||||||
// Local art found
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Nothing found
|
|
||||||
m_CoverPath.clear();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -261,10 +205,7 @@ void CPlayerAIMP::UpdateData()
|
|||||||
*/
|
*/
|
||||||
void CPlayerAIMP::Pause()
|
void CPlayerAIMP::Pause()
|
||||||
{
|
{
|
||||||
if (m_Window)
|
SendMessage(m_Window, WM_AIMP_COMMAND, WM_AIMP_CALLFUNC, AIMP_PAUSE);
|
||||||
{
|
|
||||||
SendMessage(m_Window, WM_AIMP_COMMAND, WM_AIMP_CALLFUNC, AIMP_PAUSE);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -275,21 +216,7 @@ void CPlayerAIMP::Pause()
|
|||||||
*/
|
*/
|
||||||
void CPlayerAIMP::Play()
|
void CPlayerAIMP::Play()
|
||||||
{
|
{
|
||||||
if (m_Window)
|
SendMessage(m_Window, WM_AIMP_COMMAND, WM_AIMP_CALLFUNC, AIMP_PLAY);
|
||||||
{
|
|
||||||
SendMessage(m_Window, WM_AIMP_COMMAND, WM_AIMP_CALLFUNC, AIMP_PLAY);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
** PlayPause
|
|
||||||
**
|
|
||||||
** Handles the PlayPause bang.
|
|
||||||
**
|
|
||||||
*/
|
|
||||||
void CPlayerAIMP::PlayPause()
|
|
||||||
{
|
|
||||||
(m_State == PLAYER_STOPPED) ? Play() : Pause();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -300,10 +227,7 @@ void CPlayerAIMP::PlayPause()
|
|||||||
*/
|
*/
|
||||||
void CPlayerAIMP::Stop()
|
void CPlayerAIMP::Stop()
|
||||||
{
|
{
|
||||||
if (m_Window)
|
SendMessage(m_Window, WM_AIMP_COMMAND, WM_AIMP_CALLFUNC, AIMP_STOP);
|
||||||
{
|
|
||||||
SendMessage(m_Window, WM_AIMP_COMMAND, WM_AIMP_CALLFUNC, AIMP_STOP);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -314,10 +238,7 @@ void CPlayerAIMP::Stop()
|
|||||||
*/
|
*/
|
||||||
void CPlayerAIMP::Next()
|
void CPlayerAIMP::Next()
|
||||||
{
|
{
|
||||||
if (m_Window)
|
SendMessage(m_Window, WM_AIMP_COMMAND, WM_AIMP_CALLFUNC, AIMP_NEXT);
|
||||||
{
|
|
||||||
SendMessage(m_Window, WM_AIMP_COMMAND, WM_AIMP_CALLFUNC, AIMP_NEXT);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -328,10 +249,7 @@ void CPlayerAIMP::Next()
|
|||||||
*/
|
*/
|
||||||
void CPlayerAIMP::Previous()
|
void CPlayerAIMP::Previous()
|
||||||
{
|
{
|
||||||
if (m_Window)
|
SendMessage(m_Window, WM_AIMP_COMMAND, WM_AIMP_CALLFUNC, AIMP_PREV);
|
||||||
{
|
|
||||||
SendMessage(m_Window, WM_AIMP_COMMAND, WM_AIMP_CALLFUNC, AIMP_PREV);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -354,7 +272,7 @@ void CPlayerAIMP::SetPosition(int position)
|
|||||||
void CPlayerAIMP::SetRating(int rating)
|
void CPlayerAIMP::SetRating(int rating)
|
||||||
{
|
{
|
||||||
// Set rating through the AIMP Winamp API
|
// Set rating through the AIMP Winamp API
|
||||||
if (m_WinampWindow && (m_State == PLAYER_PLAYING || m_State == PLAYER_PAUSED))
|
if (m_State != PLAYER_STOPPED)
|
||||||
{
|
{
|
||||||
if (rating < 0)
|
if (rating < 0)
|
||||||
{
|
{
|
||||||
@ -389,10 +307,7 @@ void CPlayerAIMP::SetVolume(int volume)
|
|||||||
*/
|
*/
|
||||||
void CPlayerAIMP::ClosePlayer()
|
void CPlayerAIMP::ClosePlayer()
|
||||||
{
|
{
|
||||||
if (m_Window)
|
SendMessage(m_Window, WM_CLOSE, 0, 0);
|
||||||
{
|
|
||||||
SendMessage(m_Window, WM_CLOSE, 0, 0);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -401,9 +316,9 @@ void CPlayerAIMP::ClosePlayer()
|
|||||||
** Handles the OpenPlayer bang.
|
** Handles the OpenPlayer bang.
|
||||||
**
|
**
|
||||||
*/
|
*/
|
||||||
void CPlayerAIMP::OpenPlayer()
|
void CPlayerAIMP::OpenPlayer(std::wstring& path)
|
||||||
{
|
{
|
||||||
if (m_PlayerPath.empty())
|
if (path.empty())
|
||||||
{
|
{
|
||||||
// Check for AIMP2 first
|
// Check for AIMP2 first
|
||||||
DWORD size = 512;
|
DWORD size = 512;
|
||||||
@ -427,7 +342,7 @@ void CPlayerAIMP::OpenPlayer()
|
|||||||
if (type == REG_SZ)
|
if (type == REG_SZ)
|
||||||
{
|
{
|
||||||
ShellExecute(NULL, L"open", data, NULL, NULL, SW_SHOW);
|
ShellExecute(NULL, L"open", data, NULL, NULL, SW_SHOW);
|
||||||
m_PlayerPath = data;
|
path = data;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -449,11 +364,10 @@ void CPlayerAIMP::OpenPlayer()
|
|||||||
{
|
{
|
||||||
if (type == REG_SZ)
|
if (type == REG_SZ)
|
||||||
{
|
{
|
||||||
std::wstring path = data;
|
path = data;
|
||||||
path.resize(path.find_last_of(L'\\') + 1);
|
path.resize(path.find_last_of(L'\\') + 1);
|
||||||
path += L"AIMP3.exe";
|
path += L"AIMP3.exe";
|
||||||
ShellExecute(NULL, L"open", path.c_str(), NULL, NULL, SW_SHOW);
|
ShellExecute(NULL, L"open", path.c_str(), NULL, NULL, SW_SHOW);
|
||||||
m_PlayerPath = path;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -463,17 +377,6 @@ void CPlayerAIMP::OpenPlayer()
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
ShellExecute(NULL, L"open", m_PlayerPath.c_str(), NULL, NULL, SW_SHOW);
|
ShellExecute(NULL, L"open", path.c_str(), NULL, NULL, SW_SHOW);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
** TogglePlayer
|
|
||||||
**
|
|
||||||
** Handles the TogglePlayer bang.
|
|
||||||
**
|
|
||||||
*/
|
|
||||||
void CPlayerAIMP::TogglePlayer()
|
|
||||||
{
|
|
||||||
m_Window ? ClosePlayer() : OpenPlayer();
|
|
||||||
}
|
|
||||||
|
@ -27,9 +27,10 @@ public:
|
|||||||
CPlayerAIMP();
|
CPlayerAIMP();
|
||||||
~CPlayerAIMP();
|
~CPlayerAIMP();
|
||||||
|
|
||||||
|
virtual void UpdateData();
|
||||||
|
|
||||||
virtual void Pause();
|
virtual void Pause();
|
||||||
virtual void Play();
|
virtual void Play();
|
||||||
virtual void PlayPause();
|
|
||||||
virtual void Stop();
|
virtual void Stop();
|
||||||
virtual void Next();
|
virtual void Next();
|
||||||
virtual void Previous();
|
virtual void Previous();
|
||||||
@ -37,18 +38,12 @@ public:
|
|||||||
virtual void SetRating(int rating);
|
virtual void SetRating(int rating);
|
||||||
virtual void SetVolume(int volume);
|
virtual void SetVolume(int volume);
|
||||||
virtual void ClosePlayer();
|
virtual void ClosePlayer();
|
||||||
virtual void OpenPlayer();
|
virtual void OpenPlayer(std::wstring& path);
|
||||||
virtual void TogglePlayer();
|
|
||||||
|
|
||||||
virtual void AddInstance(MEASURETYPE type);
|
|
||||||
virtual void RemoveInstance();
|
|
||||||
virtual void UpdateData();
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool Initialize();
|
bool Initialize();
|
||||||
bool CheckActive();
|
bool CheckActive();
|
||||||
|
|
||||||
bool m_HasCoverMeasure;
|
|
||||||
LPVOID m_FileMap;
|
LPVOID m_FileMap;
|
||||||
HANDLE m_FileMapHandle;
|
HANDLE m_FileMapHandle;
|
||||||
HWND m_Window; // AIMP window
|
HWND m_Window; // AIMP window
|
||||||
|
@ -33,7 +33,6 @@ extern std::wstring g_SettingsFile;
|
|||||||
**
|
**
|
||||||
*/
|
*/
|
||||||
CPlayerCAD::CPlayerCAD() : CPlayer(),
|
CPlayerCAD::CPlayerCAD() : CPlayer(),
|
||||||
m_HasCoverMeasure(false),
|
|
||||||
m_Window(),
|
m_Window(),
|
||||||
m_PlayerWindow()
|
m_PlayerWindow()
|
||||||
{
|
{
|
||||||
@ -48,40 +47,10 @@ CPlayerCAD::CPlayerCAD() : CPlayer(),
|
|||||||
*/
|
*/
|
||||||
CPlayerCAD::~CPlayerCAD()
|
CPlayerCAD::~CPlayerCAD()
|
||||||
{
|
{
|
||||||
|
g_CAD = NULL;
|
||||||
Uninitialize();
|
Uninitialize();
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
** AddInstance
|
|
||||||
**
|
|
||||||
** Called during initialization of each measure.
|
|
||||||
**
|
|
||||||
*/
|
|
||||||
void CPlayerCAD::AddInstance(MEASURETYPE type)
|
|
||||||
{
|
|
||||||
++m_InstanceCount;
|
|
||||||
|
|
||||||
if (type == MEASURE_COVER)
|
|
||||||
{
|
|
||||||
m_HasCoverMeasure = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
** RemoveInstance
|
|
||||||
**
|
|
||||||
** Called during destruction of each measure.
|
|
||||||
**
|
|
||||||
*/
|
|
||||||
void CPlayerCAD::RemoveInstance()
|
|
||||||
{
|
|
||||||
if (--m_InstanceCount == 0)
|
|
||||||
{
|
|
||||||
g_CAD = NULL;
|
|
||||||
delete this;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** Initialize
|
** Initialize
|
||||||
**
|
**
|
||||||
@ -145,7 +114,7 @@ void CPlayerCAD::Initialize()
|
|||||||
if (m_PlayerWindow)
|
if (m_PlayerWindow)
|
||||||
{
|
{
|
||||||
SendMessage(m_PlayerWindow, WM_USER, (WPARAM)m_Window, IPC_SET_CALLBACK_HWND);
|
SendMessage(m_PlayerWindow, WM_USER, (WPARAM)m_Window, IPC_SET_CALLBACK_HWND);
|
||||||
m_State = (PLAYERSTATE)SendMessage(m_PlayerWindow, WM_USER, 0, IPC_GET_PLAYER_STATE);
|
m_State = (PLAYSTATE)SendMessage(m_PlayerWindow, WM_USER, 0, IPC_GET_PLAYER_STATE);
|
||||||
|
|
||||||
if (m_State != PLAYER_STOPPED)
|
if (m_State != PLAYER_STOPPED)
|
||||||
{
|
{
|
||||||
@ -195,16 +164,16 @@ LRESULT CALLBACK CPlayerCAD::WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case IPC_PLAYER_STATE_CHANGED_NOTIFICATION:
|
case IPC_PLAYER_STATE_CHANGED_NOTIFICATION:
|
||||||
p->m_State = (PLAYERSTATE)wParam;
|
p->m_State = (PLAYSTATE)wParam;
|
||||||
if (p->m_State == PLAYER_STOPPED)
|
if (p->m_State == PLAYER_STOPPED)
|
||||||
{
|
{
|
||||||
p->ClearInfo();
|
p->ClearData();
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case IPC_SHUTDOWN_NOTIFICATION:
|
case IPC_SHUTDOWN_NOTIFICATION:
|
||||||
p->m_PlayerWindow = NULL;
|
p->m_PlayerWindow = NULL;
|
||||||
p->ClearInfo();
|
p->ClearData();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
@ -214,7 +183,9 @@ LRESULT CALLBACK CPlayerCAD::WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM
|
|||||||
PCOPYDATASTRUCT cds = (PCOPYDATASTRUCT)lParam;
|
PCOPYDATASTRUCT cds = (PCOPYDATASTRUCT)lParam;
|
||||||
if (cds->dwData == IPC_CURRENT_TRACK_INFO)
|
if (cds->dwData == IPC_CURRENT_TRACK_INFO)
|
||||||
{
|
{
|
||||||
p->m_TrackChanged = true;
|
// TODO: Sent on track update?
|
||||||
|
++p->m_TrackCount;
|
||||||
|
|
||||||
std::wstring data = (WCHAR*)cds->lpData;
|
std::wstring data = (WCHAR*)cds->lpData;
|
||||||
std::wstring::size_type len = data.find_first_of(L'\t');
|
std::wstring::size_type len = data.find_first_of(L'\t');
|
||||||
p->m_Title.assign(data, 0, len);
|
p->m_Title.assign(data, 0, len);
|
||||||
@ -282,7 +253,7 @@ LRESULT CALLBACK CPlayerCAD::WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM
|
|||||||
|
|
||||||
if (p->m_PlayerWindow)
|
if (p->m_PlayerWindow)
|
||||||
{
|
{
|
||||||
p->m_State = (PLAYERSTATE)SendMessage(p->m_PlayerWindow, WM_USER, 0, IPC_GET_PLAYER_STATE);
|
p->m_State = (PLAYSTATE)SendMessage(p->m_PlayerWindow, WM_USER, 0, IPC_GET_PLAYER_STATE);
|
||||||
|
|
||||||
if (p->m_State != PLAYER_STOPPED)
|
if (p->m_State != PLAYER_STOPPED)
|
||||||
{
|
{
|
||||||
@ -311,12 +282,6 @@ void CPlayerCAD::UpdateData()
|
|||||||
{
|
{
|
||||||
m_Position = SendMessage(m_PlayerWindow, WM_USER, 0, IPC_GET_POSITION);
|
m_Position = SendMessage(m_PlayerWindow, WM_USER, 0, IPC_GET_POSITION);
|
||||||
m_Volume = SendMessage(m_PlayerWindow, WM_USER, 0, IPC_GET_VOLUME);
|
m_Volume = SendMessage(m_PlayerWindow, WM_USER, 0, IPC_GET_VOLUME);
|
||||||
|
|
||||||
if (m_TrackChanged)
|
|
||||||
{
|
|
||||||
ExecuteTrackChangeAction();
|
|
||||||
m_TrackChanged = false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -328,10 +293,7 @@ void CPlayerCAD::UpdateData()
|
|||||||
*/
|
*/
|
||||||
void CPlayerCAD::Pause()
|
void CPlayerCAD::Pause()
|
||||||
{
|
{
|
||||||
if (m_PlayerWindow)
|
SendMessage(m_PlayerWindow, WM_USER, 0, IPC_FORCEPAUSE);
|
||||||
{
|
|
||||||
SendMessage(m_PlayerWindow, WM_USER, 0, IPC_FORCEPAUSE);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -342,25 +304,7 @@ void CPlayerCAD::Pause()
|
|||||||
*/
|
*/
|
||||||
void CPlayerCAD::Play()
|
void CPlayerCAD::Play()
|
||||||
{
|
{
|
||||||
if (m_PlayerWindow)
|
SendMessage(m_PlayerWindow, WM_USER, 0, IPC_PLAY);
|
||||||
{
|
|
||||||
SendMessage(m_PlayerWindow, WM_USER, 0, IPC_PLAY);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
** PlayPause
|
|
||||||
**
|
|
||||||
** Handles the PlayPause bang.
|
|
||||||
**
|
|
||||||
*/
|
|
||||||
void CPlayerCAD::PlayPause()
|
|
||||||
{
|
|
||||||
if (m_PlayerWindow)
|
|
||||||
{
|
|
||||||
SendMessage(m_PlayerWindow, WM_USER, 0, IPC_PLAYPAUSE);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -371,10 +315,7 @@ void CPlayerCAD::PlayPause()
|
|||||||
*/
|
*/
|
||||||
void CPlayerCAD::Stop()
|
void CPlayerCAD::Stop()
|
||||||
{
|
{
|
||||||
if (m_PlayerWindow)
|
SendMessage(m_PlayerWindow, WM_USER, 0, IPC_STOP);
|
||||||
{
|
|
||||||
SendMessage(m_PlayerWindow, WM_USER, 0, IPC_STOP);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -385,10 +326,7 @@ void CPlayerCAD::Stop()
|
|||||||
*/
|
*/
|
||||||
void CPlayerCAD::Next()
|
void CPlayerCAD::Next()
|
||||||
{
|
{
|
||||||
if (m_PlayerWindow)
|
SendMessage(m_PlayerWindow, WM_USER, 0, IPC_NEXT);
|
||||||
{
|
|
||||||
SendMessage(m_PlayerWindow, WM_USER, 0, IPC_NEXT);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -399,10 +337,7 @@ void CPlayerCAD::Next()
|
|||||||
*/
|
*/
|
||||||
void CPlayerCAD::Previous()
|
void CPlayerCAD::Previous()
|
||||||
{
|
{
|
||||||
if (m_PlayerWindow)
|
SendMessage(m_PlayerWindow, WM_USER, 0, IPC_PREVIOUS);
|
||||||
{
|
|
||||||
SendMessage(m_PlayerWindow, WM_USER, 0, IPC_PREVIOUS);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -424,12 +359,9 @@ void CPlayerCAD::SetPosition(int position)
|
|||||||
*/
|
*/
|
||||||
void CPlayerCAD::SetRating(int rating)
|
void CPlayerCAD::SetRating(int rating)
|
||||||
{
|
{
|
||||||
if (m_PlayerWindow)
|
m_Rating = rating;
|
||||||
{
|
rating *= 2; // From 0 - 5 to 0 - 10
|
||||||
m_Rating = rating;
|
SendMessage(m_PlayerWindow, WM_USER, rating, IPC_RATING_CHANGED_NOTIFICATION);
|
||||||
rating *= 2; // From 0 - 5 to 0 - 10
|
|
||||||
SendMessage(m_PlayerWindow, WM_USER, rating, IPC_RATING_CHANGED_NOTIFICATION);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -440,18 +372,15 @@ void CPlayerCAD::SetRating(int rating)
|
|||||||
*/
|
*/
|
||||||
void CPlayerCAD::SetVolume(int volume)
|
void CPlayerCAD::SetVolume(int volume)
|
||||||
{
|
{
|
||||||
if (m_PlayerWindow)
|
if (volume < 0)
|
||||||
{
|
{
|
||||||
if (volume < 0)
|
volume = 0;
|
||||||
{
|
|
||||||
volume = 0;
|
|
||||||
}
|
|
||||||
else if (volume > 100)
|
|
||||||
{
|
|
||||||
volume = 100;
|
|
||||||
}
|
|
||||||
SendMessage(m_PlayerWindow, WM_USER, volume, IPC_SET_VOLUME);
|
|
||||||
}
|
}
|
||||||
|
else if (volume > 100)
|
||||||
|
{
|
||||||
|
volume = 100;
|
||||||
|
}
|
||||||
|
SendMessage(m_PlayerWindow, WM_USER, volume, IPC_SET_VOLUME);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -464,7 +393,7 @@ void CPlayerCAD::ClosePlayer()
|
|||||||
{
|
{
|
||||||
SendMessage(m_PlayerWindow, WM_USER, 0, IPC_CLOSE_PLAYER);
|
SendMessage(m_PlayerWindow, WM_USER, 0, IPC_CLOSE_PLAYER);
|
||||||
m_PlayerWindow = NULL;
|
m_PlayerWindow = NULL;
|
||||||
ClearInfo();
|
ClearData();
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -473,21 +402,14 @@ void CPlayerCAD::ClosePlayer()
|
|||||||
** Handles the OpenPlayer bang.
|
** Handles the OpenPlayer bang.
|
||||||
**
|
**
|
||||||
*/
|
*/
|
||||||
void CPlayerCAD::OpenPlayer()
|
void CPlayerCAD::OpenPlayer(std::wstring& path)
|
||||||
{
|
{
|
||||||
if (!m_PlayerPath.empty())
|
if (!path.empty())
|
||||||
|
{
|
||||||
|
ShellExecute(NULL, L"open", path.c_str(), NULL, NULL, SW_SHOW);
|
||||||
|
}
|
||||||
|
else if (!m_PlayerPath.empty())
|
||||||
{
|
{
|
||||||
ShellExecute(NULL, L"open", m_PlayerPath.c_str(), NULL, NULL, SW_SHOW);
|
ShellExecute(NULL, L"open", m_PlayerPath.c_str(), NULL, NULL, SW_SHOW);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
** TogglePlayer
|
|
||||||
**
|
|
||||||
** Handles the TogglePlayer bang.
|
|
||||||
**
|
|
||||||
*/
|
|
||||||
void CPlayerCAD::TogglePlayer()
|
|
||||||
{
|
|
||||||
m_PlayerWindow ? ClosePlayer() : OpenPlayer();
|
|
||||||
}
|
|
||||||
|
@ -27,9 +27,10 @@ public:
|
|||||||
CPlayerCAD();
|
CPlayerCAD();
|
||||||
~CPlayerCAD();
|
~CPlayerCAD();
|
||||||
|
|
||||||
|
virtual void UpdateData();
|
||||||
|
|
||||||
virtual void Pause();
|
virtual void Pause();
|
||||||
virtual void Play();
|
virtual void Play();
|
||||||
virtual void PlayPause();
|
|
||||||
virtual void Stop();
|
virtual void Stop();
|
||||||
virtual void Next();
|
virtual void Next();
|
||||||
virtual void Previous();
|
virtual void Previous();
|
||||||
@ -37,21 +38,16 @@ public:
|
|||||||
virtual void SetRating(int rating);
|
virtual void SetRating(int rating);
|
||||||
virtual void SetVolume(int volume);
|
virtual void SetVolume(int volume);
|
||||||
virtual void ClosePlayer();
|
virtual void ClosePlayer();
|
||||||
virtual void OpenPlayer();
|
virtual void OpenPlayer(std::wstring& path);
|
||||||
virtual void TogglePlayer();
|
|
||||||
|
|
||||||
virtual void AddInstance(MEASURETYPE type);
|
|
||||||
virtual void RemoveInstance();
|
|
||||||
virtual void UpdateData();
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void Initialize();
|
void Initialize();
|
||||||
void Uninitialize();
|
void Uninitialize();
|
||||||
static LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);
|
static LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);
|
||||||
|
|
||||||
bool m_HasCoverMeasure;
|
|
||||||
HWND m_Window;
|
HWND m_Window;
|
||||||
HWND m_PlayerWindow;
|
HWND m_PlayerWindow;
|
||||||
|
std::wstring m_PlayerPath;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -28,7 +28,6 @@ extern CPlayer* g_Foobar;
|
|||||||
**
|
**
|
||||||
*/
|
*/
|
||||||
CPlayerFoobar::CPlayerFoobar() : CPlayer(),
|
CPlayerFoobar::CPlayerFoobar() : CPlayer(),
|
||||||
m_HasCoverMeasure(false),
|
|
||||||
m_Window(),
|
m_Window(),
|
||||||
m_FooWindow()
|
m_FooWindow()
|
||||||
{
|
{
|
||||||
@ -43,40 +42,10 @@ CPlayerFoobar::CPlayerFoobar() : CPlayer(),
|
|||||||
*/
|
*/
|
||||||
CPlayerFoobar::~CPlayerFoobar()
|
CPlayerFoobar::~CPlayerFoobar()
|
||||||
{
|
{
|
||||||
|
g_Foobar = NULL;
|
||||||
Uninitialize();
|
Uninitialize();
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
** AddInstance
|
|
||||||
**
|
|
||||||
** Called during initialization of each measure.
|
|
||||||
**
|
|
||||||
*/
|
|
||||||
void CPlayerFoobar::AddInstance(MEASURETYPE type)
|
|
||||||
{
|
|
||||||
++m_InstanceCount;
|
|
||||||
|
|
||||||
if (type == MEASURE_COVER)
|
|
||||||
{
|
|
||||||
m_HasCoverMeasure = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
** RemoveInstance
|
|
||||||
**
|
|
||||||
** Called during destruction of each measure.
|
|
||||||
**
|
|
||||||
*/
|
|
||||||
void CPlayerFoobar::RemoveInstance()
|
|
||||||
{
|
|
||||||
if (--m_InstanceCount == 0)
|
|
||||||
{
|
|
||||||
g_Foobar = NULL;
|
|
||||||
delete this;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** Initialize
|
** Initialize
|
||||||
**
|
**
|
||||||
@ -150,7 +119,7 @@ void CPlayerFoobar::Uninitialize()
|
|||||||
*/
|
*/
|
||||||
LRESULT CALLBACK CPlayerFoobar::WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
|
LRESULT CALLBACK CPlayerFoobar::WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
|
||||||
{
|
{
|
||||||
static CPlayerFoobar* foobar;
|
static CPlayerFoobar* player;
|
||||||
|
|
||||||
switch (msg)
|
switch (msg)
|
||||||
{
|
{
|
||||||
@ -158,7 +127,7 @@ LRESULT CALLBACK CPlayerFoobar::WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPAR
|
|||||||
{
|
{
|
||||||
// Get pointer to the CPlayerFoobar class from the CreateWindow call
|
// Get pointer to the CPlayerFoobar class from the CreateWindow call
|
||||||
LPVOID params = ((CREATESTRUCT*)lParam)->lpCreateParams;
|
LPVOID params = ((CREATESTRUCT*)lParam)->lpCreateParams;
|
||||||
foobar = (CPlayerFoobar*)params;
|
player = (CPlayerFoobar*)params;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -170,33 +139,33 @@ LRESULT CALLBACK CPlayerFoobar::WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPAR
|
|||||||
|
|
||||||
case FOO_STATECHANGE:
|
case FOO_STATECHANGE:
|
||||||
{
|
{
|
||||||
PLAYERSTATE ps = (PLAYERSTATE)wParam;
|
PLAYSTATE ps = (PLAYSTATE)wParam;
|
||||||
if (ps == PLAYER_STOPPED)
|
if (ps == PLAYER_STOPPED)
|
||||||
{
|
{
|
||||||
foobar->ClearInfo();
|
player->ClearData();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
foobar->m_State = ps;
|
player->m_State = ps;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case FOO_TIMECHANGE:
|
case FOO_TIMECHANGE:
|
||||||
foobar->m_Position = (UINT)wParam;
|
player->m_Position = (UINT)wParam;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case FOO_VOLUMECHANGE:
|
case FOO_VOLUMECHANGE:
|
||||||
foobar->m_Volume = (UINT)wParam;
|
player->m_Volume = (UINT)wParam;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case FOO_PLAYERSTART:
|
case FOO_PLAYERSTART:
|
||||||
foobar->m_FooWindow = (HWND)wParam;
|
player->m_FooWindow = (HWND)wParam;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case FOO_PLAYERQUIT:
|
case FOO_PLAYERQUIT:
|
||||||
foobar->m_FooWindow = NULL;
|
player->m_FooWindow = NULL;
|
||||||
foobar->ClearInfo();
|
player->ClearData();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
@ -207,51 +176,52 @@ LRESULT CALLBACK CPlayerFoobar::WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPAR
|
|||||||
|
|
||||||
if (cds->dwData == FOO_TRACKCHANGE)
|
if (cds->dwData == FOO_TRACKCHANGE)
|
||||||
{
|
{
|
||||||
if (foobar->m_State != PLAYER_PLAYING)
|
if (player->m_State != PLAYER_PLAYING)
|
||||||
{
|
{
|
||||||
foobar->m_State = PLAYER_PLAYING;
|
player->m_State = PLAYER_PLAYING;
|
||||||
}
|
}
|
||||||
|
|
||||||
// In the format "TITLE ARTIST ALBUM LENGTH RATING" (seperated by \t)
|
// In the format "TITLE ARTIST ALBUM LENGTH RATING" (seperated by \t)
|
||||||
WCHAR buffer[1024];
|
WCHAR buffer[1024];
|
||||||
MultiByteToWideChar(CP_UTF8, 0, (char*)cds->lpData, cds->cbData, buffer, 1024);
|
MultiByteToWideChar(CP_UTF8, 0, (char*)cds->lpData, cds->cbData, buffer, 1024);
|
||||||
foobar->m_Artist = buffer;
|
player->m_Artist = buffer;
|
||||||
|
|
||||||
WCHAR* token = wcstok(buffer, L"\t");
|
WCHAR* token = wcstok(buffer, L"\t");
|
||||||
if (token)
|
if (token)
|
||||||
{
|
{
|
||||||
foobar->m_Title = token;
|
player->m_Title = token;
|
||||||
}
|
}
|
||||||
token = wcstok(NULL, L"\t");
|
token = wcstok(NULL, L"\t");
|
||||||
if (token)
|
if (token)
|
||||||
{
|
{
|
||||||
foobar->m_Artist = token;
|
player->m_Artist = token;
|
||||||
}
|
}
|
||||||
token = wcstok(NULL, L"\t");
|
token = wcstok(NULL, L"\t");
|
||||||
if (token)
|
if (token)
|
||||||
{
|
{
|
||||||
foobar->m_Album = token;
|
player->m_Album = token;
|
||||||
}
|
}
|
||||||
token = wcstok(NULL, L"\t");
|
token = wcstok(NULL, L"\t");
|
||||||
if (token)
|
if (token)
|
||||||
{
|
{
|
||||||
foobar->m_Duration = _wtoi(token);
|
player->m_Duration = _wtoi(token);
|
||||||
}
|
}
|
||||||
token = wcstok(NULL, L"\t");
|
token = wcstok(NULL, L"\t");
|
||||||
if (token)
|
if (token)
|
||||||
{
|
{
|
||||||
foobar->m_Rating = _wtoi(token);
|
player->m_Rating = _wtoi(token);
|
||||||
}
|
}
|
||||||
token = wcstok(NULL, L"\t");
|
token = wcstok(NULL, L"\t");
|
||||||
if (token)
|
if (token && wcscmp(token, player->m_FilePath.c_str()) != 0)
|
||||||
{
|
{
|
||||||
if (wcscmp(token, foobar->m_FilePath.c_str()) != 0)
|
// If different file
|
||||||
|
++player->m_TrackCount;
|
||||||
|
player->m_FilePath = token;
|
||||||
|
player->m_Position = 0;
|
||||||
|
|
||||||
|
if (player->m_HasCoverMeasure || player->m_InstanceCount == 0)
|
||||||
{
|
{
|
||||||
// If different file
|
GetCover(player->m_Artist, player->m_Title, player->m_FilePath, player->m_CoverPath);
|
||||||
foobar->m_FilePath = token;
|
|
||||||
foobar->m_TrackChanged = true;
|
|
||||||
foobar->m_Position = 0;
|
|
||||||
foobar->GetCoverArt(token);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -263,47 +233,6 @@ LRESULT CALLBACK CPlayerFoobar::WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPAR
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
** GetCoverArt
|
|
||||||
**
|
|
||||||
** Try to find cover art for file.
|
|
||||||
**
|
|
||||||
*/
|
|
||||||
void CPlayerFoobar::GetCoverArt(LPTSTR filename)
|
|
||||||
{
|
|
||||||
// TODO: Fix temp solution
|
|
||||||
if (m_HasCoverMeasure || m_InstanceCount == 0)
|
|
||||||
{
|
|
||||||
if (GetCachedArt())
|
|
||||||
{
|
|
||||||
// Cover is in cache, lets use the that
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
TagLib::FileRef fr(filename);
|
|
||||||
if (!fr.isNull() && fr.tag() && GetEmbeddedArt(fr))
|
|
||||||
{
|
|
||||||
// Embedded art found
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get rid of the name and extension from filename
|
|
||||||
std::wstring trackFolder = filename;
|
|
||||||
std::wstring::size_type pos = trackFolder.find_last_of(L'\\');
|
|
||||||
if (pos == std::wstring::npos) return;
|
|
||||||
trackFolder.resize(++pos);
|
|
||||||
|
|
||||||
if (GetLocalArt(trackFolder, L"cover") || GetLocalArt(trackFolder, L"folder"))
|
|
||||||
{
|
|
||||||
// Local art found
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Nothing found
|
|
||||||
m_CoverPath.clear();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** UpdateData
|
** UpdateData
|
||||||
**
|
**
|
||||||
@ -312,11 +241,6 @@ void CPlayerFoobar::GetCoverArt(LPTSTR filename)
|
|||||||
*/
|
*/
|
||||||
void CPlayerFoobar::UpdateData()
|
void CPlayerFoobar::UpdateData()
|
||||||
{
|
{
|
||||||
if (m_TrackChanged)
|
|
||||||
{
|
|
||||||
ExecuteTrackChangeAction();
|
|
||||||
m_TrackChanged = false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -327,10 +251,7 @@ void CPlayerFoobar::UpdateData()
|
|||||||
*/
|
*/
|
||||||
void CPlayerFoobar::Pause()
|
void CPlayerFoobar::Pause()
|
||||||
{
|
{
|
||||||
if (m_FooWindow)
|
SendMessage(m_FooWindow, WM_USER, 0, FOO_PAUSE);
|
||||||
{
|
|
||||||
SendMessage(m_FooWindow, WM_USER, 0, FOO_PAUSE);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -341,24 +262,7 @@ void CPlayerFoobar::Pause()
|
|||||||
*/
|
*/
|
||||||
void CPlayerFoobar::Play()
|
void CPlayerFoobar::Play()
|
||||||
{
|
{
|
||||||
if (m_FooWindow)
|
SendMessage(m_FooWindow, WM_USER, 0, FOO_PLAY);
|
||||||
{
|
|
||||||
SendMessage(m_FooWindow, WM_USER, 0, FOO_PLAY);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
** PlayPause
|
|
||||||
**
|
|
||||||
** Handles the PlayPause bang.
|
|
||||||
**
|
|
||||||
*/
|
|
||||||
void CPlayerFoobar::PlayPause()
|
|
||||||
{
|
|
||||||
if (m_FooWindow)
|
|
||||||
{
|
|
||||||
SendMessage(m_FooWindow, WM_USER, 0, FOO_PLAYPAUSE);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -369,10 +273,7 @@ void CPlayerFoobar::PlayPause()
|
|||||||
*/
|
*/
|
||||||
void CPlayerFoobar::Stop()
|
void CPlayerFoobar::Stop()
|
||||||
{
|
{
|
||||||
if (m_FooWindow)
|
SendMessage(m_FooWindow, WM_USER, 0, FOO_STOP);
|
||||||
{
|
|
||||||
SendMessage(m_FooWindow, WM_USER, 0, FOO_STOP);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -383,10 +284,7 @@ void CPlayerFoobar::Stop()
|
|||||||
*/
|
*/
|
||||||
void CPlayerFoobar::Next()
|
void CPlayerFoobar::Next()
|
||||||
{
|
{
|
||||||
if (m_FooWindow)
|
SendMessage(m_FooWindow, WM_USER, 0, FOO_NEXT);
|
||||||
{
|
|
||||||
SendMessage(m_FooWindow, WM_USER, 0, FOO_NEXT);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -397,10 +295,7 @@ void CPlayerFoobar::Next()
|
|||||||
*/
|
*/
|
||||||
void CPlayerFoobar::Previous()
|
void CPlayerFoobar::Previous()
|
||||||
{
|
{
|
||||||
if (m_FooWindow)
|
SendMessage(m_FooWindow, WM_USER, 0, FOO_PREVIOUS);
|
||||||
{
|
|
||||||
SendMessage(m_FooWindow, WM_USER, 0, FOO_PREVIOUS);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -411,10 +306,7 @@ void CPlayerFoobar::Previous()
|
|||||||
*/
|
*/
|
||||||
void CPlayerFoobar::SetPosition(int position)
|
void CPlayerFoobar::SetPosition(int position)
|
||||||
{
|
{
|
||||||
if (m_FooWindow)
|
SendMessage(m_FooWindow, WM_USER, position, FOO_SETPOSITION);
|
||||||
{
|
|
||||||
SendMessage(m_FooWindow, WM_USER, position, FOO_SETPOSITION);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -425,10 +317,7 @@ void CPlayerFoobar::SetPosition(int position)
|
|||||||
*/
|
*/
|
||||||
void CPlayerFoobar::SetVolume(int volume)
|
void CPlayerFoobar::SetVolume(int volume)
|
||||||
{
|
{
|
||||||
if (m_FooWindow)
|
SendMessage(m_FooWindow, WM_USER, volume, FOO_SETVOLUME);
|
||||||
{
|
|
||||||
SendMessage(m_FooWindow, WM_USER, volume, FOO_SETVOLUME);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -439,10 +328,7 @@ void CPlayerFoobar::SetVolume(int volume)
|
|||||||
*/
|
*/
|
||||||
void CPlayerFoobar::ClosePlayer()
|
void CPlayerFoobar::ClosePlayer()
|
||||||
{
|
{
|
||||||
if (m_FooWindow)
|
SendMessage(m_FooWindow, WM_USER, 0, FOO_QUITPLAYER);
|
||||||
{
|
|
||||||
SendMessage(m_FooWindow, WM_USER, 0, FOO_QUITPLAYER);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -451,11 +337,11 @@ void CPlayerFoobar::ClosePlayer()
|
|||||||
** Handles the OpenPlayer bang.
|
** Handles the OpenPlayer bang.
|
||||||
**
|
**
|
||||||
*/
|
*/
|
||||||
void CPlayerFoobar::OpenPlayer()
|
void CPlayerFoobar::OpenPlayer(std::wstring& path)
|
||||||
{
|
{
|
||||||
if (!m_FooWindow)
|
if (!m_FooWindow)
|
||||||
{
|
{
|
||||||
if (m_PlayerPath.empty())
|
if (path.empty())
|
||||||
{
|
{
|
||||||
// Gotta figure out where foobar2000 is located at
|
// Gotta figure out where foobar2000 is located at
|
||||||
HKEY hKey;
|
HKEY hKey;
|
||||||
@ -478,7 +364,7 @@ void CPlayerFoobar::OpenPlayer()
|
|||||||
{
|
{
|
||||||
if (type == REG_SZ && data[0] == L'\"')
|
if (type == REG_SZ && data[0] == L'\"')
|
||||||
{
|
{
|
||||||
std::wstring path = data;
|
path = data;
|
||||||
path.erase(0, 1); // Get rid of the leading quote
|
path.erase(0, 1); // Get rid of the leading quote
|
||||||
std::wstring::size_type pos = path.find_first_of(L'\"');
|
std::wstring::size_type pos = path.find_first_of(L'\"');
|
||||||
|
|
||||||
@ -486,7 +372,11 @@ void CPlayerFoobar::OpenPlayer()
|
|||||||
{
|
{
|
||||||
path.resize(pos); // Get rid the last quote and everything after it
|
path.resize(pos); // Get rid the last quote and everything after it
|
||||||
ShellExecute(NULL, L"open", path.c_str(), NULL, NULL, SW_SHOW);
|
ShellExecute(NULL, L"open", path.c_str(), NULL, NULL, SW_SHOW);
|
||||||
m_PlayerPath = path;
|
path = path;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
path.clear();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -496,7 +386,7 @@ void CPlayerFoobar::OpenPlayer()
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
ShellExecute(NULL, L"open", m_PlayerPath.c_str(), NULL, NULL, SW_SHOW);
|
ShellExecute(NULL, L"open", path.c_str(), NULL, NULL, SW_SHOW);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -504,14 +394,3 @@ void CPlayerFoobar::OpenPlayer()
|
|||||||
SendMessage(m_FooWindow, WM_USER, 0, FOO_SHOWPLAYER);
|
SendMessage(m_FooWindow, WM_USER, 0, FOO_SHOWPLAYER);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
** TogglePlayer
|
|
||||||
**
|
|
||||||
** Handles the TogglePlayer bang.
|
|
||||||
**
|
|
||||||
*/
|
|
||||||
void CPlayerFoobar::TogglePlayer()
|
|
||||||
{
|
|
||||||
m_FooWindow ? ClosePlayer() : OpenPlayer();
|
|
||||||
}
|
|
||||||
|
@ -27,9 +27,10 @@ public:
|
|||||||
CPlayerFoobar();
|
CPlayerFoobar();
|
||||||
~CPlayerFoobar();
|
~CPlayerFoobar();
|
||||||
|
|
||||||
|
virtual void UpdateData();
|
||||||
|
|
||||||
virtual void Pause();
|
virtual void Pause();
|
||||||
virtual void Play();
|
virtual void Play();
|
||||||
virtual void PlayPause();
|
|
||||||
virtual void Stop();
|
virtual void Stop();
|
||||||
virtual void Next();
|
virtual void Next();
|
||||||
virtual void Previous();
|
virtual void Previous();
|
||||||
@ -37,12 +38,7 @@ public:
|
|||||||
virtual void SetRating(int rating) {}
|
virtual void SetRating(int rating) {}
|
||||||
virtual void SetVolume(int volume);
|
virtual void SetVolume(int volume);
|
||||||
virtual void ClosePlayer();
|
virtual void ClosePlayer();
|
||||||
virtual void OpenPlayer();
|
virtual void OpenPlayer(std::wstring& path);
|
||||||
virtual void TogglePlayer();
|
|
||||||
|
|
||||||
virtual void AddInstance(MEASURETYPE type);
|
|
||||||
virtual void RemoveInstance();
|
|
||||||
virtual void UpdateData();
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
enum FOOMESSAGE
|
enum FOOMESSAGE
|
||||||
@ -76,9 +72,7 @@ private:
|
|||||||
void Initialize();
|
void Initialize();
|
||||||
void Uninitialize();
|
void Uninitialize();
|
||||||
static LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);
|
static LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);
|
||||||
void GetCoverArt(LPTSTR filename);
|
|
||||||
|
|
||||||
bool m_HasCoverMeasure;
|
|
||||||
HWND m_Window; // Our reciever window
|
HWND m_Window; // Our reciever window
|
||||||
HWND m_FooWindow; // Foobar receiver window
|
HWND m_FooWindow; // Foobar receiver window
|
||||||
};
|
};
|
||||||
|
@ -114,10 +114,7 @@ HRESULT STDMETHODCALLTYPE CPlayerITunes::CEventHandler::Invoke(DISPID dispidMemb
|
|||||||
**
|
**
|
||||||
*/
|
*/
|
||||||
CPlayerITunes::CPlayerITunes() : CPlayer(),
|
CPlayerITunes::CPlayerITunes() : CPlayer(),
|
||||||
m_Initialized(false),
|
|
||||||
m_UserQuitPrompt(false),
|
m_UserQuitPrompt(false),
|
||||||
m_HasCoverMeasure(false),
|
|
||||||
m_Window(),
|
|
||||||
m_iTunes(),
|
m_iTunes(),
|
||||||
m_iTunesEvent()
|
m_iTunesEvent()
|
||||||
{
|
{
|
||||||
@ -132,41 +129,11 @@ CPlayerITunes::CPlayerITunes() : CPlayer(),
|
|||||||
*/
|
*/
|
||||||
CPlayerITunes::~CPlayerITunes()
|
CPlayerITunes::~CPlayerITunes()
|
||||||
{
|
{
|
||||||
|
g_iTunes = NULL;
|
||||||
Uninitialize();
|
Uninitialize();
|
||||||
CoUninitialize();
|
CoUninitialize();
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
** AddInstance
|
|
||||||
**
|
|
||||||
** Called during initialization of each measure.
|
|
||||||
**
|
|
||||||
*/
|
|
||||||
void CPlayerITunes::AddInstance(MEASURETYPE type)
|
|
||||||
{
|
|
||||||
++m_InstanceCount;
|
|
||||||
|
|
||||||
if (type == MEASURE_COVER)
|
|
||||||
{
|
|
||||||
m_HasCoverMeasure = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
** RemoveInstance
|
|
||||||
**
|
|
||||||
** Called during destruction of each measure.
|
|
||||||
**
|
|
||||||
*/
|
|
||||||
void CPlayerITunes::RemoveInstance()
|
|
||||||
{
|
|
||||||
if (--m_InstanceCount == 0)
|
|
||||||
{
|
|
||||||
g_iTunes = NULL;
|
|
||||||
delete this;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** Initialize
|
** Initialize
|
||||||
**
|
**
|
||||||
@ -256,11 +223,17 @@ void CPlayerITunes::Uninitialize()
|
|||||||
delete m_iTunesEvent;
|
delete m_iTunesEvent;
|
||||||
}
|
}
|
||||||
|
|
||||||
ClearInfo();
|
ClearData();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CPlayerITunes::CheckActive()
|
/*
|
||||||
|
** CheckWindow
|
||||||
|
**
|
||||||
|
** Try to find iTunes periodically.
|
||||||
|
**
|
||||||
|
*/
|
||||||
|
bool CPlayerITunes::CheckWindow()
|
||||||
{
|
{
|
||||||
static DWORD oldTime = 0;
|
static DWORD oldTime = 0;
|
||||||
DWORD time = GetTickCount();
|
DWORD time = GetTickCount();
|
||||||
@ -268,36 +241,9 @@ bool CPlayerITunes::CheckActive()
|
|||||||
if (time - oldTime > 5000)
|
if (time - oldTime > 5000)
|
||||||
{
|
{
|
||||||
oldTime = time;
|
oldTime = time;
|
||||||
m_Window = FindWindow(L"iTunes", L"iTunes");
|
|
||||||
return m_Window ? true : false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
HWND wnd = FindWindow(L"iTunes", L"iTunes");
|
||||||
}
|
if (wnd)
|
||||||
|
|
||||||
/*
|
|
||||||
** UpdateData
|
|
||||||
**
|
|
||||||
** Called during each update of the main measure.
|
|
||||||
**
|
|
||||||
*/
|
|
||||||
void CPlayerITunes::UpdateData()
|
|
||||||
{
|
|
||||||
if (m_Initialized)
|
|
||||||
{
|
|
||||||
if (m_TrackChanged)
|
|
||||||
{
|
|
||||||
ExecuteTrackChangeAction();
|
|
||||||
m_TrackChanged = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
long position;
|
|
||||||
m_iTunes->get_PlayerPosition(&position);
|
|
||||||
m_Position = (UINT)position;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (CheckActive())
|
|
||||||
{
|
{
|
||||||
if (!m_UserQuitPrompt)
|
if (!m_UserQuitPrompt)
|
||||||
{
|
{
|
||||||
@ -309,6 +255,24 @@ void CPlayerITunes::UpdateData()
|
|||||||
m_UserQuitPrompt = false;
|
m_UserQuitPrompt = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return m_Initialized;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
** UpdateData
|
||||||
|
**
|
||||||
|
** Called during each update of the main measure.
|
||||||
|
**
|
||||||
|
*/
|
||||||
|
void CPlayerITunes::UpdateData()
|
||||||
|
{
|
||||||
|
if ((m_Initialized || CheckWindow()) && m_State != PLAYER_STOPPED)
|
||||||
|
{
|
||||||
|
long position;
|
||||||
|
m_iTunes->get_PlayerPosition(&position);
|
||||||
|
m_Position = (UINT)position;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -352,50 +316,47 @@ void CPlayerITunes::OnTrackChange()
|
|||||||
file->Release();
|
file->Release();
|
||||||
if (tmpStr && wcscmp(tmpStr, m_FilePath.c_str()) != 0)
|
if (tmpStr && wcscmp(tmpStr, m_FilePath.c_str()) != 0)
|
||||||
{
|
{
|
||||||
|
++m_TrackCount;
|
||||||
m_FilePath = tmpStr;
|
m_FilePath = tmpStr;
|
||||||
m_TrackChanged = true;
|
|
||||||
|
|
||||||
if (m_HasCoverMeasure)
|
if (m_HasCoverMeasure && !GetCachedCover(m_Artist, m_Title, m_CoverPath))
|
||||||
{
|
{
|
||||||
if (!GetCachedArt())
|
// Art not in cache, check for embedded art
|
||||||
|
IITArtworkCollection* artworkCollection;
|
||||||
|
hr = track->get_Artwork(&artworkCollection);
|
||||||
|
|
||||||
|
if (SUCCEEDED(hr))
|
||||||
{
|
{
|
||||||
// Art not in cache, check for embedded art
|
long count;
|
||||||
IITArtworkCollection* artworkCollection;
|
artworkCollection->get_Count(&count);
|
||||||
hr = track->get_Artwork(&artworkCollection);
|
|
||||||
|
|
||||||
if (SUCCEEDED(hr))
|
if (count > 0)
|
||||||
{
|
{
|
||||||
long count;
|
IITArtwork* artwork;
|
||||||
artworkCollection->get_Count(&count);
|
hr = artworkCollection->get_Item(1, &artwork);
|
||||||
|
|
||||||
if (count > 0)
|
if (SUCCEEDED(hr))
|
||||||
{
|
{
|
||||||
IITArtwork* artwork;
|
tmpStr = m_CoverPath.c_str();
|
||||||
hr = artworkCollection->get_Item(1, &artwork);
|
hr = artwork->SaveArtworkToFile(tmpStr);
|
||||||
|
if (FAILED(hr))
|
||||||
if (SUCCEEDED(hr))
|
|
||||||
{
|
{
|
||||||
tmpStr = m_CoverPath.c_str();
|
m_CoverPath.clear();
|
||||||
hr = artwork->SaveArtworkToFile(tmpStr);
|
|
||||||
if (FAILED(hr))
|
|
||||||
{
|
|
||||||
m_CoverPath.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
artwork->Release();
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
m_CoverPath.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
artworkCollection->Release();
|
artwork->Release();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
m_CoverPath.clear();
|
m_CoverPath.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
artworkCollection->Release();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m_CoverPath.clear();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -405,7 +366,7 @@ void CPlayerITunes::OnTrackChange()
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
ClearInfo();
|
ClearData();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -447,10 +408,7 @@ void CPlayerITunes::OnVolumeChange(int volume)
|
|||||||
*/
|
*/
|
||||||
void CPlayerITunes::Pause()
|
void CPlayerITunes::Pause()
|
||||||
{
|
{
|
||||||
if (m_Initialized)
|
m_iTunes->Pause();
|
||||||
{
|
|
||||||
m_iTunes->Pause();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -461,24 +419,7 @@ void CPlayerITunes::Pause()
|
|||||||
*/
|
*/
|
||||||
void CPlayerITunes::Play()
|
void CPlayerITunes::Play()
|
||||||
{
|
{
|
||||||
if (m_Initialized)
|
m_iTunes->Play();
|
||||||
{
|
|
||||||
m_iTunes->Play();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
** PlayPause
|
|
||||||
**
|
|
||||||
** Handles the PlayPause bang.
|
|
||||||
**
|
|
||||||
*/
|
|
||||||
void CPlayerITunes::PlayPause()
|
|
||||||
{
|
|
||||||
if (m_Initialized)
|
|
||||||
{
|
|
||||||
m_iTunes->PlayPause();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -489,10 +430,7 @@ void CPlayerITunes::PlayPause()
|
|||||||
*/
|
*/
|
||||||
void CPlayerITunes::Stop()
|
void CPlayerITunes::Stop()
|
||||||
{
|
{
|
||||||
if (m_Initialized)
|
m_iTunes->Stop();
|
||||||
{
|
|
||||||
m_iTunes->Stop();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -503,10 +441,7 @@ void CPlayerITunes::Stop()
|
|||||||
*/
|
*/
|
||||||
void CPlayerITunes::Next()
|
void CPlayerITunes::Next()
|
||||||
{
|
{
|
||||||
if (m_Initialized)
|
m_iTunes->NextTrack();
|
||||||
{
|
|
||||||
m_iTunes->NextTrack();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -517,10 +452,7 @@ void CPlayerITunes::Next()
|
|||||||
*/
|
*/
|
||||||
void CPlayerITunes::Previous()
|
void CPlayerITunes::Previous()
|
||||||
{
|
{
|
||||||
if (m_Initialized)
|
m_iTunes->PreviousTrack();
|
||||||
{
|
|
||||||
m_iTunes->PreviousTrack();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -531,10 +463,7 @@ void CPlayerITunes::Previous()
|
|||||||
*/
|
*/
|
||||||
void CPlayerITunes::SetPosition(int position)
|
void CPlayerITunes::SetPosition(int position)
|
||||||
{
|
{
|
||||||
if (m_Initialized)
|
m_iTunes->put_PlayerPosition((long)position);
|
||||||
{
|
|
||||||
m_iTunes->put_PlayerPosition((long)position);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -545,17 +474,14 @@ void CPlayerITunes::SetPosition(int position)
|
|||||||
*/
|
*/
|
||||||
void CPlayerITunes::SetRating(int rating)
|
void CPlayerITunes::SetRating(int rating)
|
||||||
{
|
{
|
||||||
if (m_Initialized)
|
IITTrack* track;
|
||||||
|
HRESULT hr = m_iTunes->get_CurrentTrack(&track);
|
||||||
|
|
||||||
|
if (SUCCEEDED(hr))
|
||||||
{
|
{
|
||||||
rating *= 20;
|
rating *= 20;
|
||||||
IITTrack* track;
|
track->put_Rating((long)rating);
|
||||||
HRESULT hr = m_iTunes->get_CurrentTrack(&track);
|
track->Release();
|
||||||
|
|
||||||
if (SUCCEEDED(hr))
|
|
||||||
{
|
|
||||||
track->put_Rating((long)rating);
|
|
||||||
track->Release();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -567,10 +493,7 @@ void CPlayerITunes::SetRating(int rating)
|
|||||||
*/
|
*/
|
||||||
void CPlayerITunes::SetVolume(int volume)
|
void CPlayerITunes::SetVolume(int volume)
|
||||||
{
|
{
|
||||||
if (m_Initialized)
|
m_iTunes->put_SoundVolume((long)volume);
|
||||||
{
|
|
||||||
m_iTunes->put_SoundVolume((long)volume);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -581,12 +504,9 @@ void CPlayerITunes::SetVolume(int volume)
|
|||||||
*/
|
*/
|
||||||
void CPlayerITunes::ClosePlayer()
|
void CPlayerITunes::ClosePlayer()
|
||||||
{
|
{
|
||||||
if (m_Initialized)
|
m_UserQuitPrompt = true;
|
||||||
{
|
m_iTunes->Quit();
|
||||||
m_UserQuitPrompt = true;
|
Uninitialize();
|
||||||
m_iTunes->Quit();
|
|
||||||
Uninitialize();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -595,18 +515,7 @@ void CPlayerITunes::ClosePlayer()
|
|||||||
** Handles the OpenPlayer bang.
|
** Handles the OpenPlayer bang.
|
||||||
**
|
**
|
||||||
*/
|
*/
|
||||||
void CPlayerITunes::OpenPlayer()
|
void CPlayerITunes::OpenPlayer(std::wstring& path)
|
||||||
{
|
{
|
||||||
ShellExecute(NULL, L"open", m_PlayerPath.empty() ? L"iTunes.exe" : m_PlayerPath.c_str(), NULL, NULL, SW_SHOW);
|
ShellExecute(NULL, L"open", path.empty() ? L"iTunes.exe" : path.c_str(), NULL, NULL, SW_SHOW);
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
** TogglePlayer
|
|
||||||
**
|
|
||||||
** Handles the TogglePlayer bang.
|
|
||||||
**
|
|
||||||
*/
|
|
||||||
void CPlayerITunes::TogglePlayer()
|
|
||||||
{
|
|
||||||
m_Initialized ? ClosePlayer() : OpenPlayer();
|
|
||||||
}
|
}
|
||||||
|
@ -38,9 +38,10 @@ public:
|
|||||||
CPlayerITunes();
|
CPlayerITunes();
|
||||||
~CPlayerITunes();
|
~CPlayerITunes();
|
||||||
|
|
||||||
|
virtual void UpdateData();
|
||||||
|
|
||||||
virtual void Pause();
|
virtual void Pause();
|
||||||
virtual void Play();
|
virtual void Play();
|
||||||
virtual void PlayPause();
|
|
||||||
virtual void Stop();
|
virtual void Stop();
|
||||||
virtual void Next();
|
virtual void Next();
|
||||||
virtual void Previous();
|
virtual void Previous();
|
||||||
@ -48,12 +49,7 @@ public:
|
|||||||
virtual void SetRating(int rating);
|
virtual void SetRating(int rating);
|
||||||
virtual void SetVolume(int volume);
|
virtual void SetVolume(int volume);
|
||||||
virtual void ClosePlayer();
|
virtual void ClosePlayer();
|
||||||
virtual void OpenPlayer();
|
virtual void OpenPlayer(std::wstring& path);
|
||||||
virtual void TogglePlayer();
|
|
||||||
|
|
||||||
virtual void AddInstance(MEASURETYPE type);
|
|
||||||
virtual void RemoveInstance();
|
|
||||||
virtual void UpdateData();
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
class CEventHandler : public _IiTunesEvents
|
class CEventHandler : public _IiTunesEvents
|
||||||
@ -85,13 +81,9 @@ private:
|
|||||||
void OnTrackChange();
|
void OnTrackChange();
|
||||||
void OnStateChange(bool playing);
|
void OnStateChange(bool playing);
|
||||||
void OnVolumeChange(int volume);
|
void OnVolumeChange(int volume);
|
||||||
bool CheckActive();
|
bool CheckWindow();
|
||||||
|
|
||||||
bool m_Initialized;
|
|
||||||
bool m_UserQuitPrompt;
|
bool m_UserQuitPrompt;
|
||||||
bool m_HasCoverMeasure;
|
|
||||||
HWND m_Window;
|
|
||||||
|
|
||||||
IiTunes* m_iTunes;
|
IiTunes* m_iTunes;
|
||||||
CEventHandler* m_iTunesEvent;
|
CEventHandler* m_iTunesEvent;
|
||||||
};
|
};
|
||||||
|
@ -30,7 +30,6 @@ extern CPlayer* g_Spotify;
|
|||||||
CPlayerSpotify::CPlayerSpotify() : CPlayer(),
|
CPlayerSpotify::CPlayerSpotify() : CPlayer(),
|
||||||
m_Window()
|
m_Window()
|
||||||
{
|
{
|
||||||
GetWindow();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -41,32 +40,33 @@ CPlayerSpotify::CPlayerSpotify() : CPlayer(),
|
|||||||
*/
|
*/
|
||||||
CPlayerSpotify::~CPlayerSpotify()
|
CPlayerSpotify::~CPlayerSpotify()
|
||||||
{
|
{
|
||||||
|
g_Spotify = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** AddInstance
|
** CheckWindow
|
||||||
**
|
**
|
||||||
** Called during initialization of each measure.
|
** Try to find Spotify periodically.
|
||||||
**
|
**
|
||||||
*/
|
*/
|
||||||
void CPlayerSpotify::AddInstance(MEASURETYPE type)
|
bool CPlayerSpotify::CheckWindow()
|
||||||
{
|
{
|
||||||
++m_InstanceCount;
|
static DWORD oldTime = 0;
|
||||||
}
|
DWORD time = GetTickCount();
|
||||||
|
|
||||||
/*
|
// Try to find Spotify window every 5 seconds
|
||||||
** RemoveInstance
|
if (time - oldTime > 5000)
|
||||||
**
|
|
||||||
** Called during destruction of each measure.
|
|
||||||
**
|
|
||||||
*/
|
|
||||||
void CPlayerSpotify::RemoveInstance()
|
|
||||||
{
|
|
||||||
if (--m_InstanceCount == 0)
|
|
||||||
{
|
{
|
||||||
g_Spotify = NULL;
|
oldTime = time;
|
||||||
delete this;
|
|
||||||
|
m_Window = FindWindow(L"SpotifyMainWindow", NULL);
|
||||||
|
if (m_Window)
|
||||||
|
{
|
||||||
|
m_Initialized = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return m_Initialized;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -77,59 +77,52 @@ void CPlayerSpotify::RemoveInstance()
|
|||||||
*/
|
*/
|
||||||
void CPlayerSpotify::UpdateData()
|
void CPlayerSpotify::UpdateData()
|
||||||
{
|
{
|
||||||
if (GetWindow())
|
if (m_Initialized || CheckWindow())
|
||||||
{
|
{
|
||||||
if (m_TrackChanged)
|
// Parse title and artist from window title
|
||||||
{
|
|
||||||
ExecuteTrackChangeAction();
|
|
||||||
m_TrackChanged = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get window text
|
|
||||||
WCHAR buffer[256];
|
WCHAR buffer[256];
|
||||||
buffer[0] = 0;
|
if (GetWindowText(m_Window, buffer, 256) > 10)
|
||||||
GetWindowText(m_Window, buffer, 256);
|
|
||||||
std::wstring title = buffer;
|
|
||||||
|
|
||||||
title.erase(0, 10); // Get rid of "Spotify - "
|
|
||||||
std::wstring::size_type pos = title.find(L" – ");
|
|
||||||
if (pos != std::wstring::npos)
|
|
||||||
{
|
{
|
||||||
std::wstring artist = title.substr(0, pos);
|
std::wstring title = buffer;
|
||||||
std::wstring track = title.substr(pos + 3);
|
title.erase(0, 10); // Get rid of "Spotify - "
|
||||||
|
|
||||||
if (track != m_Title && artist != m_Artist)
|
std::wstring::size_type pos = title.find(L" – ");
|
||||||
|
if (pos != std::wstring::npos)
|
||||||
{
|
{
|
||||||
m_Title = track;
|
m_State = PLAYER_PLAYING;
|
||||||
m_Artist = artist;
|
std::wstring artist = title.substr(0, pos);
|
||||||
m_TrackChanged = true;
|
std::wstring track = title.substr(pos + 3);
|
||||||
|
|
||||||
|
if (track != m_Title && artist != m_Artist)
|
||||||
|
{
|
||||||
|
m_Title = track;
|
||||||
|
m_Artist = artist;
|
||||||
|
++m_TrackCount;
|
||||||
|
}
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
return;
|
}
|
||||||
|
else if (IsWindow(m_Window))
|
||||||
|
{
|
||||||
|
m_State = PLAYER_PAUSED;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ClearData();
|
||||||
|
m_Initialized = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ClearInfo();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool CPlayerSpotify::GetWindow()
|
|
||||||
{
|
|
||||||
m_Window = FindWindow(L"SpotifyMainWindow", NULL);
|
|
||||||
|
|
||||||
return m_Window ? true : false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** PlayPause
|
** Play
|
||||||
**
|
**
|
||||||
** Handles the PlayPause bang.
|
** Handles the Play bang.
|
||||||
**
|
**
|
||||||
*/
|
*/
|
||||||
void CPlayerSpotify::PlayPause()
|
void CPlayerSpotify::Play()
|
||||||
{
|
{
|
||||||
if (m_Window)
|
SendMessage(m_Window, WM_APPCOMMAND, 0, SPOTIFY_PLAYPAUSE);
|
||||||
{
|
|
||||||
SendMessage(m_Window, WM_APPCOMMAND, 0, SPOTIFY_PLAYPAUSE);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -140,10 +133,7 @@ void CPlayerSpotify::PlayPause()
|
|||||||
*/
|
*/
|
||||||
void CPlayerSpotify::Stop()
|
void CPlayerSpotify::Stop()
|
||||||
{
|
{
|
||||||
if (m_Window)
|
SendMessage(m_Window, WM_APPCOMMAND, 0, SPOTIFY_STOP);
|
||||||
{
|
|
||||||
SendMessage(m_Window, WM_APPCOMMAND, 0, SPOTIFY_STOP);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -154,10 +144,7 @@ void CPlayerSpotify::Stop()
|
|||||||
*/
|
*/
|
||||||
void CPlayerSpotify::Next()
|
void CPlayerSpotify::Next()
|
||||||
{
|
{
|
||||||
if (m_Window)
|
SendMessage(m_Window, WM_APPCOMMAND, 0, SPOTIFY_NEXT);
|
||||||
{
|
|
||||||
SendMessage(m_Window, WM_APPCOMMAND, 0, SPOTIFY_NEXT);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -168,10 +155,7 @@ void CPlayerSpotify::Next()
|
|||||||
*/
|
*/
|
||||||
void CPlayerSpotify::Previous()
|
void CPlayerSpotify::Previous()
|
||||||
{
|
{
|
||||||
if (m_Window)
|
SendMessage(m_Window, WM_APPCOMMAND, 0, SPOTIFY_PREV);
|
||||||
{
|
|
||||||
SendMessage(m_Window, WM_APPCOMMAND, 0, SPOTIFY_PREV);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -183,17 +167,14 @@ void CPlayerSpotify::Previous()
|
|||||||
*/
|
*/
|
||||||
void CPlayerSpotify::ClosePlayer()
|
void CPlayerSpotify::ClosePlayer()
|
||||||
{
|
{
|
||||||
if (m_Window)
|
// A little harsh...
|
||||||
|
DWORD pID;
|
||||||
|
GetWindowThreadProcessId(m_Window, &pID);
|
||||||
|
HANDLE hProcess = OpenProcess(PROCESS_TERMINATE, FALSE, pID);
|
||||||
|
if (hProcess)
|
||||||
{
|
{
|
||||||
// A little harsh...
|
TerminateProcess(hProcess, 0);
|
||||||
DWORD pID;
|
CloseHandle(hProcess);
|
||||||
GetWindowThreadProcessId(m_Window, &pID);
|
|
||||||
HANDLE hProcess = OpenProcess(PROCESS_TERMINATE, FALSE, pID);
|
|
||||||
if (hProcess)
|
|
||||||
{
|
|
||||||
TerminateProcess(hProcess, 0);
|
|
||||||
CloseHandle(hProcess);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -203,11 +184,11 @@ void CPlayerSpotify::ClosePlayer()
|
|||||||
** Handles the OpenPlayer bang.
|
** Handles the OpenPlayer bang.
|
||||||
**
|
**
|
||||||
*/
|
*/
|
||||||
void CPlayerSpotify::OpenPlayer()
|
void CPlayerSpotify::OpenPlayer(std::wstring& path)
|
||||||
{
|
{
|
||||||
if (!m_Window)
|
if (!m_Initialized)
|
||||||
{
|
{
|
||||||
if (m_PlayerPath.empty())
|
if (path.empty())
|
||||||
{
|
{
|
||||||
// Gotta figure out where Winamp is located at
|
// Gotta figure out where Winamp is located at
|
||||||
HKEY hKey;
|
HKEY hKey;
|
||||||
@ -230,11 +211,10 @@ void CPlayerSpotify::OpenPlayer()
|
|||||||
{
|
{
|
||||||
if (type == REG_SZ)
|
if (type == REG_SZ)
|
||||||
{
|
{
|
||||||
std::wstring path = data;
|
path = data;
|
||||||
path.erase(0, 1); // Get rid of the leading quote
|
path.erase(0, 1); // Get rid of the leading quote
|
||||||
path.resize(path.length() - 3); // And the ",0 at the end
|
path.resize(path.length() - 3); // And the ",0 at the end
|
||||||
ShellExecute(NULL, L"open", path.c_str(), NULL, NULL, SW_SHOW);
|
ShellExecute(NULL, L"open", path.c_str(), NULL, NULL, SW_SHOW);
|
||||||
m_PlayerPath = path;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -243,7 +223,7 @@ void CPlayerSpotify::OpenPlayer()
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
ShellExecute(NULL, L"open", m_PlayerPath.c_str(), NULL, NULL, SW_SHOW);
|
ShellExecute(NULL, L"open", path.c_str(), NULL, NULL, SW_SHOW);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -253,14 +233,3 @@ void CPlayerSpotify::OpenPlayer()
|
|||||||
BringWindowToTop(m_Window);
|
BringWindowToTop(m_Window);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
** TogglePlayer
|
|
||||||
**
|
|
||||||
** Handles the TogglePlayer bang.
|
|
||||||
**
|
|
||||||
*/
|
|
||||||
void CPlayerSpotify::TogglePlayer()
|
|
||||||
{
|
|
||||||
m_Window ? ClosePlayer() : OpenPlayer();
|
|
||||||
}
|
|
||||||
|
@ -21,38 +21,36 @@
|
|||||||
|
|
||||||
#include "Player.h"
|
#include "Player.h"
|
||||||
|
|
||||||
#define SPOTIFY_PLAYPAUSE 917504
|
|
||||||
#define SPOTIFY_NEXT 720896
|
|
||||||
#define SPOTIFY_PREV 786432
|
|
||||||
#define SPOTIFY_STOP 851968
|
|
||||||
#define SPOTIFY_MUTE 524288
|
|
||||||
#define SPOTIFY_VOLUMEDOWN 589824
|
|
||||||
#define SPOTIFY_VOLUMEUP 655360
|
|
||||||
|
|
||||||
class CPlayerSpotify : public CPlayer
|
class CPlayerSpotify : public CPlayer
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
CPlayerSpotify();
|
CPlayerSpotify();
|
||||||
~CPlayerSpotify();
|
~CPlayerSpotify();
|
||||||
|
|
||||||
virtual void Pause() { return PlayPause(); }
|
virtual void Pause() { return Play(); }
|
||||||
virtual void Play() { return PlayPause(); }
|
virtual void Play();
|
||||||
virtual void PlayPause();
|
|
||||||
virtual void Stop();
|
virtual void Stop();
|
||||||
virtual void Next();
|
virtual void Next();
|
||||||
virtual void Previous();
|
virtual void Previous();
|
||||||
virtual void ClosePlayer();
|
virtual void ClosePlayer();
|
||||||
virtual void OpenPlayer();
|
virtual void OpenPlayer(std::wstring& path);
|
||||||
virtual void TogglePlayer();
|
|
||||||
|
|
||||||
virtual void AddInstance(MEASURETYPE type);
|
|
||||||
virtual void RemoveInstance();
|
|
||||||
virtual void UpdateData();
|
virtual void UpdateData();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool GetWindow();
|
enum SPOTIFYCOMMAND
|
||||||
|
{
|
||||||
|
SPOTIFY_MUTE = 524288,
|
||||||
|
SPOTIFY_VOLUMEDOWN = 589824,
|
||||||
|
SPOTIFY_VOLUMEUP = 655360,
|
||||||
|
SPOTIFY_NEXT = 720896,
|
||||||
|
SPOTIFY_PREV = 786432,
|
||||||
|
SPOTIFY_STOP = 851968,
|
||||||
|
SPOTIFY_PLAYPAUSE = 917504
|
||||||
|
};
|
||||||
|
|
||||||
HWND m_Window; // Spotify window
|
bool CheckWindow();
|
||||||
|
|
||||||
|
HWND m_Window;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -22,7 +22,7 @@
|
|||||||
extern CPlayer* g_WLM;
|
extern CPlayer* g_WLM;
|
||||||
|
|
||||||
// This player emulates the MSN/WLM Messenger 'Listening to' interface, which is
|
// This player emulates the MSN/WLM Messenger 'Listening to' interface, which is
|
||||||
// supported by OpenPandora, Last.fm, Media Player Classic, TTPlayer, etc.
|
// supported by OpenPandora, Last.fm, Media Player Classic, TTPlayer, Zune, etc.
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** CPlayerWLM
|
** CPlayerWLM
|
||||||
@ -64,36 +64,11 @@ CPlayerWLM::CPlayerWLM() : CPlayer(),
|
|||||||
*/
|
*/
|
||||||
CPlayerWLM::~CPlayerWLM()
|
CPlayerWLM::~CPlayerWLM()
|
||||||
{
|
{
|
||||||
|
g_WLM = NULL;
|
||||||
DestroyWindow(m_Window);
|
DestroyWindow(m_Window);
|
||||||
UnregisterClass(L"MsnMsgrUIManager", GetModuleHandle(NULL));
|
UnregisterClass(L"MsnMsgrUIManager", GetModuleHandle(NULL));
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
** AddInstance
|
|
||||||
**
|
|
||||||
** Called during initialization of each measure.
|
|
||||||
**
|
|
||||||
*/
|
|
||||||
void CPlayerWLM::AddInstance(MEASURETYPE type)
|
|
||||||
{
|
|
||||||
++m_InstanceCount;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
** RemoveInstance
|
|
||||||
**
|
|
||||||
** Called during destruction of each measure.
|
|
||||||
**
|
|
||||||
*/
|
|
||||||
void CPlayerWLM::RemoveInstance()
|
|
||||||
{
|
|
||||||
if (--m_InstanceCount == 0)
|
|
||||||
{
|
|
||||||
g_WLM = NULL;
|
|
||||||
delete this;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
LRESULT CALLBACK CPlayerWLM::WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
|
LRESULT CALLBACK CPlayerWLM::WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
|
||||||
{
|
{
|
||||||
static CPlayerWLM* player;
|
static CPlayerWLM* player;
|
||||||
@ -127,6 +102,7 @@ LRESULT CALLBACK CPlayerWLM::WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM
|
|||||||
player->m_State = PLAYER_PLAYING;
|
player->m_State = PLAYER_PLAYING;
|
||||||
data.erase(0, 3); // Get rid of the status
|
data.erase(0, 3); // Get rid of the status
|
||||||
|
|
||||||
|
// TODO: Handle invalid
|
||||||
len = data.find_first_of(L'\\');
|
len = data.find_first_of(L'\\');
|
||||||
len += 2;
|
len += 2;
|
||||||
data.erase(0, len); // Get rid of the format
|
data.erase(0, len); // Get rid of the format
|
||||||
@ -146,7 +122,7 @@ LRESULT CALLBACK CPlayerWLM::WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
player->ClearInfo();
|
player->ClearData();
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
@ -180,12 +156,12 @@ void CPlayerWLM::UpdateData()
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** PlayPause
|
** Play
|
||||||
**
|
**
|
||||||
** Handles the PlayPause bang.
|
** Handles the Play bang.
|
||||||
**
|
**
|
||||||
*/
|
*/
|
||||||
void CPlayerWLM::PlayPause()
|
void CPlayerWLM::Play()
|
||||||
{
|
{
|
||||||
SendKeyInput(VK_MEDIA_PLAY_PAUSE);
|
SendKeyInput(VK_MEDIA_PLAY_PAUSE);
|
||||||
}
|
}
|
||||||
|
@ -27,22 +27,19 @@ public:
|
|||||||
CPlayerWLM();
|
CPlayerWLM();
|
||||||
~CPlayerWLM();
|
~CPlayerWLM();
|
||||||
|
|
||||||
virtual void Pause() { return PlayPause(); }
|
virtual void UpdateData();
|
||||||
virtual void Play() { return PlayPause(); }
|
|
||||||
virtual void PlayPause();
|
virtual void Pause() { return Play(); }
|
||||||
|
virtual void Play();
|
||||||
virtual void Stop();
|
virtual void Stop();
|
||||||
virtual void Next();
|
virtual void Next();
|
||||||
virtual void Previous();
|
virtual void Previous();
|
||||||
|
|
||||||
virtual void AddInstance(MEASURETYPE type);
|
|
||||||
virtual void RemoveInstance();
|
|
||||||
virtual void UpdateData();
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);
|
static LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);
|
||||||
void SendKeyInput(WORD key);
|
void SendKeyInput(WORD key);
|
||||||
|
|
||||||
HWND m_Window; // Spotify window
|
HWND m_Window;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -111,7 +111,7 @@ void CPlayerWMP::CRemoteHost::PlayStateChange(long NewState)
|
|||||||
{
|
{
|
||||||
case wmppsStopped:
|
case wmppsStopped:
|
||||||
case wmppsMediaEnded:
|
case wmppsMediaEnded:
|
||||||
m_Player->ClearInfo();
|
m_Player->ClearData();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case wmppsPaused:
|
case wmppsPaused:
|
||||||
@ -139,7 +139,7 @@ void CPlayerWMP::CRemoteHost::PlayStateChange(long NewState)
|
|||||||
*/
|
*/
|
||||||
void CPlayerWMP::CRemoteHost::SwitchedToControl()
|
void CPlayerWMP::CRemoteHost::SwitchedToControl()
|
||||||
{
|
{
|
||||||
m_Player->ClearInfo();
|
m_Player->ClearData();
|
||||||
m_Player->Uninitialize();
|
m_Player->Uninitialize();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -150,8 +150,8 @@ void CPlayerWMP::CRemoteHost::SwitchedToControl()
|
|||||||
**
|
**
|
||||||
*/
|
*/
|
||||||
CPlayerWMP::CPlayerWMP() : CPlayer(),
|
CPlayerWMP::CPlayerWMP() : CPlayer(),
|
||||||
m_Initialized(false),
|
m_TrackChanged(false),
|
||||||
m_HasCoverMeasure(false),
|
m_Window(),
|
||||||
m_ComModule(),
|
m_ComModule(),
|
||||||
m_AxWindow(),
|
m_AxWindow(),
|
||||||
m_IPlayer(),
|
m_IPlayer(),
|
||||||
@ -170,41 +170,11 @@ CPlayerWMP::CPlayerWMP() : CPlayer(),
|
|||||||
*/
|
*/
|
||||||
CPlayerWMP::~CPlayerWMP()
|
CPlayerWMP::~CPlayerWMP()
|
||||||
{
|
{
|
||||||
|
g_WMP = NULL;
|
||||||
Uninitialize();
|
Uninitialize();
|
||||||
m_ComModule.Term();
|
m_ComModule.Term();
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
** AddInstance
|
|
||||||
**
|
|
||||||
** Called during initialization of each measure.
|
|
||||||
**
|
|
||||||
*/
|
|
||||||
void CPlayerWMP::AddInstance(MEASURETYPE type)
|
|
||||||
{
|
|
||||||
++m_InstanceCount;
|
|
||||||
|
|
||||||
if (type == MEASURE_COVER)
|
|
||||||
{
|
|
||||||
m_HasCoverMeasure = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
** RemoveInstance
|
|
||||||
**
|
|
||||||
** Called during destruction of each measure.
|
|
||||||
**
|
|
||||||
*/
|
|
||||||
void CPlayerWMP::RemoveInstance()
|
|
||||||
{
|
|
||||||
if (--m_InstanceCount == 0)
|
|
||||||
{
|
|
||||||
g_WMP = NULL;
|
|
||||||
delete this;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** Initialize
|
** Initialize
|
||||||
**
|
**
|
||||||
@ -410,7 +380,9 @@ void CPlayerWMP::UpdateData()
|
|||||||
|
|
||||||
if (m_TrackChanged)
|
if (m_TrackChanged)
|
||||||
{
|
{
|
||||||
|
++m_TrackCount;
|
||||||
m_TrackChanged = false;
|
m_TrackChanged = false;
|
||||||
|
|
||||||
CComPtr<IWMPMedia> spMedia;
|
CComPtr<IWMPMedia> spMedia;
|
||||||
m_IPlayer->get_currentMedia(&spMedia);
|
m_IPlayer->get_currentMedia(&spMedia);
|
||||||
|
|
||||||
@ -462,7 +434,8 @@ void CPlayerWMP::UpdateData()
|
|||||||
{
|
{
|
||||||
m_FilePath = targetPath;
|
m_FilePath = targetPath;
|
||||||
|
|
||||||
// TODO: Better solution for this
|
// Find cover if needed
|
||||||
|
// TODO: Fix temp solution
|
||||||
if (m_HasCoverMeasure || m_InstanceCount == 0)
|
if (m_HasCoverMeasure || m_InstanceCount == 0)
|
||||||
{
|
{
|
||||||
spMedia->getItemInfo(CComBSTR("WM/WMCollectionID"), &val);
|
spMedia->getItemInfo(CComBSTR("WM/WMCollectionID"), &val);
|
||||||
@ -477,37 +450,9 @@ void CPlayerWMP::UpdateData()
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (GetCachedArt())
|
GetCover(m_Artist, m_Title, m_FilePath, m_CoverPath);
|
||||||
{
|
|
||||||
// Cover is in cache, lets use the that
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
TagLib::FileRef fr(url.m_str);
|
|
||||||
if (!fr.isNull() && fr.tag() && GetEmbeddedArt(fr))
|
|
||||||
{
|
|
||||||
// Embedded art found
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get rid of the name and extension from filename
|
|
||||||
std::wstring trackFolder = url;
|
|
||||||
std::wstring::size_type pos = trackFolder.find_last_of(L'\\');
|
|
||||||
if (pos == std::wstring::npos) return;
|
|
||||||
trackFolder.resize(++pos);
|
|
||||||
|
|
||||||
if (GetLocalArt(trackFolder, L"cover") || GetLocalArt(trackFolder, L"folder"))
|
|
||||||
{
|
|
||||||
// Local art found
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Nothing found
|
|
||||||
m_CoverPath.clear();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ExecuteTrackChangeAction();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -538,10 +483,7 @@ void CPlayerWMP::UpdateData()
|
|||||||
*/
|
*/
|
||||||
void CPlayerWMP::Pause()
|
void CPlayerWMP::Pause()
|
||||||
{
|
{
|
||||||
if (m_IPlayer)
|
m_IControls->pause();
|
||||||
{
|
|
||||||
m_IControls->pause();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -552,21 +494,7 @@ void CPlayerWMP::Pause()
|
|||||||
*/
|
*/
|
||||||
void CPlayerWMP::Play()
|
void CPlayerWMP::Play()
|
||||||
{
|
{
|
||||||
if (m_IPlayer)
|
m_IControls->play();
|
||||||
{
|
|
||||||
m_IControls->play();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
** PlayPause
|
|
||||||
**
|
|
||||||
** Handles the PlayPause bang.
|
|
||||||
**
|
|
||||||
*/
|
|
||||||
void CPlayerWMP::PlayPause()
|
|
||||||
{
|
|
||||||
(m_State == PLAYER_PLAYING) ? Pause() : Play();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -577,11 +505,9 @@ void CPlayerWMP::PlayPause()
|
|||||||
*/
|
*/
|
||||||
void CPlayerWMP::Stop()
|
void CPlayerWMP::Stop()
|
||||||
{
|
{
|
||||||
if (m_IPlayer)
|
m_IControls->stop();
|
||||||
{
|
// TODO: FIXME
|
||||||
m_IControls->stop();
|
m_State = PLAYER_STOPPED;
|
||||||
m_State = PLAYER_STOPPED;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -592,10 +518,7 @@ void CPlayerWMP::Stop()
|
|||||||
*/
|
*/
|
||||||
void CPlayerWMP::Next()
|
void CPlayerWMP::Next()
|
||||||
{
|
{
|
||||||
if (m_IPlayer)
|
m_IControls->next();
|
||||||
{
|
|
||||||
m_IControls->next();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -606,10 +529,7 @@ void CPlayerWMP::Next()
|
|||||||
*/
|
*/
|
||||||
void CPlayerWMP::Previous()
|
void CPlayerWMP::Previous()
|
||||||
{
|
{
|
||||||
if (m_IPlayer)
|
m_IControls->previous();
|
||||||
{
|
|
||||||
m_IControls->previous();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -620,10 +540,7 @@ void CPlayerWMP::Previous()
|
|||||||
*/
|
*/
|
||||||
void CPlayerWMP::SetPosition(int position)
|
void CPlayerWMP::SetPosition(int position)
|
||||||
{
|
{
|
||||||
if (m_IPlayer)
|
m_IControls->put_currentPosition((double)position);
|
||||||
{
|
|
||||||
m_IControls->put_currentPosition((double)position);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -634,7 +551,7 @@ void CPlayerWMP::SetPosition(int position)
|
|||||||
*/
|
*/
|
||||||
void CPlayerWMP::SetRating(int rating)
|
void CPlayerWMP::SetRating(int rating)
|
||||||
{
|
{
|
||||||
if (m_IPlayer && (m_State == PLAYER_PLAYING || m_State == PLAYER_PAUSED))
|
if (m_State != PLAYER_STOPPED)
|
||||||
{
|
{
|
||||||
CComPtr<IWMPMedia> spMedia;
|
CComPtr<IWMPMedia> spMedia;
|
||||||
m_IPlayer->get_currentMedia(&spMedia);
|
m_IPlayer->get_currentMedia(&spMedia);
|
||||||
@ -683,10 +600,7 @@ void CPlayerWMP::SetRating(int rating)
|
|||||||
*/
|
*/
|
||||||
void CPlayerWMP::SetVolume(int volume)
|
void CPlayerWMP::SetVolume(int volume)
|
||||||
{
|
{
|
||||||
if (m_IPlayer)
|
m_ISettings->put_volume(volume);
|
||||||
{
|
|
||||||
m_ISettings->put_volume(volume);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -697,14 +611,11 @@ void CPlayerWMP::SetVolume(int volume)
|
|||||||
*/
|
*/
|
||||||
void CPlayerWMP::ClosePlayer()
|
void CPlayerWMP::ClosePlayer()
|
||||||
{
|
{
|
||||||
if (m_IPlayer)
|
HWND wnd = FindWindow(L"WMPlayerApp", NULL);
|
||||||
{
|
|
||||||
HWND wmp = FindWindow(L"WMPlayerApp", NULL);
|
|
||||||
|
|
||||||
if (wmp)
|
if (wnd)
|
||||||
{
|
{
|
||||||
SendMessage(wmp, WM_CLOSE, 0, 0);
|
SendMessage(wnd, WM_CLOSE, 0, 0);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -714,18 +625,7 @@ void CPlayerWMP::ClosePlayer()
|
|||||||
** Handles the OpenPlayer bang.
|
** Handles the OpenPlayer bang.
|
||||||
**
|
**
|
||||||
*/
|
*/
|
||||||
void CPlayerWMP::OpenPlayer()
|
void CPlayerWMP::OpenPlayer(std::wstring& path)
|
||||||
{
|
{
|
||||||
ShellExecute(NULL, L"open", m_PlayerPath.empty() ? L"wmplayer.exe" : m_PlayerPath.c_str(), NULL, NULL, SW_SHOW);
|
ShellExecute(NULL, L"open", path.empty() ? L"wmplayer.exe" : path.c_str(), NULL, NULL, SW_SHOW);
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
** TogglePlayer
|
|
||||||
**
|
|
||||||
** Handles the TogglePlayer bang.
|
|
||||||
**
|
|
||||||
*/
|
|
||||||
void CPlayerWMP::TogglePlayer()
|
|
||||||
{
|
|
||||||
m_IPlayer ? ClosePlayer() : OpenPlayer();
|
|
||||||
}
|
}
|
||||||
|
@ -37,22 +37,18 @@ public:
|
|||||||
CPlayerWMP();
|
CPlayerWMP();
|
||||||
~CPlayerWMP();
|
~CPlayerWMP();
|
||||||
|
|
||||||
|
virtual void UpdateData();
|
||||||
|
|
||||||
virtual void Pause();
|
virtual void Pause();
|
||||||
virtual void Play();
|
virtual void Play();
|
||||||
virtual void PlayPause();
|
|
||||||
virtual void Stop();
|
virtual void Stop();
|
||||||
virtual void Next();
|
virtual void Next();
|
||||||
virtual void Previous();
|
virtual void Previous();
|
||||||
virtual void SetPosition(int position);
|
virtual void SetPosition(int position);
|
||||||
virtual void SetRating(int rating);
|
virtual void SetRating(int rating);
|
||||||
virtual void SetVolume(int volume);
|
virtual void SetVolume(int volume);
|
||||||
virtual void OpenPlayer();
|
virtual void OpenPlayer(std::wstring& path);
|
||||||
virtual void ClosePlayer();
|
virtual void ClosePlayer();
|
||||||
virtual void TogglePlayer();
|
|
||||||
|
|
||||||
virtual void AddInstance(MEASURETYPE type);
|
|
||||||
virtual void RemoveInstance();
|
|
||||||
virtual void UpdateData();
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
class CRemoteHost :
|
class CRemoteHost :
|
||||||
@ -133,11 +129,10 @@ private:
|
|||||||
void Initialize();
|
void Initialize();
|
||||||
void Uninitialize();
|
void Uninitialize();
|
||||||
|
|
||||||
bool m_Initialized;
|
bool m_TrackChanged;
|
||||||
bool m_HasCoverMeasure;
|
|
||||||
HWND m_Window;
|
HWND m_Window;
|
||||||
CComModule m_ComModule;
|
|
||||||
CAxWindow* m_AxWindow;
|
CAxWindow* m_AxWindow;
|
||||||
|
CComModule m_ComModule;
|
||||||
CComPtr<IWMPPlayer4> m_IPlayer;
|
CComPtr<IWMPPlayer4> m_IPlayer;
|
||||||
CComPtr<IWMPControls> m_IControls;
|
CComPtr<IWMPControls> m_IControls;
|
||||||
CComPtr<IWMPSettings> m_ISettings;
|
CComPtr<IWMPSettings> m_ISettings;
|
||||||
|
@ -34,10 +34,8 @@ extern CPlayer* g_Winamp;
|
|||||||
CPlayerWinamp::CPlayerWinamp(WINAMPTYPE type) : CPlayer(),
|
CPlayerWinamp::CPlayerWinamp(WINAMPTYPE type) : CPlayer(),
|
||||||
m_WinampType(type),
|
m_WinampType(type),
|
||||||
m_UseUnicodeAPI(false),
|
m_UseUnicodeAPI(false),
|
||||||
m_HasCoverMeasure(false),
|
|
||||||
m_Window()
|
m_Window()
|
||||||
{
|
{
|
||||||
Initialize();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -48,102 +46,43 @@ CPlayerWinamp::CPlayerWinamp(WINAMPTYPE type) : CPlayer(),
|
|||||||
*/
|
*/
|
||||||
CPlayerWinamp::~CPlayerWinamp()
|
CPlayerWinamp::~CPlayerWinamp()
|
||||||
{
|
{
|
||||||
|
g_Winamp = NULL;
|
||||||
if (m_WinampHandle) CloseHandle(m_WinampHandle);
|
if (m_WinampHandle) CloseHandle(m_WinampHandle);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** AddInstance
|
** CheckWindow
|
||||||
**
|
**
|
||||||
** Called during initialization of each measure.
|
** Try to find Winamp periodically.
|
||||||
**
|
**
|
||||||
*/
|
*/
|
||||||
void CPlayerWinamp::AddInstance(MEASURETYPE type)
|
bool CPlayerWinamp::CheckWindow()
|
||||||
{
|
{
|
||||||
++m_InstanceCount;
|
static DWORD oldTime = 0;
|
||||||
|
DWORD time = GetTickCount();
|
||||||
|
|
||||||
if (type == MEASURE_COVER)
|
// Try to find Winamp window every 5 seconds
|
||||||
|
if (time - oldTime > 5000)
|
||||||
{
|
{
|
||||||
m_HasCoverMeasure = true;
|
oldTime = time;
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
m_Window = FindWindow(L"Winamp v1.x", NULL);
|
||||||
** RemoveInstance
|
if (m_Window)
|
||||||
**
|
|
||||||
** Called during destruction of each measure.
|
|
||||||
**
|
|
||||||
*/
|
|
||||||
void CPlayerWinamp::RemoveInstance()
|
|
||||||
{
|
|
||||||
if (--m_InstanceCount == 0)
|
|
||||||
{
|
|
||||||
g_Winamp = NULL;
|
|
||||||
delete this;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
** Initialize
|
|
||||||
**
|
|
||||||
** Get things ready with Winamp.
|
|
||||||
**
|
|
||||||
*/
|
|
||||||
bool CPlayerWinamp::Initialize()
|
|
||||||
{
|
|
||||||
m_Window = FindWindow(L"Winamp v1.x", NULL);
|
|
||||||
|
|
||||||
if (m_Window)
|
|
||||||
{
|
|
||||||
DWORD pID;
|
|
||||||
GetWindowThreadProcessId(m_Window, &pID);
|
|
||||||
m_WinampHandle = OpenProcess(PROCESS_VM_READ, false, pID);
|
|
||||||
|
|
||||||
if (m_WinampHandle)
|
|
||||||
{
|
{
|
||||||
m_WinampAddress = (LPCVOID)SendMessage(m_Window, WM_WA_IPC, 0, IPC_GET_PLAYING_FILENAME);
|
DWORD pID;
|
||||||
m_UseUnicodeAPI = m_WinampAddress ? true : false;
|
GetWindowThreadProcessId(m_Window, &pID);
|
||||||
return true;
|
m_WinampHandle = OpenProcess(PROCESS_VM_READ, false, pID);
|
||||||
|
|
||||||
|
if (m_WinampHandle)
|
||||||
|
{
|
||||||
|
m_WinampAddress = (LPCVOID)SendMessage(m_Window, WM_WA_IPC, 0, IPC_GET_PLAYING_FILENAME);
|
||||||
|
m_UseUnicodeAPI = m_WinampAddress ? true : false;
|
||||||
|
m_Initialized = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return m_Initialized;
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
** CheckActive
|
|
||||||
**
|
|
||||||
** Check if Winamp is active.
|
|
||||||
**
|
|
||||||
*/
|
|
||||||
bool CPlayerWinamp::CheckActive()
|
|
||||||
{
|
|
||||||
if (m_Window)
|
|
||||||
{
|
|
||||||
if (!IsWindow(m_Window))
|
|
||||||
{
|
|
||||||
m_Window = NULL;
|
|
||||||
CloseHandle(m_WinampHandle);
|
|
||||||
ClearInfo();
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
static DWORD oldTime = 0;
|
|
||||||
DWORD time = GetTickCount();
|
|
||||||
|
|
||||||
// Try to find Winamp window every 5 seconds
|
|
||||||
if (time - oldTime > 5000)
|
|
||||||
{
|
|
||||||
oldTime = time;
|
|
||||||
return Initialize();
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -154,181 +93,175 @@ bool CPlayerWinamp::CheckActive()
|
|||||||
*/
|
*/
|
||||||
void CPlayerWinamp::UpdateData()
|
void CPlayerWinamp::UpdateData()
|
||||||
{
|
{
|
||||||
if (!CheckActive()) return; // Make sure Winamp is running
|
if (m_Initialized || CheckWindow())
|
||||||
|
|
||||||
if (m_TrackChanged)
|
|
||||||
{
|
{
|
||||||
ExecuteTrackChangeAction();
|
int playing = SendMessage(m_Window, WM_WA_IPC, 0, IPC_ISPLAYING);
|
||||||
m_TrackChanged = false;
|
if (playing == 0)
|
||||||
}
|
|
||||||
|
|
||||||
int playing = SendMessage(m_Window, WM_WA_IPC, 0, IPC_ISPLAYING);
|
|
||||||
if (playing == 0)
|
|
||||||
{
|
|
||||||
if (!m_FilePath.empty())
|
|
||||||
{
|
{
|
||||||
ClearInfo();
|
// Make sure Winamp is still active
|
||||||
}
|
if (!IsWindow(m_Window))
|
||||||
return; // Don't continue if stopped
|
{
|
||||||
}
|
m_Initialized = false;
|
||||||
else
|
if (m_WinampHandle) CloseHandle(m_WinampHandle);
|
||||||
{
|
}
|
||||||
m_State = (playing == 1) ? PLAYER_PLAYING : PLAYER_PAUSED;
|
|
||||||
m_Position = SendMessage(m_Window, WM_WA_IPC, 0, IPC_GETOUTPUTTIME) / 1000; // Returns ms, make seconds
|
|
||||||
|
|
||||||
float volume = SendMessage(m_Window, WM_WA_IPC, -666, IPC_SETVOLUME);
|
if (!m_FilePath.empty())
|
||||||
volume /= 2.55f;
|
{
|
||||||
m_Volume = (UINT)volume;
|
ClearData();
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOL ret;
|
// Don't continue if Winamp has quit or is stopped
|
||||||
WCHAR wBuffer[MAX_PATH];
|
return;
|
||||||
char cBuffer[MAX_PATH];
|
|
||||||
|
|
||||||
if (m_UseUnicodeAPI)
|
|
||||||
{
|
|
||||||
ret = ReadProcessMemory(m_WinampHandle, m_WinampAddress, &wBuffer, MAX_PATH, NULL);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// MediaMonkey doesn't support wide IPC messages
|
|
||||||
int pos = SendMessage(m_Window, WM_WA_IPC, 0, IPC_GETLISTPOS);
|
|
||||||
LPCVOID address = (LPCVOID)SendMessage(m_Window, WM_WA_IPC, pos, IPC_GETPLAYLISTFILE);
|
|
||||||
ret = ReadProcessMemory(m_WinampHandle, address, &cBuffer, MAX_PATH, NULL);
|
|
||||||
mbstowcs(wBuffer, cBuffer, MAX_PATH);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!ret)
|
|
||||||
{
|
|
||||||
LSLog(LOG_ERROR, L"Rainmeter", L"NowPlayingPlugin: Failed to read Winamp memory (file).");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (wcscmp(wBuffer, m_FilePath.c_str()) != 0)
|
|
||||||
{
|
|
||||||
m_TrackChanged = true;
|
|
||||||
m_FilePath = wBuffer;
|
|
||||||
m_Rating = SendMessage(m_Window, WM_WA_IPC, 0, IPC_GETRATING);
|
|
||||||
m_Duration = SendMessage(m_Window, WM_WA_IPC, 1, IPC_GETOUTPUTTIME);
|
|
||||||
|
|
||||||
TagLib::FileRef fr(wBuffer);
|
|
||||||
if (!fr.isNull() && fr.tag())
|
|
||||||
{
|
|
||||||
TagLib::Tag* tag = fr.tag();
|
|
||||||
m_Artist = tag->artist().toWString();
|
|
||||||
m_Album = tag->album().toWString();
|
|
||||||
m_Title = tag->title().toWString();
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// TagLib couldn't parse the file, try title instead
|
m_State = (playing == 1) ? PLAYER_PLAYING : PLAYER_PAUSED;
|
||||||
if (m_UseUnicodeAPI)
|
m_Position = SendMessage(m_Window, WM_WA_IPC, 0, IPC_GETOUTPUTTIME) / 1000; // ms to secs
|
||||||
{
|
m_Volume = (SendMessage(m_Window, WM_WA_IPC, -666, IPC_SETVOLUME) * 100) / 255; // 0 - 255 to 0 - 100
|
||||||
LPCVOID address = (LPCVOID)SendMessage(m_Window, WM_WA_IPC, 0, IPC_GET_PLAYING_TITLE);
|
|
||||||
ret = ReadProcessMemory(m_WinampHandle, address, &wBuffer, MAX_PATH, NULL);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
int pos = SendMessage(m_Window, WM_WA_IPC, 0, IPC_GETLISTPOS);
|
|
||||||
LPCVOID address = (LPCVOID)SendMessage(m_Window, WM_WA_IPC, pos, IPC_GETPLAYLISTTITLE);
|
|
||||||
ReadProcessMemory(m_WinampHandle, m_WinampAddress, &cBuffer, MAX_PATH, NULL);
|
|
||||||
ret = mbstowcs(wBuffer, cBuffer, MAX_PATH);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!ret)
|
|
||||||
{
|
|
||||||
LSLog(LOG_ERROR, L"Rainmeter", L"NowPlayingPlugin: Failed to read Winamp memory (title).");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::wstring title = wBuffer;
|
|
||||||
std::wstring::size_type pos = title.find(L". ");
|
|
||||||
|
|
||||||
if (pos != std::wstring::npos && pos < 5)
|
|
||||||
{
|
|
||||||
pos += 2; // Skip ". "
|
|
||||||
title.erase(0, pos);
|
|
||||||
}
|
|
||||||
|
|
||||||
pos = title.find(L" - ");
|
|
||||||
if (pos != std::wstring::npos)
|
|
||||||
{
|
|
||||||
m_Title = title.substr(0, pos);
|
|
||||||
pos += 3; // Skip " - "
|
|
||||||
m_Artist = title.substr(pos);
|
|
||||||
m_Album.clear();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
ClearInfo();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_HasCoverMeasure)
|
BOOL ret;
|
||||||
|
WCHAR wBuffer[MAX_PATH];
|
||||||
|
char cBuffer[MAX_PATH];
|
||||||
|
|
||||||
|
if (m_UseUnicodeAPI)
|
||||||
{
|
{
|
||||||
if (GetCachedArt() || GetEmbeddedArt(fr))
|
ret = ReadProcessMemory(m_WinampHandle, m_WinampAddress, &wBuffer, MAX_PATH, NULL);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// MediaMonkey doesn't support wide IPC messages
|
||||||
|
int pos = SendMessage(m_Window, WM_WA_IPC, 0, IPC_GETLISTPOS);
|
||||||
|
LPCVOID address = (LPCVOID)SendMessage(m_Window, WM_WA_IPC, pos, IPC_GETPLAYLISTFILE);
|
||||||
|
ret = ReadProcessMemory(m_WinampHandle, address, &cBuffer, MAX_PATH, NULL);
|
||||||
|
mbstowcs(wBuffer, cBuffer, MAX_PATH);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!ret)
|
||||||
|
{
|
||||||
|
LSLog(LOG_ERROR, L"Rainmeter", L"NowPlayingPlugin: Failed to read Winamp memory (file).");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (wcscmp(wBuffer, m_FilePath.c_str()) != 0)
|
||||||
|
{
|
||||||
|
++m_TrackCount;
|
||||||
|
m_FilePath = wBuffer;
|
||||||
|
m_Rating = SendMessage(m_Window, WM_WA_IPC, 0, IPC_GETRATING);
|
||||||
|
m_Duration = SendMessage(m_Window, WM_WA_IPC, 1, IPC_GETOUTPUTTIME);
|
||||||
|
|
||||||
|
TagLib::FileRef fr(wBuffer);
|
||||||
|
if (!fr.isNull() && fr.tag())
|
||||||
{
|
{
|
||||||
// Art found in cache or embedded in file
|
TagLib::Tag* tag = fr.tag();
|
||||||
return;
|
m_Artist = tag->artist().toWString();
|
||||||
|
m_Album = tag->album().toWString();
|
||||||
|
m_Title = tag->title().toWString();
|
||||||
}
|
}
|
||||||
|
else
|
||||||
// Get rid of the name and extension from filename
|
|
||||||
std::wstring trackFolder = m_FilePath;
|
|
||||||
std::wstring::size_type pos = trackFolder.find_last_of(L'\\');
|
|
||||||
if (pos == std::wstring::npos) return;
|
|
||||||
trackFolder.resize(++pos);
|
|
||||||
|
|
||||||
if (!m_Album.empty())
|
|
||||||
{
|
{
|
||||||
std::wstring file = m_Album;
|
// TagLib couldn't parse the file, try title instead
|
||||||
std::wstring::size_type end = file.length();
|
if (m_UseUnicodeAPI)
|
||||||
for (pos = 0; pos < end; ++pos)
|
|
||||||
{
|
{
|
||||||
// Replace reserved chars according to Winamp specs
|
LPCVOID address = (LPCVOID)SendMessage(m_Window, WM_WA_IPC, 0, IPC_GET_PLAYING_TITLE);
|
||||||
switch (file[pos])
|
ret = ReadProcessMemory(m_WinampHandle, address, &wBuffer, MAX_PATH, NULL);
|
||||||
{
|
}
|
||||||
case L'?':
|
else
|
||||||
case L'*':
|
{
|
||||||
case L'|':
|
int pos = SendMessage(m_Window, WM_WA_IPC, 0, IPC_GETLISTPOS);
|
||||||
file[pos] = L'_';
|
LPCVOID address = (LPCVOID)SendMessage(m_Window, WM_WA_IPC, pos, IPC_GETPLAYLISTTITLE);
|
||||||
break;
|
ReadProcessMemory(m_WinampHandle, m_WinampAddress, &cBuffer, MAX_PATH, NULL);
|
||||||
|
ret = mbstowcs(wBuffer, cBuffer, MAX_PATH);
|
||||||
case L'/':
|
|
||||||
case L'\\':
|
|
||||||
case L':':
|
|
||||||
file[pos] = L'-';
|
|
||||||
break;
|
|
||||||
|
|
||||||
case L'\"':
|
|
||||||
file[pos] = L'\'';
|
|
||||||
break;
|
|
||||||
|
|
||||||
case L'<':
|
|
||||||
file[pos] = L'(';
|
|
||||||
break;
|
|
||||||
|
|
||||||
case L'>':
|
|
||||||
file[pos] = L')';
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (GetLocalArt(trackFolder, file))
|
if (!ret)
|
||||||
{
|
{
|
||||||
// %album% art file found
|
LSLog(LOG_ERROR, L"Rainmeter", L"NowPlayingPlugin: Failed to read Winamp memory (title).");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::wstring title = wBuffer;
|
||||||
|
std::wstring::size_type pos = title.find(L". ");
|
||||||
|
|
||||||
|
if (pos != std::wstring::npos && pos < 5)
|
||||||
|
{
|
||||||
|
pos += 2; // Skip ". "
|
||||||
|
title.erase(0, pos);
|
||||||
|
}
|
||||||
|
|
||||||
|
pos = title.find(L" - ");
|
||||||
|
if (pos != std::wstring::npos)
|
||||||
|
{
|
||||||
|
m_Title = title.substr(0, pos);
|
||||||
|
pos += 3; // Skip " - "
|
||||||
|
m_Artist = title.substr(pos);
|
||||||
|
m_Album.clear();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ClearData();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (GetLocalArt(trackFolder, L"cover") || GetLocalArt(trackFolder, L"folder"))
|
// Find cover if needed
|
||||||
|
if (m_HasCoverMeasure &&
|
||||||
|
!GetCachedCover(m_Artist, m_Title, m_CoverPath) &&
|
||||||
|
!GetEmbeddedCover(fr, m_CoverPath))
|
||||||
{
|
{
|
||||||
// Local art found
|
std::wstring trackFolder = GetFileFolder(m_FilePath);
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Nothing found
|
if (!m_Album.empty())
|
||||||
m_CoverPath.clear();
|
{
|
||||||
|
// Winamp stores covers usually as %album%.jpg
|
||||||
|
std::wstring file = m_Album;
|
||||||
|
std::wstring::size_type end = file.length();
|
||||||
|
for (std::wstring::size_type pos = 0; pos < end; ++pos)
|
||||||
|
{
|
||||||
|
// Replace reserved chars according to Winamp specs
|
||||||
|
switch (file[pos])
|
||||||
|
{
|
||||||
|
case L'?':
|
||||||
|
case L'*':
|
||||||
|
case L'|':
|
||||||
|
file[pos] = L'_';
|
||||||
|
break;
|
||||||
|
|
||||||
|
case L'/':
|
||||||
|
case L'\\':
|
||||||
|
case L':':
|
||||||
|
file[pos] = L'-';
|
||||||
|
break;
|
||||||
|
|
||||||
|
case L'\"':
|
||||||
|
file[pos] = L'\'';
|
||||||
|
break;
|
||||||
|
|
||||||
|
case L'<':
|
||||||
|
file[pos] = L'(';
|
||||||
|
break;
|
||||||
|
|
||||||
|
case L'>':
|
||||||
|
file[pos] = L')';
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (GetLocalCover(file, trackFolder, m_CoverPath))
|
||||||
|
{
|
||||||
|
// %album% art file found
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!GetLocalCover(L"cover", trackFolder, m_CoverPath) &&
|
||||||
|
!GetLocalCover(L"folder", trackFolder, m_CoverPath))
|
||||||
|
{
|
||||||
|
// Nothing found
|
||||||
|
m_CoverPath.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -341,10 +274,7 @@ void CPlayerWinamp::UpdateData()
|
|||||||
*/
|
*/
|
||||||
void CPlayerWinamp::Pause()
|
void CPlayerWinamp::Pause()
|
||||||
{
|
{
|
||||||
if (m_Window)
|
SendMessage(m_Window, WM_COMMAND, WINAMP_PAUSE, 0);
|
||||||
{
|
|
||||||
SendMessage(m_Window, WM_COMMAND, WINAMP_PAUSE, 0);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -355,21 +285,7 @@ void CPlayerWinamp::Pause()
|
|||||||
*/
|
*/
|
||||||
void CPlayerWinamp::Play()
|
void CPlayerWinamp::Play()
|
||||||
{
|
{
|
||||||
if (m_Window)
|
SendMessage(m_Window, WM_COMMAND, WINAMP_PLAY, 0);
|
||||||
{
|
|
||||||
SendMessage(m_Window, WM_COMMAND, WINAMP_PLAY, 0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
** PlayPause
|
|
||||||
**
|
|
||||||
** Handles the PlayPause bang.
|
|
||||||
**
|
|
||||||
*/
|
|
||||||
void CPlayerWinamp::PlayPause()
|
|
||||||
{
|
|
||||||
(m_State == PLAYER_PLAYING) ? Pause() : Play();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -380,10 +296,7 @@ void CPlayerWinamp::PlayPause()
|
|||||||
*/
|
*/
|
||||||
void CPlayerWinamp::Stop()
|
void CPlayerWinamp::Stop()
|
||||||
{
|
{
|
||||||
if (m_Window)
|
SendMessage(m_Window, WM_COMMAND, WINAMP_STOP, 0);
|
||||||
{
|
|
||||||
SendMessage(m_Window, WM_COMMAND, WINAMP_STOP, 0);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -394,10 +307,7 @@ void CPlayerWinamp::Stop()
|
|||||||
*/
|
*/
|
||||||
void CPlayerWinamp::Next()
|
void CPlayerWinamp::Next()
|
||||||
{
|
{
|
||||||
if (m_Window)
|
SendMessage(m_Window, WM_COMMAND, WINAMP_FASTFWD, 0);
|
||||||
{
|
|
||||||
SendMessage(m_Window, WM_COMMAND, WINAMP_FASTFWD, 0);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -408,10 +318,7 @@ void CPlayerWinamp::Next()
|
|||||||
*/
|
*/
|
||||||
void CPlayerWinamp::Previous()
|
void CPlayerWinamp::Previous()
|
||||||
{
|
{
|
||||||
if (m_Window)
|
SendMessage(m_Window, WM_COMMAND, WINAMP_REWIND, 0);
|
||||||
{
|
|
||||||
SendMessage(m_Window, WM_COMMAND, WINAMP_REWIND, 0);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -422,11 +329,8 @@ void CPlayerWinamp::Previous()
|
|||||||
*/
|
*/
|
||||||
void CPlayerWinamp::SetPosition(int position)
|
void CPlayerWinamp::SetPosition(int position)
|
||||||
{
|
{
|
||||||
if (m_Window)
|
position *= 1000; // To milliseconds
|
||||||
{
|
SendMessage(m_Window, WM_WA_IPC, position, IPC_JUMPTOTIME);
|
||||||
position *= 1000; // To milliseconds
|
|
||||||
SendMessage(m_Window, WM_WA_IPC, position, IPC_JUMPTOTIME);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -437,20 +341,17 @@ void CPlayerWinamp::SetPosition(int position)
|
|||||||
*/
|
*/
|
||||||
void CPlayerWinamp::SetRating(int rating)
|
void CPlayerWinamp::SetRating(int rating)
|
||||||
{
|
{
|
||||||
if (m_Window && (m_State != PLAYER_STOPPED))
|
if (rating < 0)
|
||||||
{
|
{
|
||||||
if (rating < 0)
|
rating = 0;
|
||||||
{
|
|
||||||
rating = 0;
|
|
||||||
}
|
|
||||||
else if (rating > 5)
|
|
||||||
{
|
|
||||||
rating = 5;
|
|
||||||
}
|
|
||||||
|
|
||||||
SendMessage(m_Window, WM_WA_IPC, rating, IPC_SETRATING);
|
|
||||||
m_Rating = rating;
|
|
||||||
}
|
}
|
||||||
|
else if (rating > 5)
|
||||||
|
{
|
||||||
|
rating = 5;
|
||||||
|
}
|
||||||
|
|
||||||
|
SendMessage(m_Window, WM_WA_IPC, rating, IPC_SETRATING);
|
||||||
|
m_Rating = rating;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -461,25 +362,20 @@ void CPlayerWinamp::SetRating(int rating)
|
|||||||
*/
|
*/
|
||||||
void CPlayerWinamp::SetVolume(int volume)
|
void CPlayerWinamp::SetVolume(int volume)
|
||||||
{
|
{
|
||||||
if (m_Window)
|
++volume; // For proper scaling
|
||||||
|
if (volume < 0)
|
||||||
{
|
{
|
||||||
++volume; // For proper scaling
|
volume = 0;
|
||||||
if (volume < 0)
|
|
||||||
{
|
|
||||||
volume = 0;
|
|
||||||
}
|
|
||||||
else if (volume > 100)
|
|
||||||
{
|
|
||||||
volume = 100;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Winamp accepts volume in 0 - 255 range
|
|
||||||
float fVolume = (float)volume;
|
|
||||||
fVolume *= 2.55f;
|
|
||||||
volume = (UINT)fVolume;
|
|
||||||
|
|
||||||
SendMessage(m_Window, WM_WA_IPC, volume, IPC_SETVOLUME);
|
|
||||||
}
|
}
|
||||||
|
else if (volume > 100)
|
||||||
|
{
|
||||||
|
volume = 100;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Winamp accepts volume in 0 - 255 range
|
||||||
|
volume *= 255;
|
||||||
|
volume /= 100;
|
||||||
|
SendMessage(m_Window, WM_WA_IPC, volume, IPC_SETVOLUME);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -490,19 +386,16 @@ void CPlayerWinamp::SetVolume(int volume)
|
|||||||
*/
|
*/
|
||||||
void CPlayerWinamp::ClosePlayer()
|
void CPlayerWinamp::ClosePlayer()
|
||||||
{
|
{
|
||||||
if (m_Window)
|
if (m_WinampType == WA_WINAMP)
|
||||||
{
|
{
|
||||||
if (m_WinampType == WA_WINAMP)
|
SendMessage(m_Window, WM_CLOSE, 0, 0);
|
||||||
|
}
|
||||||
|
else // if (m_WinampType == WA_MEDIAMONKEY)
|
||||||
|
{
|
||||||
|
HWND wnd = FindWindow(L"TFMainWindow", L"MediaMonkey");
|
||||||
|
if (wnd)
|
||||||
{
|
{
|
||||||
SendMessage(m_Window, WM_CLOSE, 0, 0);
|
SendMessage(wnd, WM_CLOSE, 0, 0);
|
||||||
}
|
|
||||||
else // if (m_WinampType == WA_MEDIAMONKEY)
|
|
||||||
{
|
|
||||||
HWND wnd = FindWindow(L"TFMainWindow", L"MediaMonkey");
|
|
||||||
if (wnd)
|
|
||||||
{
|
|
||||||
SendMessage(wnd, WM_CLOSE, 0, 0);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -513,15 +406,15 @@ void CPlayerWinamp::ClosePlayer()
|
|||||||
** Handles the OpenPlayer bang.
|
** Handles the OpenPlayer bang.
|
||||||
**
|
**
|
||||||
*/
|
*/
|
||||||
void CPlayerWinamp::OpenPlayer()
|
void CPlayerWinamp::OpenPlayer(std::wstring& path)
|
||||||
{
|
{
|
||||||
if (m_WinampType == WA_WINAMP)
|
if (m_WinampType == WA_WINAMP)
|
||||||
{
|
{
|
||||||
ShellExecute(NULL, L"open", m_PlayerPath.empty() ? L"winamp.exe" : m_PlayerPath.c_str(), NULL, NULL, SW_SHOW);
|
ShellExecute(NULL, L"open", path.empty() ? L"winamp.exe" : path.c_str(), NULL, NULL, SW_SHOW);
|
||||||
}
|
}
|
||||||
else // if (m_WinampType == WA_MEDIAMONKEY)
|
else // if (m_WinampType == WA_MEDIAMONKEY)
|
||||||
{
|
{
|
||||||
if (m_PlayerPath.empty())
|
if (path.empty())
|
||||||
{
|
{
|
||||||
// Gotta figure out where Winamp is located at
|
// Gotta figure out where Winamp is located at
|
||||||
HKEY hKey;
|
HKEY hKey;
|
||||||
@ -545,7 +438,7 @@ void CPlayerWinamp::OpenPlayer()
|
|||||||
if (type == REG_SZ)
|
if (type == REG_SZ)
|
||||||
{
|
{
|
||||||
ShellExecute(NULL, L"open", data, NULL, NULL, SW_SHOW);
|
ShellExecute(NULL, L"open", data, NULL, NULL, SW_SHOW);
|
||||||
m_PlayerPath = data;
|
path = data;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -554,18 +447,7 @@ void CPlayerWinamp::OpenPlayer()
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
ShellExecute(NULL, L"open", m_PlayerPath.c_str(), NULL, NULL, SW_SHOW);
|
ShellExecute(NULL, L"open", path.c_str(), NULL, NULL, SW_SHOW);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
** TogglePlayer
|
|
||||||
**
|
|
||||||
** Handles the TogglePlayer bang.
|
|
||||||
**
|
|
||||||
*/
|
|
||||||
void CPlayerWinamp::TogglePlayer()
|
|
||||||
{
|
|
||||||
m_Window ? ClosePlayer() : OpenPlayer();
|
|
||||||
}
|
|
||||||
|
@ -33,9 +33,10 @@ public:
|
|||||||
CPlayerWinamp(WINAMPTYPE type);
|
CPlayerWinamp(WINAMPTYPE type);
|
||||||
~CPlayerWinamp();
|
~CPlayerWinamp();
|
||||||
|
|
||||||
|
virtual void UpdateData();
|
||||||
|
|
||||||
virtual void Pause();
|
virtual void Pause();
|
||||||
virtual void Play();
|
virtual void Play();
|
||||||
virtual void PlayPause();
|
|
||||||
virtual void Stop();
|
virtual void Stop();
|
||||||
virtual void Next();
|
virtual void Next();
|
||||||
virtual void Previous();
|
virtual void Previous();
|
||||||
@ -43,18 +44,11 @@ public:
|
|||||||
virtual void SetRating(int rating);
|
virtual void SetRating(int rating);
|
||||||
virtual void SetVolume(int volume);
|
virtual void SetVolume(int volume);
|
||||||
virtual void ClosePlayer();
|
virtual void ClosePlayer();
|
||||||
virtual void OpenPlayer();
|
virtual void OpenPlayer(std::wstring& path);
|
||||||
virtual void TogglePlayer();
|
|
||||||
|
|
||||||
virtual void AddInstance(MEASURETYPE type);
|
|
||||||
virtual void RemoveInstance();
|
|
||||||
virtual void UpdateData();
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool Initialize();
|
bool CheckWindow();
|
||||||
bool CheckActive();
|
|
||||||
|
|
||||||
bool m_HasCoverMeasure;
|
|
||||||
bool m_UseUnicodeAPI;
|
bool m_UseUnicodeAPI;
|
||||||
WINAMPTYPE m_WinampType;
|
WINAMPTYPE m_WinampType;
|
||||||
HWND m_Window; // Winamp window
|
HWND m_Window; // Winamp window
|
||||||
|
@ -12,7 +12,7 @@
|
|||||||
//
|
//
|
||||||
|
|
||||||
VS_VERSION_INFO VERSIONINFO
|
VS_VERSION_INFO VERSIONINFO
|
||||||
FILEVERSION 1,1,0,0
|
FILEVERSION 1,1,1,0
|
||||||
PRODUCTVERSION PRODUCTVER
|
PRODUCTVERSION PRODUCTVER
|
||||||
FILEFLAGSMASK 0x17L
|
FILEFLAGSMASK 0x17L
|
||||||
#ifdef _DEBUG
|
#ifdef _DEBUG
|
||||||
@ -29,7 +29,7 @@ BEGIN
|
|||||||
BLOCK "040904E4"
|
BLOCK "040904E4"
|
||||||
BEGIN
|
BEGIN
|
||||||
VALUE "FileDescription", "NowPlaying Plugin for Rainmeter"
|
VALUE "FileDescription", "NowPlaying Plugin for Rainmeter"
|
||||||
VALUE "FileVersion", "1.1.0.0"
|
VALUE "FileVersion", "1.1.1.0"
|
||||||
VALUE "InternalName", "NowPlaying"
|
VALUE "InternalName", "NowPlaying"
|
||||||
VALUE "LegalCopyright", "Copyright (C) 2011 - Birunthan Mohanathas"
|
VALUE "LegalCopyright", "Copyright (C) 2011 - Birunthan Mohanathas"
|
||||||
VALUE "OriginalFilename", "NowPlaying.dll"
|
VALUE "OriginalFilename", "NowPlaying.dll"
|
||||||
|
@ -255,6 +255,7 @@
|
|||||||
</Link>
|
</Link>
|
||||||
</ItemDefinitionGroup>
|
</ItemDefinitionGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
<ClCompile Include="Cover.cpp" />
|
||||||
<ClCompile Include="NowPlaying.cpp" />
|
<ClCompile Include="NowPlaying.cpp" />
|
||||||
<ClCompile Include="Player.cpp" />
|
<ClCompile Include="Player.cpp" />
|
||||||
<ClCompile Include="PlayerAIMP.cpp" />
|
<ClCompile Include="PlayerAIMP.cpp" />
|
||||||
@ -342,6 +343,7 @@
|
|||||||
</ProjectReference>
|
</ProjectReference>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
<ClInclude Include="Cover.h" />
|
||||||
<ClInclude Include="NowPlaying.h" />
|
<ClInclude Include="NowPlaying.h" />
|
||||||
<ClInclude Include="Player.h" />
|
<ClInclude Include="Player.h" />
|
||||||
<ClInclude Include="PlayerAIMP.h" />
|
<ClInclude Include="PlayerAIMP.h" />
|
||||||
|
@ -264,6 +264,9 @@
|
|||||||
<ClCompile Include="PlayerWLM.cpp">
|
<ClCompile Include="PlayerWLM.cpp">
|
||||||
<Filter>Source Files</Filter>
|
<Filter>Source Files</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
<ClCompile Include="Cover.cpp">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClInclude Include="SDKs\AIMP\aimp2_sdk.h">
|
<ClInclude Include="SDKs\AIMP\aimp2_sdk.h">
|
||||||
@ -320,6 +323,9 @@
|
|||||||
<ClInclude Include="PlayerWLM.h">
|
<ClInclude Include="PlayerWLM.h">
|
||||||
<Filter>Header Files</Filter>
|
<Filter>Header Files</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
|
<ClInclude Include="Cover.h">
|
||||||
|
<Filter>Header Files</Filter>
|
||||||
|
</ClInclude>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ResourceCompile Include="PluginNowPlaying.rc">
|
<ResourceCompile Include="PluginNowPlaying.rc">
|
||||||
|
@ -109,7 +109,7 @@ enum IPCMESSAGE
|
|||||||
// uMsg: WM_USER, wParam: 0 or 1, lParam: 128
|
// uMsg: WM_USER, wParam: 0 or 1, lParam: 128
|
||||||
IPC_SET_REPEAT,
|
IPC_SET_REPEAT,
|
||||||
|
|
||||||
// uMsg: WM_USER, wParam: 0 or 1, lParam: 128 [Sent by/to player]
|
// uMsg: WM_USER, wParam: 0 or 1, lParam: 129 [Sent by/to player]
|
||||||
// The player should send this message when it quits.
|
// The player should send this message when it quits.
|
||||||
// CAD will also send this message on exit. Upon receival, the player should
|
// CAD will also send this message on exit. Upon receival, the player should
|
||||||
// disconnect the communication interface and get ready for a IPC_SET_CALLBACK_HWND message.
|
// disconnect the communication interface and get ready for a IPC_SET_CALLBACK_HWND message.
|
||||||
|
Loading…
x
Reference in New Issue
Block a user