From b3e93c0765c255864d6746cc297544c63c1d1696 Mon Sep 17 00:00:00 2001 From: jsmorley Date: Sun, 15 Aug 2010 13:32:18 +0000 Subject: [PATCH] Fix by elestel to iTunes plugin: iTunesPlugin did not handle AboutToPromptUserToQuitEvent before (when user quit iTunes there will be a quit/don't quit dialog) --- Application/Application.rc | 8 +- Plugins/PluginiTunes/iTunesPlugin.cpp | 123 ++++++++++++++++++++++---- revision-number.h | 2 +- 3 files changed, 110 insertions(+), 23 deletions(-) diff --git a/Application/Application.rc b/Application/Application.rc index 954c699f..64be9782 100644 --- a/Application/Application.rc +++ b/Application/Application.rc @@ -28,8 +28,8 @@ LANGUAGE LANG_FINNISH, SUBLANG_DEFAULT // VS_VERSION_INFO VERSIONINFO - FILEVERSION 1,3,0,502 - PRODUCTVERSION 1,3,0,502 + FILEVERSION 1,3,0,507 + PRODUCTVERSION 1,3,0,507 FILEFLAGSMASK 0x17L #ifdef _DEBUG FILEFLAGS 0x1L @@ -45,12 +45,12 @@ BEGIN BLOCK "040b04b0" BEGIN VALUE "FileDescription", "Rainmeter - A Customizable Resource Meter" - VALUE "FileVersion", "1, 3, 0, 502" + VALUE "FileVersion", "1, 3, 0, 507" VALUE "InternalName", "Rainmeter" VALUE "LegalCopyright", "Copyright (C) 2010 - Rainy" VALUE "OriginalFilename", "Rainmeter.exe" VALUE "ProductName", "Rainmeter" - VALUE "ProductVersion", "1, 3, 0, 502" + VALUE "ProductVersion", "1, 3, 0, 507" END END BLOCK "VarFileInfo" diff --git a/Plugins/PluginiTunes/iTunesPlugin.cpp b/Plugins/PluginiTunes/iTunesPlugin.cpp index 4ec3873a..a3ac84ee 100644 --- a/Plugins/PluginiTunes/iTunesPlugin.cpp +++ b/Plugins/PluginiTunes/iTunesPlugin.cpp @@ -342,6 +342,90 @@ static bool updateCurrentTrack() return (NULL != CurrentTrack); } +static bool iTunesAboutToPromptUserToQuit = false; +// from http://www.codeproject.com/KB/cs/itunestray.aspx?msg=2300786#xx2300786xx +class CiTunesEventHandler : public _IiTunesEvents +{ +private: + long m_dwRefCount; + ITypeInfo* m_pITypeInfo; // Pointer to type information. + +public: + CiTunesEventHandler() + { + m_dwRefCount=0; + ITypeLib* pITypeLib = NULL ; + HRESULT hr = ::LoadRegTypeLib(LIBID_iTunesLib, 1, 5, 0x00, &pITypeLib) ; + // Get type information for the interface of the object. + hr = pITypeLib->GetTypeInfoOfGuid(DIID__IiTunesEvents, &m_pITypeInfo) ; + pITypeLib->Release() ; + } + ~CiTunesEventHandler() + {} + + HRESULT STDMETHODCALLTYPE QueryInterface(REFIID iid, void **ppvObject) + { + if ((iid == IID_IDispatch)||(iid == DIID__IiTunesEvents)) { + m_dwRefCount++; + *ppvObject = this;//(_IiTunesEvents *)this; + return S_OK; + } + if (iid == IID_IUnknown) { + m_dwRefCount++; + *ppvObject = this;//(IUnknown *)this; + return S_OK; + } + return E_NOINTERFACE; + } + ULONG STDMETHODCALLTYPE CiTunesEventHandler::AddRef() + { + InterlockedIncrement(&m_dwRefCount); + return m_dwRefCount; + } + ULONG STDMETHODCALLTYPE Release() + { + InterlockedDecrement(&m_dwRefCount); + if (m_dwRefCount == 0) { + delete this; + return 0; + } + return m_dwRefCount; + } + HRESULT STDMETHODCALLTYPE GetTypeInfoCount(UINT *){return E_NOTIMPL;}; + HRESULT STDMETHODCALLTYPE GetTypeInfo(UINT,LCID,ITypeInfo ** ){return E_NOTIMPL;}; + HRESULT STDMETHODCALLTYPE GetIDsOfNames(const IID &,LPOLESTR * ,UINT,LCID,DISPID *){return E_NOTIMPL;}; + HRESULT STDMETHODCALLTYPE Invoke(DISPID dispidMember, REFIID, LCID,WORD, DISPPARAMS* pdispparams, VARIANT*,EXCEPINFO*, UINT*) + { + switch (dispidMember) //look in the documentation for "enum ITEvent" to get the numbers for the functions you want to implement + { + case 9: // AboutToPromptUserToQuitEvent + CurrentTrack.Release(); + iTunes->Quit(); + iTunes.Release(); + InstanceCreated = false; + iTunesAboutToPromptUserToQuit = true; + break; + default: + break; + } + return S_OK; + } +}; + +static CiTunesEventHandler* iTunesEventHandler; +static void initEventHandler() +{ + IConnectionPointContainer* icpc; + iTunes->QueryInterface(IID_IConnectionPointContainer, (void **)&icpc); + IConnectionPoint* icp; + icpc->FindConnectionPoint(DIID__IiTunesEvents, &icp); + icpc->Release(); + DWORD dwAdvise; + iTunesEventHandler = new CiTunesEventHandler(); + icp->Advise(iTunesEventHandler, &dwAdvise); + icp->Release(); +} + /* This function is called when the measure is initialized. The function must return the maximum value that can be measured. @@ -373,6 +457,7 @@ UINT Initialize(HMODULE instance, LPCTSTR iniFile, LPCTSTR section, UINT id) { InstanceCreated = true; LSLog(LOG_DEBUG, L"Rainmeter", L"iTunesApp initialized successfully."); + initEventHandler(); } else { @@ -410,24 +495,26 @@ UINT Update(UINT id) { if (!CoInitialized || !InstanceCreated) { - // Check if the iTunes window has appeared - if (::FindWindow(L"iTunes", L"iTunes")) - { - if (SUCCEEDED(iTunes.CreateInstance(CLSID_iTunesApp, NULL, CLSCTX_LOCAL_SERVER))) - { - InstanceCreated = true; - LSLog(LOG_DEBUG, L"Rainmeter", L"iTunesApp initialized successfully."); - } - else - { - LSLog(LOG_DEBUG, L"Rainmeter", L"Unable to create the iTunesApp instance."); - return 0; - } - } - else - { - return 0; - } + // Check if the iTunes window has appeared + if (::FindWindow(L"iTunes", L"iTunes")) + { + if (!iTunesAboutToPromptUserToQuit && SUCCEEDED(iTunes.CreateInstance(CLSID_iTunesApp, NULL, CLSCTX_LOCAL_SERVER))) + { + InstanceCreated = true; + LSLog(LOG_DEBUG, L"Rainmeter", L"iTunesApp initialized successfully."); + initEventHandler(); + } + else + { + LSLog(LOG_DEBUG, L"Rainmeter", L"Unable to create the iTunesApp instance."); + return 0; + } + } + else + { + iTunesAboutToPromptUserToQuit = false; + return 0; + } } CCommandIdMap::const_iterator it = CommandIdMap.find(id); diff --git a/revision-number.h b/revision-number.h index e8ebbe10..25e16354 100644 --- a/revision-number.h +++ b/revision-number.h @@ -1,3 +1,3 @@ #pragma once -const int revision_number = 502; +const int revision_number = 507; const bool revision_beta = true; \ No newline at end of file