NowPlaying: Remove dependency on ATL headers

This commit is contained in:
Birunthan Mohanathas 2013-05-09 13:23:52 +03:00
parent 0f6f6d48e5
commit f82b03b583
6 changed files with 239 additions and 198 deletions

View File

@ -429,7 +429,7 @@ void CPlayerITunes::OnTrackChange()
if (SUCCEEDED(hr)) if (SUCCEEDED(hr))
{ {
CComBSTR coverPath = m_TempCoverPath.c_str(); _bstr_t coverPath = m_TempCoverPath.c_str();
hr = artwork->SaveArtworkToFile(coverPath); hr = artwork->SaveArtworkToFile(coverPath);
if (SUCCEEDED(hr)) if (SUCCEEDED(hr))
{ {

View File

@ -22,17 +22,6 @@
#include "Player.h" #include "Player.h"
#include "iTunes/iTunesCOMInterface.h" #include "iTunes/iTunesCOMInterface.h"
#ifndef _ATL_DLL
#define _ATL_DLL
#define _ATL_APARTMENT_THREADED
#define _ATL_NO_EXCEPTIONS
#endif
#include <atlbase.h>
#include <atlcom.h>
#include <atlhost.h>
#include <atlctl.h>
const int TIMER_CHECKACTIVE = 1; const int TIMER_CHECKACTIVE = 1;
class CPlayerITunes : public CPlayer class CPlayerITunes : public CPlayer

View File

@ -22,26 +22,109 @@
CPlayer* CPlayerWMP::c_Player = NULL; CPlayer* CPlayerWMP::c_Player = NULL;
extern HINSTANCE g_Instance; extern HINSTANCE g_Instance;
/* namespace {
** Constructor.
** // Definitions of ATL stuff we need to avoid dependency on atlbase.h (which is not included in free
*/ // versions of Visual Studio).
MIDL_INTERFACE("B6EA2050-048A-11d1-82B9-00C04FB9942E")
IAxWinHostWindow : public IUnknown
{
public:
virtual HRESULT STDMETHODCALLTYPE CreateControl(
LPCOLESTR lpTricsData, HWND hWnd, IStream *pStream) = 0;
virtual HRESULT STDMETHODCALLTYPE CreateControlEx(
LPCOLESTR lpszTricsData, HWND hWnd, IStream* pStream, IUnknown** ppUnk, REFIID iidAdvise,
IUnknown* punkSink) = 0;
virtual HRESULT STDMETHODCALLTYPE AttachControl(IUnknown* pUnkControl, HWND hWnd) = 0;
virtual HRESULT STDMETHODCALLTYPE QueryControl(REFIID riid, void** ppvObject) = 0;
virtual HRESULT STDMETHODCALLTYPE SetExternalDispatch(IDispatch* pDisp) = 0;
virtual HRESULT STDMETHODCALLTYPE SetExternalUIHandler(void* pDisp) = 0;
};
typedef BOOL (WINAPI * AtlAxWinInitFunc)();
typedef HRESULT (WINAPI * AtlAxGetControlFunc)(HWND h, IUnknown** pp);
typedef HRESULT (WINAPI * AtlAxGetHostFunc)(HWND h, IUnknown** pp);
HMODULE InitializeAtlLibrary()
{
static HMODULE s_ATL = LoadLibrary(L"atl");
if (s_ATL)
{
auto atlAxWinInit = (AtlAxWinInitFunc)GetProcAddress(s_ATL, "AtlAxWinInit");
atlAxWinInit();
}
return s_ATL;
}
} // namespace
//
// CPlayerWMP::CRemoteHost
//
CPlayerWMP::CRemoteHost::CRemoteHost() : CPlayerWMP::CRemoteHost::CRemoteHost() :
m_Player() m_Player(),
m_RefCount(0)
{ {
} }
/*
** Destructor.
**
*/
CPlayerWMP::CRemoteHost::~CRemoteHost() CPlayerWMP::CRemoteHost::~CRemoteHost()
{ {
} }
ULONG STDMETHODCALLTYPE CPlayerWMP::CRemoteHost::AddRef()
{
++m_RefCount;
return m_RefCount;
}
ULONG STDMETHODCALLTYPE CPlayerWMP::CRemoteHost::Release()
{
--m_RefCount;
if (m_RefCount == 0)
{
delete this;
return 0;
}
return m_RefCount;
}
HRESULT STDMETHODCALLTYPE CPlayerWMP::CRemoteHost::QueryInterface(IID const& riid, void** object)
{
if (!object)
{
return E_POINTER;
}
if (riid == __uuidof(IUnknown) ||
riid == __uuidof(IServiceProvider))
{
*object = (IServiceProvider*)this;
}
else if (riid == __uuidof(IWMPRemoteMediaServices))
{
*object = (IWMPRemoteMediaServices*)this;
}
else if (riid == __uuidof(IWMPEvents))
{
*object = (IWMPEvents*)this;
}
else
{
*object = NULL;
return E_NOINTERFACE;
}
AddRef();
return S_OK;
}
HRESULT CPlayerWMP::CRemoteHost::QueryService(REFGUID guidService, REFIID riid, void** ppv) HRESULT CPlayerWMP::CRemoteHost::QueryService(REFGUID guidService, REFIID riid, void** ppv)
{ {
return ppv ? QueryInterface(riid, ppv) : E_POINTER; return QueryInterface(riid, ppv);
} }
HRESULT CPlayerWMP::CRemoteHost::GetServiceType(BSTR* pbstrType) HRESULT CPlayerWMP::CRemoteHost::GetServiceType(BSTR* pbstrType)
@ -123,33 +206,22 @@ void CPlayerWMP::CRemoteHost::SwitchedToControl()
m_Player->Uninitialize(); m_Player->Uninitialize();
} }
/* //
** Constructor. // CPlayerWMP
** //
*/
CPlayerWMP::CPlayerWMP() : CPlayer(), CPlayerWMP::CPlayerWMP() : CPlayer(),
m_TrackChanged(false), m_TrackChanged(false),
m_Window(), m_Window(),
m_LastCheckTime(0), m_LastCheckTime(0),
m_ComModule(), m_ConnectionCookie()
m_AxWindow(),
m_IPlayer(),
m_IControls(),
m_ISettings(),
m_IConnectionPoint()
{ {
m_ComModule.Init(NULL, NULL, &LIBID_ATLLib);
} }
/*
** Destructor.
**
*/
CPlayerWMP::~CPlayerWMP() CPlayerWMP::~CPlayerWMP()
{ {
c_Player = NULL; c_Player = NULL;
Uninitialize(); Uninitialize();
m_ComModule.Term();
} }
/* /*
@ -172,130 +244,106 @@ CPlayer* CPlayerWMP::Create()
*/ */
void CPlayerWMP::Initialize() void CPlayerWMP::Initialize()
{ {
// Create windows class HMODULE atl = InitializeAtlLibrary();
WNDCLASS wc = {0}; if (!atl)
wc.hInstance = g_Instance;
wc.lpfnWndProc = DefWindowProc;
wc.lpszClassName = L"NowPlayingWMPClass";
RegisterClass(&wc);
// Create the host window
m_Window = CreateWindow(L"NowPlayingWMPClass",
L"HostWindow",
WS_DISABLED,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
NULL,
NULL,
g_Instance,
NULL);
if (!m_Window) return;
CComPtr<IObjectWithSite> spHostObject;
CComPtr<IAxWinHostWindow> spHost;
CComObject<CRemoteHost>* pRemoteHost;
m_AxWindow = new CAxWindow();
HRESULT hr = m_AxWindow ? S_OK : E_OUTOFMEMORY;
if (SUCCEEDED(hr))
{
m_AxWindow->Create(m_Window, NULL, NULL, WS_CHILD | WS_DISABLED);
if(IsWindow(m_AxWindow->m_hWnd))
{
hr = m_AxWindow->QueryHost(IID_IObjectWithSite, (void**)&spHostObject);
if(!spHostObject.p)
{
hr = E_POINTER;
}
}
}
else
{ {
RmLog(LOG_ERROR, L"NowPlaying: ATL not found");
return; return;
} }
// Create remote host which implements IServiceProvider and IWMPRemoteMediaServices auto atlAxGetControl = (AtlAxGetControlFunc)GetProcAddress(atl, "AtlAxGetControl");
auto atlAxGetHost = (AtlAxGetHostFunc)GetProcAddress(atl, "AtlAxGetHost");
WNDCLASS wc = {0};
wc.hInstance = g_Instance;
wc.lpfnWndProc = DefWindowProc;
wc.lpszClassName = L"NowPlayingWMP";
RegisterClass(&wc);
// Create the container window and the ATL host window.
m_Window = CreateWindow(
L"NowPlayingWMP", L"",
WS_DISABLED,
CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
NULL, NULL, g_Instance, NULL);
HWND window = CreateWindow(
L"AtlAxWin", L"",
WS_DISABLED | WS_CHILD,
CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
m_Window, NULL, g_Instance, NULL);
Microsoft::WRL::ComPtr<IUnknown> axHost;
Microsoft::WRL::ComPtr<IObjectWithSite> hostObject;
HRESULT hr = atlAxGetHost(window, axHost.GetAddressOf());
if (SUCCEEDED(hr)) if (SUCCEEDED(hr))
{ {
hr = CComObject<CRemoteHost>::CreateInstance(&pRemoteHost); hr = axHost.As(&hostObject);
if (pRemoteHost)
{
pRemoteHost->AddRef();
pRemoteHost->m_Player = this;
}
else
{
hr = E_POINTER;
}
} }
// Set site to the remote host Microsoft::WRL::ComPtr<CRemoteHost> remoteHost(new CRemoteHost());
if (SUCCEEDED(hr)) if (SUCCEEDED(hr))
{ {
hr = spHostObject->SetSite((IWMPRemoteMediaServices*)pRemoteHost); remoteHost->m_Player = this;
hr = hostObject->SetSite((IWMPRemoteMediaServices*)remoteHost.Get());
}
Microsoft::WRL::ComPtr<IAxWinHostWindow> axWinHostWindow;
if (SUCCEEDED(hr))
{
hr = axHost.As(&axWinHostWindow);
} }
if (SUCCEEDED(hr)) if (SUCCEEDED(hr))
{ {
hr = m_AxWindow->QueryHost(&spHost); hr = axWinHostWindow->CreateControl(L"{6BF52A52-394A-11D3-B153-00C04F79FAA6}", window, nullptr);
if (!spHost)
{
hr = E_NOINTERFACE;
}
} }
// Create WMP control Microsoft::WRL::ComPtr<IUnknown> axControl;
if (SUCCEEDED(hr)) if (SUCCEEDED(hr))
{ {
hr = spHost->CreateControl(L"{6BF52A52-394A-11D3-B153-00C04F79FAA6}", m_AxWindow->m_hWnd, NULL); hr = atlAxGetControl(window, axControl.GetAddressOf());
} }
if (SUCCEEDED(hr)) if (SUCCEEDED(hr))
{ {
hr = m_AxWindow->QueryControl(&m_IPlayer); hr = axControl.As(&m_IPlayer);
if (!m_IPlayer.p)
{
hr = E_NOINTERFACE;
}
} }
// Connect the event interface // Connect the event interface.
CComPtr<IConnectionPointContainer> spConnectionContainer; Microsoft::WRL::ComPtr<IConnectionPointContainer> wmpPlayerConnectionContainer;
hr = m_IPlayer->QueryInterface(&spConnectionContainer);
if (SUCCEEDED(hr)) if (SUCCEEDED(hr))
{ {
hr = spConnectionContainer->FindConnectionPoint( __uuidof(IWMPEvents), &m_IConnectionPoint); hr = m_IPlayer.As(&wmpPlayerConnectionContainer);
} }
if (SUCCEEDED(hr)) if (SUCCEEDED(hr))
{ {
DWORD adviseCookie; hr = wmpPlayerConnectionContainer->FindConnectionPoint(
hr = m_IConnectionPoint->Advise(pRemoteHost->GetUnknown(), &adviseCookie); __uuidof(IWMPEvents), m_IConnectionPoint.GetAddressOf());
}
if ((FAILED(hr)) || !adviseCookie) if (SUCCEEDED(hr))
{ {
m_IConnectionPoint = NULL; hr = m_IConnectionPoint->Advise(remoteHost->GetUnknown(), &m_ConnectionCookie);
} if (!m_ConnectionCookie)
}
// Release remote host object
if (pRemoteHost)
{ {
pRemoteHost->Release(); hr = E_FAIL;
}
} }
if (SUCCEEDED(hr))
{
hr = m_IPlayer->get_controls(&m_IControls); hr = m_IPlayer->get_controls(&m_IControls);
if (FAILED(hr)) return; }
if (SUCCEEDED(hr))
{
hr = m_IPlayer->get_settings(&m_ISettings); hr = m_IPlayer->get_settings(&m_ISettings);
if (FAILED(hr)) return; }
// Get player state if (SUCCEEDED(hr))
{
WMPPlayState state; WMPPlayState state;
m_IPlayer->get_playState(&state); m_IPlayer->get_playState(&state);
if (state == wmppsPlaying) if (state == wmppsPlaying)
@ -314,6 +362,11 @@ void CPlayerWMP::Initialize()
m_Initialized = true; m_Initialized = true;
} }
else
{
Uninitialize();
}
}
/* /*
** Close the interface with WMP. ** Close the interface with WMP.
@ -324,13 +377,18 @@ void CPlayerWMP::Uninitialize()
if (m_Initialized) if (m_Initialized)
{ {
m_Initialized = false; m_Initialized = false;
m_IControls.Release();
m_ISettings.Release(); if (m_ConnectionCookie)
m_IPlayer.Release(); {
m_AxWindow->DestroyWindow(); m_IConnectionPoint->Unadvise(m_ConnectionCookie);
delete m_AxWindow; m_ConnectionCookie = 0;
}
m_IControls.Reset();
m_ISettings.Reset();
m_IConnectionPoint.Reset();
m_IPlayer.Reset();
DestroyWindow(m_Window); DestroyWindow(m_Window);
UnregisterClass(L"NowPlayingWMPClass", g_Instance);
} }
} }
@ -358,22 +416,23 @@ void CPlayerWMP::UpdateData()
{ {
m_TrackChanged = false; m_TrackChanged = false;
CComPtr<IWMPMedia> spMedia; Microsoft::WRL::ComPtr<IWMPMedia> spMedia;
m_IPlayer->get_currentMedia(&spMedia); m_IPlayer->get_currentMedia(spMedia.GetAddressOf());
if (spMedia) if (spMedia)
{ {
BSTR val; BSTR val;
spMedia->getItemInfo(CComBSTR(L"Artist"), &val);
spMedia->getItemInfo(_bstr_t(L"Artist"), &val);
m_Artist = val; m_Artist = val;
spMedia->getItemInfo(CComBSTR(L"Title"), &val); spMedia->getItemInfo(_bstr_t(L"Title"), &val);
m_Title = val; m_Title = val;
spMedia->getItemInfo(CComBSTR(L"Album"), &val); spMedia->getItemInfo(_bstr_t(L"Album"), &val);
m_Album = val; m_Album = val;
spMedia->getItemInfo(CComBSTR(L"UserRating"), &val); spMedia->getItemInfo(_bstr_t(L"UserRating"), &val);
int rating = _wtoi(val); int rating = _wtoi(val);
if (rating > 75) if (rating > 75)
@ -397,10 +456,10 @@ void CPlayerWMP::UpdateData()
m_Rating = rating; m_Rating = rating;
} }
spMedia->getItemInfo(CComBSTR(L"WM/TrackNumber"), &val); spMedia->getItemInfo(_bstr_t(L"WM/TrackNumber"), &val);
m_Number = (UINT)_wtoi(val); m_Number = (UINT)_wtoi(val);
spMedia->getItemInfo(CComBSTR(L"WM/Year"), &val); spMedia->getItemInfo(_bstr_t(L"WM/Year"), &val);
m_Year = (UINT)_wtoi(val); m_Year = (UINT)_wtoi(val);
double duration; double duration;
@ -420,7 +479,7 @@ void CPlayerWMP::UpdateData()
// TODO: Fix temp solution // TODO: Fix temp solution
if (m_Measures & MEASURE_COVER || m_InstanceCount == 0) if (m_Measures & MEASURE_COVER || m_InstanceCount == 0)
{ {
spMedia->getItemInfo(CComBSTR(L"WM/WMCollectionID"), &val); spMedia->getItemInfo(_bstr_t(L"WM/WMCollectionID"), &val);
targetPath.resize(targetPath.find_last_of(L'\\') + 1); targetPath.resize(targetPath.find_last_of(L'\\') + 1);
targetPath += L"AlbumArt_"; targetPath += L"AlbumArt_";
targetPath += val; targetPath += val;
@ -525,8 +584,8 @@ void CPlayerWMP::SetRating(int rating)
{ {
if (m_State != STATE_STOPPED) if (m_State != STATE_STOPPED)
{ {
CComPtr<IWMPMedia> spMedia; Microsoft::WRL::ComPtr<IWMPMedia> spMedia;
m_IPlayer->get_currentMedia(&spMedia); m_IPlayer->get_currentMedia(spMedia.GetAddressOf());
if (spMedia) if (spMedia)
{ {
@ -558,7 +617,7 @@ void CPlayerWMP::SetRating(int rating)
break; break;
} }
spMedia->setItemInfo(CComBSTR(L"UserRating"), val); spMedia->setItemInfo(_bstr_t(L"UserRating"), val);
m_Rating = rating; m_Rating = rating;
} }
} }

View File

@ -20,18 +20,8 @@
#define __PLAYERWMP_H__ #define __PLAYERWMP_H__
#include "Player.h" #include "Player.h"
#ifndef _ATL_DLL
#define _ATL_DLL
#define _ATL_APARTMENT_THREADED
#define _ATL_NO_EXCEPTIONS
#endif
#include <wmp.h> #include <wmp.h>
#include <atlbase.h> #include <wrl/client.h>
#include <atlcom.h>
#include <atlhost.h>
#include <atlctl.h>
class CPlayerWMP : public CPlayer class CPlayerWMP : public CPlayer
{ {
@ -58,7 +48,6 @@ protected:
private: private:
class CRemoteHost : class CRemoteHost :
public CComObjectRootEx<CComSingleThreadModel>,
public IServiceProvider, public IServiceProvider,
public IWMPRemoteMediaServices, public IWMPRemoteMediaServices,
public IWMPEvents public IWMPEvents
@ -69,11 +58,12 @@ private:
CPlayerWMP* m_Player; CPlayerWMP* m_Player;
BEGIN_COM_MAP(CRemoteHost) IUnknown* GetUnknown() const { return (IServiceProvider*)this; }
COM_INTERFACE_ENTRY(IServiceProvider)
COM_INTERFACE_ENTRY(IWMPRemoteMediaServices) // IUnknown
COM_INTERFACE_ENTRY(IWMPEvents) virtual HRESULT STDMETHODCALLTYPE QueryInterface(REFIID uuid, void** object) override;
END_COM_MAP() virtual ULONG STDMETHODCALLTYPE AddRef() override;
virtual ULONG STDMETHODCALLTYPE Release() override;
// IServiceProvider // IServiceProvider
STDMETHOD(QueryService)(REFGUID guidService, REFIID riid, void** ppv); STDMETHOD(QueryService)(REFGUID guidService, REFIID riid, void** ppv);
@ -130,6 +120,9 @@ private:
void STDMETHODCALLTYPE MouseDown(short nButton, short nShiftState, long fX, long fY) {} void STDMETHODCALLTYPE MouseDown(short nButton, short nShiftState, long fX, long fY) {}
void STDMETHODCALLTYPE MouseMove(short nButton, short nShiftState, long fX, long fY) {} void STDMETHODCALLTYPE MouseMove(short nButton, short nShiftState, long fX, long fY) {}
void STDMETHODCALLTYPE MouseUp(short nButton, short nShiftState, long fX, long fY) {} void STDMETHODCALLTYPE MouseUp(short nButton, short nShiftState, long fX, long fY) {}
private:
ULONG m_RefCount;
}; };
void Initialize(); void Initialize();
@ -141,12 +134,11 @@ private:
HWND m_Window; HWND m_Window;
DWORD m_LastCheckTime; DWORD m_LastCheckTime;
CComModule m_ComModule; Microsoft::WRL::ComPtr<IWMPPlayer4> m_IPlayer;
CAxWindow* m_AxWindow; Microsoft::WRL::ComPtr<IWMPControls> m_IControls;
CComPtr<IWMPPlayer4> m_IPlayer; Microsoft::WRL::ComPtr<IWMPSettings> m_ISettings;
CComPtr<IWMPControls> m_IControls; Microsoft::WRL::ComPtr<IConnectionPoint> m_IConnectionPoint;
CComPtr<IWMPSettings> m_ISettings; DWORD m_ConnectionCookie;
CComPtr<IConnectionPoint> m_IConnectionPoint;
}; };
#endif #endif

View File

@ -24,7 +24,7 @@
<AdditionalIncludeDirectories>.\sha2;.\taglib;.\taglib\toolkit;.\taglib\mpeg\id3v2\frames;.\taglib\ogg;.\taglib\asf;.\taglib\mp4;.\taglib\ogg\vorbis;.\taglib\ogg\flac;.\taglib\ogg\speex;.\taglib\riff;.\taglib\riff\wav;.\taglib\riff\aiff;.\taglib\flac;.\taglib\mpeg;.\taglib\mpeg\id3v1;.\taglib\mpeg\id3v2;.\taglib\mpc;.\taglib\ape;.\taglib\trueaudio;.\taglib\wavpack;.\SDKs\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> <AdditionalIncludeDirectories>.\sha2;.\taglib;.\taglib\toolkit;.\taglib\mpeg\id3v2\frames;.\taglib\ogg;.\taglib\asf;.\taglib\mp4;.\taglib\ogg\vorbis;.\taglib\ogg\flac;.\taglib\ogg\speex;.\taglib\riff;.\taglib\riff\wav;.\taglib\riff\aiff;.\taglib\flac;.\taglib\mpeg;.\taglib\mpeg\id3v1;.\taglib\mpeg\id3v2;.\taglib\mpc;.\taglib\ape;.\taglib\trueaudio;.\taglib\wavpack;.\SDKs\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ClCompile> </ClCompile>
<Link> <Link>
<AdditionalDependencies>Psapi.lib;WinInet.lib;%(AdditionalDependencies)</AdditionalDependencies> <AdditionalDependencies>Psapi.lib;WinInet.lib;comsuppwd.lib;%(AdditionalDependencies)</AdditionalDependencies>
<RuntimeTypeInfo>true</RuntimeTypeInfo> <RuntimeTypeInfo>true</RuntimeTypeInfo>
</Link> </Link>
</ItemDefinitionGroup> </ItemDefinitionGroup>
@ -35,7 +35,7 @@
<AdditionalIncludeDirectories>.\sha2;.\taglib;.\taglib\toolkit;.\taglib\mpeg\id3v2\frames;.\taglib\ogg;.\taglib\asf;.\taglib\mp4;.\taglib\ogg\vorbis;.\taglib\ogg\flac;.\taglib\ogg\speex;.\taglib\riff;.\taglib\riff\wav;.\taglib\riff\aiff;.\taglib\flac;.\taglib\mpeg;.\taglib\mpeg\id3v1;.\taglib\mpeg\id3v2;.\taglib\mpc;.\taglib\ape;.\taglib\trueaudio;.\taglib\wavpack;.\SDKs\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> <AdditionalIncludeDirectories>.\sha2;.\taglib;.\taglib\toolkit;.\taglib\mpeg\id3v2\frames;.\taglib\ogg;.\taglib\asf;.\taglib\mp4;.\taglib\ogg\vorbis;.\taglib\ogg\flac;.\taglib\ogg\speex;.\taglib\riff;.\taglib\riff\wav;.\taglib\riff\aiff;.\taglib\flac;.\taglib\mpeg;.\taglib\mpeg\id3v1;.\taglib\mpeg\id3v2;.\taglib\mpc;.\taglib\ape;.\taglib\trueaudio;.\taglib\wavpack;.\SDKs\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ClCompile> </ClCompile>
<Link> <Link>
<AdditionalDependencies>Psapi.lib;WinInet.lib;%(AdditionalDependencies)</AdditionalDependencies> <AdditionalDependencies>Psapi.lib;WinInet.lib;comsuppwd.lib;%(AdditionalDependencies)</AdditionalDependencies>
<RuntimeTypeInfo>true</RuntimeTypeInfo> <RuntimeTypeInfo>true</RuntimeTypeInfo>
</Link> </Link>
</ItemDefinitionGroup> </ItemDefinitionGroup>
@ -47,7 +47,7 @@
<ExceptionHandling>false</ExceptionHandling> <ExceptionHandling>false</ExceptionHandling>
</ClCompile> </ClCompile>
<Link> <Link>
<AdditionalDependencies>Psapi.lib;WinInet.lib;%(AdditionalDependencies)</AdditionalDependencies> <AdditionalDependencies>Psapi.lib;WinInet.lib;comsuppw.lib;%(AdditionalDependencies)</AdditionalDependencies>
<RuntimeTypeInfo>true</RuntimeTypeInfo> <RuntimeTypeInfo>true</RuntimeTypeInfo>
</Link> </Link>
</ItemDefinitionGroup> </ItemDefinitionGroup>
@ -59,7 +59,7 @@
<ExceptionHandling>false</ExceptionHandling> <ExceptionHandling>false</ExceptionHandling>
</ClCompile> </ClCompile>
<Link> <Link>
<AdditionalDependencies>Psapi.lib;WinInet.lib;%(AdditionalDependencies)</AdditionalDependencies> <AdditionalDependencies>Psapi.lib;WinInet.lib;comsuppw.lib;%(AdditionalDependencies)</AdditionalDependencies>
<RuntimeTypeInfo>true</RuntimeTypeInfo> <RuntimeTypeInfo>true</RuntimeTypeInfo>
</Link> </Link>
</ItemDefinitionGroup> </ItemDefinitionGroup>

View File

@ -23,6 +23,7 @@
#include <Windows.h> #include <Windows.h>
#include <WinInet.h> #include <WinInet.h>
#include <Psapi.h> #include <Psapi.h>
#include <comutil.h>
// STL // STL
#include <string> #include <string>