NowPlayingPlugin:

- Added interface to receive MSN/Windows Live Messenger 'Listening to' notifications sent by various players (e.g Media Player Classic)
- Changes to CAD interface to allow proper supports for players other than MusicBee (e.g. VLC)
- Fixed crash when using the WinAmp interface in multiple skins
This commit is contained in:
Birunthan Mohanathas 2011-06-12 10:05:37 +00:00
parent 7163823971
commit 67cc4c7c6c
11 changed files with 397 additions and 45 deletions

View File

@ -25,6 +25,7 @@
#include "PlayerITunes.h" #include "PlayerITunes.h"
#include "PlayerSpotify.h" #include "PlayerSpotify.h"
#include "PlayerWinamp.h" #include "PlayerWinamp.h"
#include "PlayerWLM.h"
#include "PlayerWMP.h" #include "PlayerWMP.h"
CPlayer* g_AIMP = NULL; CPlayer* g_AIMP = NULL;
@ -33,11 +34,13 @@ CPlayer* g_Foobar = NULL;
CPlayer* g_iTunes = NULL; CPlayer* g_iTunes = NULL;
CPlayer* g_Spotify = NULL; CPlayer* g_Spotify = NULL;
CPlayer* g_Winamp = NULL; CPlayer* g_Winamp = NULL;
CPlayer* g_WLM = NULL;
CPlayer* g_WMP = NULL; CPlayer* g_WMP = NULL;
static MeasureMap g_Values; static MeasureMap g_Values;
static bool g_DisableLeazingZero = false; static bool g_DisableLeazingZero = false;
std::wstring g_CachePath; std::wstring g_CachePath;
std::wstring g_SettingsFile;
void SecondsToTime(UINT seconds, WCHAR* buffer) void SecondsToTime(UINT seconds, WCHAR* buffer)
{ {
@ -69,11 +72,21 @@ UINT Initialize(HMODULE instance, LPCTSTR iniFile, LPCTSTR section, UINT id)
{ {
if (g_Values.empty()) if (g_Values.empty())
{ {
// Get path to temporary folder (for cover art cache)
WCHAR buffer[MAX_PATH]; WCHAR buffer[MAX_PATH];
GetTempPath(MAX_PATH, buffer); GetTempPath(MAX_PATH, buffer);
wcscat(buffer, L"Rainmeter-Cache\\"); wcscat(buffer, L"Rainmeter-Cache\\");
CreateDirectory(buffer, NULL); CreateDirectory(buffer, NULL);
g_CachePath = buffer; g_CachePath = buffer;
// Get path to Plugins.ini (usually %APPDATA%\Rainmeter\Plugins.ini)
std::wstring str = PluginBridge(L"getconfig", iniFile);
if (!str.empty())
{
str += L" \"SETTINGSPATH\"";
g_SettingsFile = PluginBridge(L"getvariable", str.c_str());
g_SettingsFile += L"Plugins.ini";
}
} }
UINT maxValue = 0; UINT maxValue = 0;
@ -124,6 +137,14 @@ UINT Initialize(HMODULE instance, LPCTSTR iniFile, LPCTSTR section, UINT id)
} }
data->player = g_AIMP; data->player = g_AIMP;
} }
else if (_wcsicmp(L"CAD", str) == 0)
{
if (!g_CAD)
{
g_CAD = new CPlayerCAD();
}
data->player = g_CAD;
}
else if (_wcsicmp(L"foobar2000", str) == 0) else if (_wcsicmp(L"foobar2000", str) == 0)
{ {
if (!g_Foobar) if (!g_Foobar)
@ -148,14 +169,6 @@ UINT Initialize(HMODULE instance, LPCTSTR iniFile, LPCTSTR section, UINT id)
} }
data->player = g_Winamp; data->player = g_Winamp;
} }
else if (_wcsicmp(L"MusicBee", str) == 0)
{
if (!g_CAD)
{
g_CAD = new CPlayerCAD();
}
data->player = g_CAD;
}
else if (_wcsicmp(L"Spotify", str) == 0) else if (_wcsicmp(L"Spotify", str) == 0)
{ {
if (!g_Spotify) if (!g_Spotify)
@ -172,6 +185,14 @@ UINT Initialize(HMODULE instance, LPCTSTR iniFile, LPCTSTR section, UINT id)
} }
data->player = g_Winamp; data->player = g_Winamp;
} }
else if (_wcsicmp(L"WLM", str) == 0)
{
if (!g_WLM)
{
g_WLM = new CPlayerWLM();
}
data->player = g_WLM;
}
else if (_wcsicmp(L"WMP", str) == 0) else if (_wcsicmp(L"WMP", str) == 0)
{ {
if (!g_WMP) if (!g_WMP)
@ -182,6 +203,12 @@ UINT Initialize(HMODULE instance, LPCTSTR iniFile, LPCTSTR section, UINT id)
} }
else else
{ {
if (_wcsicmp(L"MusicBee", str) == 0)
{
// TODO: Remove this in a few weeks (left here for MusicBee backwards compatibility)
MessageBox(NULL, L"Due to some internal changes in the NowPlaying plugin, PlayerName=MusicBee is not valid any longer.\n\nPlease edit the skin and change to PlayerName=CAD to continue use with MusicBee.", L"NowPlaying", MB_OK | MB_ICONINFORMATION | MB_TOPMOST);
}
std::wstring error = L"NowPlayingPlugin: PlayerName="; std::wstring error = L"NowPlayingPlugin: PlayerName=";
error += str; error += str;
error += L" in section ["; error += L" in section [";
@ -463,7 +490,6 @@ void ExecuteBang(LPCTSTR bang, UINT id)
{ {
if (wcsnicmp(bang, L"SetPosition", 11) == 0) if (wcsnicmp(bang, L"SetPosition", 11) == 0)
{ {
//(player->GetPosition() * 100) / player->GetDuration()
int position = (_wtoi(arg) * player->GetDuration()) / 100; int position = (_wtoi(arg) * player->GetDuration()) / 100;
if (arg[0] == L'+' || arg[0] == L'-') if (arg[0] == L'+' || arg[0] == L'-')
{ {
@ -505,7 +531,7 @@ void ExecuteBang(LPCTSTR bang, UINT id)
UINT GetPluginVersion() UINT GetPluginVersion()
{ {
// Major * 1000 + Minor // Major * 1000 + Minor
return 1000; return 1001;
} }
/* /*

View File

@ -20,10 +20,11 @@
#include "PlayerCAD.h" #include "PlayerCAD.h"
#include "CAD/cad_sdk.h" #include "CAD/cad_sdk.h"
// This player emulates the CD Art Display IPC API. For now, only MusicBee
// is supported, but this can easily be extended.
extern CPlayer* g_CAD; extern CPlayer* g_CAD;
extern std::wstring g_SettingsFile;
// This player emulates the CD Art Display IPC interface, which is supported by
// MusicBee, VLC (with libcad plugin), and possibly others.
/* /*
** CPlayerCAD ** CPlayerCAD
@ -111,22 +112,44 @@ void CPlayerCAD::Initialize()
hInstance, hInstance,
this); this);
HWND wnd = FindWindow(L"WindowsForms10.Window.8.app.0.378734a", NULL); WCHAR buffer[MAX_PATH];
if (wnd) LPCTSTR file = g_SettingsFile.c_str();
// Read saved settings
GetPrivateProfileString(L"NowPlaying.dll", L"ClassName", NULL, buffer, MAX_PATH, file);
std::wstring className = buffer;
GetPrivateProfileString(L"NowPlaying.dll", L"WindowName", NULL, buffer, MAX_PATH, file);
std::wstring windowName = buffer;
GetPrivateProfileString(L"NowPlaying.dll", L"PlayerPath", NULL, buffer, MAX_PATH, file);
m_PlayerPath = buffer;
LPCTSTR classSz = className.empty() ? NULL : className.c_str();
LPCTSTR windowSz = windowName.empty() ? NULL : windowName.c_str();
if (classSz || windowSz)
{ {
// Let's check if it's MusicBee m_PlayerWindow = FindWindow(classSz, windowSz);
WCHAR buffer[256];
GetWindowText(wnd, buffer, 256);
if (wcsstr(buffer, L"MusicBee"))
{
m_PlayerWindow = wnd;
SendMessage(m_PlayerWindow, WM_USER, (WPARAM)m_Window, IPC_SET_CALLBACK_HWND);
SendMessage(m_PlayerWindow, WM_USER, 0, IPC_GET_CURRENT_TRACK);
m_State = (PLAYERSTATE)SendMessage(m_PlayerWindow, WM_USER, 0, IPC_GET_PLAYER_STATE);
} }
else else
{ {
LSLog(LOG_DEBUG, L"Rainmeter", L"NowPlayingPlugin: MusicBee class found with invalid title."); // TODO: Remove this in a few weeks (left here for MusicBee backwards compatibility)
m_PlayerWindow = FindWindow(L"WindowsForms10.Window.8.app.0.378734a", NULL);
if (m_PlayerWindow)
{
WritePrivateProfileString(L"NowPlaying.dll", L"ClassName", L"WindowsForms10.Window.8.app.0.378734a", file);
}
}
if (m_PlayerWindow)
{
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);
if (m_State != PLAYER_STOPPED)
{
SendMessage(m_PlayerWindow, WM_USER, 0, IPC_GET_CURRENT_TRACK);
} }
} }
} }
@ -220,8 +243,7 @@ LRESULT CALLBACK CPlayerCAD::WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM
data.erase(0, ++len); data.erase(0, ++len);
len = data.find_first_of(L'\t'); len = data.find_first_of(L'\t');
UINT rating = _wtoi(data.substr(0, len).c_str()) + 1; UINT rating = (_wtoi(data.substr(0, len).c_str()) + 1) / 2; // From 0 - 10 to 0 - 5
rating /= 2; // From 0 - 10 to 0 - 5
p->m_Rating = rating; p->m_Rating = rating;
data.erase(0, ++len); data.erase(0, ++len);
@ -248,8 +270,25 @@ LRESULT CALLBACK CPlayerCAD::WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM
p->m_PlayerPath.assign(data, 0, len); p->m_PlayerPath.assign(data, 0, len);
data.erase(0, ++len); data.erase(0, ++len);
p->m_PlayerWindow = FindWindow(className.empty() ? NULL : className.c_str(), LPCTSTR classSz = className.empty() ? NULL : className.c_str();
windowName.empty() ? NULL : windowName.c_str()); LPCTSTR windowSz = windowName.empty() ? NULL : windowName.c_str();
LPCTSTR file = g_SettingsFile.c_str();
WritePrivateProfileString(L"NowPlaying.dll", L"ClassName", classSz, file);
WritePrivateProfileString(L"NowPlaying.dll", L"WindowName", windowSz, file);
WritePrivateProfileString(L"NowPlaying.dll", L"PlayerPath", p->m_PlayerPath.c_str(), file);
p->m_PlayerWindow = FindWindow(classSz, windowSz);
if (p->m_PlayerWindow)
{
p->m_State = (PLAYERSTATE)SendMessage(p->m_PlayerWindow, WM_USER, 0, IPC_GET_PLAYER_STATE);
if (p->m_State != PLAYER_STOPPED)
{
SendMessage(p->m_PlayerWindow, WM_USER, 0, IPC_GET_CURRENT_TRACK);
}
}
} }
} }
} }
@ -436,6 +475,10 @@ void CPlayerCAD::ClosePlayer()
*/ */
void CPlayerCAD::OpenPlayer() void CPlayerCAD::OpenPlayer()
{ {
if (!m_PlayerPath.empty())
{
ShellExecute(NULL, L"open", m_PlayerPath.c_str(), NULL, NULL, SW_SHOW);
}
} }
/* /*

View File

@ -16,8 +16,8 @@
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/ */
#ifndef __PLAYERIPC_H__ #ifndef __PLAYERCAD_H__
#define __PLAYERIPC_H__ #define __PLAYERCAD_H__
#include "Player.h" #include "Player.h"
@ -50,8 +50,8 @@ 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);
bool m_HasCoverMeasure; bool m_HasCoverMeasure;
HWND m_Window; // Our reciever window HWND m_Window;
HWND m_PlayerWindow; // CAD receiver window HWND m_PlayerWindow;
}; };
#endif #endif

View File

@ -94,7 +94,7 @@ void CPlayerFoobar::Initialize()
wc.lpszClassName = L"NowPlayingFoobarClass"; wc.lpszClassName = L"NowPlayingFoobarClass";
RegisterClass(&wc); RegisterClass(&wc);
// Create dummy window // Create window
m_Window = CreateWindow(L"NowPlayingFoobarClass", m_Window = CreateWindow(L"NowPlayingFoobarClass",
L"ReceiverWindow", L"ReceiverWindow",
WS_DISABLED, WS_DISABLED,

View File

@ -0,0 +1,224 @@
/*
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 "PlayerWLM.h"
extern CPlayer* g_WLM;
// This player emulates the MSN/WLM Messenger 'Listening to' interface, which is
// supported by OpenPandora, Last.fm, Media Player Classic, TTPlayer, etc.
/*
** CPlayerWLM
**
** Constructor.
**
*/
CPlayerWLM::CPlayerWLM() : CPlayer(),
m_Window()
{
HINSTANCE hInstance = GetModuleHandle(NULL);
// Create windows class
WNDCLASS wc = {0};
wc.hInstance = hInstance;
wc.lpfnWndProc = WndProc;
wc.lpszClassName = L"MsnMsgrUIManager";
RegisterClass(&wc);
// Create dummy window
m_Window = CreateWindow(L"MsnMsgrUIManager",
L"",
WS_DISABLED,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
NULL,
NULL,
hInstance,
this);
}
/*
** ~CPlayerWLM
**
** Destructor.
**
*/
CPlayerWLM::~CPlayerWLM()
{
DestroyWindow(m_Window);
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)
{
static CPlayerWLM* player;
switch (msg)
{
case WM_CREATE:
{
// Get pointer to the CPlayerWLM class from the CreateWindow call
player = (CPlayerWLM*)((CREATESTRUCT*)lParam)->lpCreateParams;
return 0;
}
case WM_COPYDATA:
{
PCOPYDATASTRUCT cds = (PCOPYDATASTRUCT)lParam;
if (cds->dwData != 1351) return 0;
// lpData: \0Music\0<status>\0<format>\0<title>\0<artist>\0<album>\0
std::wstring data = (WCHAR*)cds->lpData;
// Some players include player name in the beginning. Skip that.
std::wstring::size_type len = data.find(L"\\0Music\\0");
len += 9;
data.erase(0, len); // Get rid of \0Music\0
bool playing = (data[0] == L'1');
if (playing)
{
player->m_State = PLAYER_PLAYING;
data.erase(0, 3); // Get rid of the status
len = data.find_first_of(L'\\');
len += 2;
data.erase(0, len); // Get rid of the format
len = data.find_first_of(L'\\');
player->m_Title = data.substr(0, len);
len += 2;
data.erase(0, len);
len = data.find_first_of(L'\\');
player->m_Artist = data.substr(0, len);
len += 2;
data.erase(0, len);
len = data.find_first_of(L'\\');
player->m_Album = data.substr(0, len);
}
else
{
player->ClearInfo();
}
return 0;
}
}
return DefWindowProc(hWnd, msg, wParam, lParam);
}
void CPlayerWLM::SendKeyInput(WORD key)
{
KEYBDINPUT kbi = {0};
kbi.wVk = key;
kbi.dwExtraInfo = (ULONG_PTR)GetMessageExtraInfo();
INPUT input = {0};
input.type = INPUT_KEYBOARD;
input.ki = kbi;
SendInput(1, &input, sizeof(INPUT));
}
/*
** UpdateData
**
** Called during each update of the main measure.
**
*/
void CPlayerWLM::UpdateData()
{
}
/*
** PlayPause
**
** Handles the PlayPause bang.
**
*/
void CPlayerWLM::PlayPause()
{
SendKeyInput(VK_MEDIA_PLAY_PAUSE);
}
/*
** Stop
**
** Handles the Stop bang.
**
*/
void CPlayerWLM::Stop()
{
SendKeyInput(VK_MEDIA_STOP);
}
/*
** Next
**
** Handles the Next bang.
**
*/
void CPlayerWLM::Next()
{
SendKeyInput(VK_MEDIA_NEXT_TRACK);
}
/*
** Previous
**
** Handles the Previous bang.
**
*/
void CPlayerWLM::Previous()
{
SendKeyInput(VK_MEDIA_PREV_TRACK);
}

View File

@ -0,0 +1,48 @@
/*
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 __PLAYERWLM_H__
#define __PLAYERWLM_H__
#include "Player.h"
class CPlayerWLM : public CPlayer
{
public:
CPlayerWLM();
~CPlayerWLM();
virtual void Pause() { return PlayPause(); }
virtual void Play() { return PlayPause(); }
virtual void PlayPause();
virtual void Stop();
virtual void Next();
virtual void Previous();
virtual void AddInstance(MEASURETYPE type);
virtual void RemoveInstance();
virtual void UpdateData();
private:
static LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);
void SendKeyInput(WORD key);
HWND m_Window; // Spotify window
};
#endif

View File

@ -52,7 +52,7 @@ HRESULT CPlayerWMP::CRemoteHost::GetServiceType(BSTR* pbstrType)
HRESULT hr = E_POINTER; HRESULT hr = E_POINTER;
if (pbstrType) if (pbstrType)
{ {
*pbstrType = SysAllocString(L"Remote"); *pbstrType = SysAllocString(L"RemoteNoDialogs");
hr = *pbstrType? S_OK : E_POINTER; hr = *pbstrType? S_OK : E_POINTER;
} }
return hr; return hr;
@ -222,9 +222,9 @@ void CPlayerWMP::Initialize()
wc.lpszClassName = L"NowPlayingWMPClass"; wc.lpszClassName = L"NowPlayingWMPClass";
RegisterClass(&wc); RegisterClass(&wc);
// Create dummy window // Create the host window
m_Window = CreateWindow(L"NowPlayingWMPClass", m_Window = CreateWindow(L"NowPlayingWMPClass",
L"DummyWindow", L"HostWindow",
WS_DISABLED, WS_DISABLED,
CW_USEDEFAULT, CW_USEDEFAULT,
CW_USEDEFAULT, CW_USEDEFAULT,
@ -337,7 +337,6 @@ void CPlayerWMP::Initialize()
pRemoteHost->Release(); pRemoteHost->Release();
} }
hr = m_IPlayer->get_controls(&m_IControls); hr = m_IPlayer->get_controls(&m_IControls);
if (FAILED(hr)) return; if (FAILED(hr)) return;
@ -356,7 +355,11 @@ void CPlayerWMP::Initialize()
m_State = PLAYER_PAUSED; m_State = PLAYER_PAUSED;
} }
if (m_State != PLAYER_STOPPED)
{
m_TrackChanged = true; m_TrackChanged = true;
}
m_Initialized = true; m_Initialized = true;
} }

View File

@ -21,10 +21,10 @@
#include "Winamp/wa_ipc.h" #include "Winamp/wa_ipc.h"
#include "Winamp/wa_cmd.h" #include "Winamp/wa_cmd.h"
// This player retrieves data through the Winamp IPC API.
extern CPlayer* g_Winamp; extern CPlayer* g_Winamp;
// This player retrieves data through the Winamp IPC interface.
/* /*
** CPlayerWinamp ** CPlayerWinamp
** **
@ -63,7 +63,6 @@ void CPlayerWinamp::AddInstance(MEASURETYPE type)
if (type == MEASURE_COVER) if (type == MEASURE_COVER)
{ {
g_Winamp = NULL;
m_HasCoverMeasure = true; m_HasCoverMeasure = true;
} }
} }
@ -78,6 +77,7 @@ void CPlayerWinamp::RemoveInstance()
{ {
if (--m_InstanceCount == 0) if (--m_InstanceCount == 0)
{ {
g_Winamp = NULL;
delete this; delete this;
} }
} }

View File

@ -12,7 +12,7 @@
// //
VS_VERSION_INFO VERSIONINFO VS_VERSION_INFO VERSIONINFO
FILEVERSION 1,0,0,0 FILEVERSION 1,1,0,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.0.0.0" VALUE "FileVersion", "1.1.0.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"

View File

@ -263,6 +263,7 @@
<ClCompile Include="PlayerITunes.cpp" /> <ClCompile Include="PlayerITunes.cpp" />
<ClCompile Include="PlayerSpotify.cpp" /> <ClCompile Include="PlayerSpotify.cpp" />
<ClCompile Include="PlayerWinamp.cpp" /> <ClCompile Include="PlayerWinamp.cpp" />
<ClCompile Include="PlayerWLM.cpp" />
<ClCompile Include="PlayerWMP.cpp" /> <ClCompile Include="PlayerWMP.cpp" />
<ClCompile Include="SDKs\iTunes\iTunesCOMInterface_i.c" /> <ClCompile Include="SDKs\iTunes\iTunesCOMInterface_i.c" />
<ClCompile Include="StdAfx.cpp" /> <ClCompile Include="StdAfx.cpp" />
@ -349,6 +350,7 @@
<ClInclude Include="PlayerITunes.h" /> <ClInclude Include="PlayerITunes.h" />
<ClInclude Include="PlayerSpotify.h" /> <ClInclude Include="PlayerSpotify.h" />
<ClInclude Include="PlayerWinamp.h" /> <ClInclude Include="PlayerWinamp.h" />
<ClInclude Include="PlayerWLM.h" />
<ClInclude Include="PlayerWMP.h" /> <ClInclude Include="PlayerWMP.h" />
<ClInclude Include="SDKs\AIMP\aimp2_sdk.h" /> <ClInclude Include="SDKs\AIMP\aimp2_sdk.h" />
<ClInclude Include="SDKs\CAD\cad_sdk.h" /> <ClInclude Include="SDKs\CAD\cad_sdk.h" />

View File

@ -261,6 +261,9 @@
<ClCompile Include="StdAfx.cpp"> <ClCompile Include="StdAfx.cpp">
<Filter>Source Files</Filter> <Filter>Source Files</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="PlayerWLM.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClInclude Include="SDKs\AIMP\aimp2_sdk.h"> <ClInclude Include="SDKs\AIMP\aimp2_sdk.h">
@ -314,6 +317,9 @@
<ClInclude Include="StdAfx.h"> <ClInclude Include="StdAfx.h">
<Filter>Header Files</Filter> <Filter>Header Files</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="PlayerWLM.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ResourceCompile Include="PluginNowPlaying.rc"> <ResourceCompile Include="PluginNowPlaying.rc">