From a639eb7cc12adc35312e154ff4946131ff80a5b0 Mon Sep 17 00:00:00 2001 From: Birunthan Mohanathas Date: Sun, 17 Jul 2011 10:36:04 +0000 Subject: [PATCH] NowPlayingPlugin: iTunes quits are handled a little more gracefully now (i.e. iTunes should now quit immediately without lag) --- Plugins/PluginNowPlaying/NowPlaying.cpp | 4 +- Plugins/PluginNowPlaying/PlayerITunes.cpp | 100 +++++++++++++++---- Plugins/PluginNowPlaying/PlayerITunes.h | 9 +- Plugins/PluginNowPlaying/PluginNowPlaying.rc | 4 +- 4 files changed, 89 insertions(+), 28 deletions(-) diff --git a/Plugins/PluginNowPlaying/NowPlaying.cpp b/Plugins/PluginNowPlaying/NowPlaying.cpp index ce64cb3b..7d15f5ad 100644 --- a/Plugins/PluginNowPlaying/NowPlaying.cpp +++ b/Plugins/PluginNowPlaying/NowPlaying.cpp @@ -449,7 +449,7 @@ void ExecuteBang(LPCTSTR bang, UINT id) if (!player->IsInitialized()) { - if (_wcsicmp(bang, L"ClosePlayer") == 0 || _wcsicmp(bang, L"TogglePlayer") == 0) + if (_wcsicmp(bang, L"OpenPlayer") == 0 || _wcsicmp(bang, L"TogglePlayer") == 0) { player->OpenPlayer(parent->playerPath); } @@ -478,7 +478,7 @@ void ExecuteBang(LPCTSTR bang, UINT id) { player->Previous(); } - else if (_wcsicmp(bang, L"OpenPlayer") == 0 || _wcsicmp(bang, L"TogglePlayer") == 0) + else if (_wcsicmp(bang, L"ClosePlayer") == 0 || _wcsicmp(bang, L"TogglePlayer") == 0) { player->ClosePlayer(); } diff --git a/Plugins/PluginNowPlaying/PlayerITunes.cpp b/Plugins/PluginNowPlaying/PlayerITunes.cpp index 4c0053e0..f4758932 100644 --- a/Plugins/PluginNowPlaying/PlayerITunes.cpp +++ b/Plugins/PluginNowPlaying/PlayerITunes.cpp @@ -20,6 +20,7 @@ #include "PlayerITunes.h" CPlayer* CPlayerITunes::c_Player = NULL; +extern HINSTANCE g_Instance; /* ** CEventHandler @@ -99,8 +100,8 @@ HRESULT STDMETHODCALLTYPE CPlayerITunes::CEventHandler::Invoke(DISPID dispidMemb break; case ITEventAboutToPromptUserToQuit: - m_Player->m_UserQuitPrompt = true; - m_Player->Uninitialize(); + PostMessage(m_Player->m_CallbackWindow, WM_USER, ITEventAboutToPromptUserToQuit, 0); + SetTimer(m_Player->m_CallbackWindow, TIMER_CHECKACTIVE, 500, NULL); break; } @@ -114,11 +115,30 @@ HRESULT STDMETHODCALLTYPE CPlayerITunes::CEventHandler::Invoke(DISPID dispidMemb ** */ CPlayerITunes::CPlayerITunes() : CPlayer(), - m_UserQuitPrompt(false), + m_CallbackWindow(), + m_iTunesActive(false), m_iTunes(), m_iTunesEvent() { - CoInitializeEx(NULL, COINIT_APARTMENTTHREADED); + // Create windows class + WNDCLASS wc = {0}; + wc.hInstance = g_Instance; + wc.lpfnWndProc = WndProc; + wc.lpszClassName = L"NowPlayingITunesClass"; + RegisterClass(&wc); + + // Create callback window + m_CallbackWindow = CreateWindow(L"NowPlayingITunesClass", + L"CallbackWindow", + WS_DISABLED, + CW_USEDEFAULT, + CW_USEDEFAULT, + CW_USEDEFAULT, + CW_USEDEFAULT, + HWND_MESSAGE, + NULL, + g_Instance, + this); } /* @@ -130,8 +150,11 @@ CPlayerITunes::CPlayerITunes() : CPlayer(), CPlayerITunes::~CPlayerITunes() { c_Player = NULL; + + DestroyWindow(m_CallbackWindow); + UnregisterClass(L"NowPlayingITunesClass", g_Instance); + Uninitialize(); - CoUninitialize(); } /* @@ -179,6 +202,7 @@ void CPlayerITunes::Initialize() if (m_iTunes) { + //SetTimer(NULL, 0, 1000, QuitCallback); m_Initialized = true; // Set up event handler @@ -229,13 +253,51 @@ void CPlayerITunes::Uninitialize() if (m_Initialized) { m_Initialized = false; - if (m_iTunes) - { - m_iTunes->Release(); - delete m_iTunesEvent; - } - ClearData(); + + m_iTunes->Release(); + delete m_iTunesEvent; + } +} + +/* +** WndProc +** +** Window procedure for the callback window. +** +*/ +LRESULT CALLBACK CPlayerITunes::WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) +{ + static CPlayerITunes* player; + + switch (msg) + { + case WM_CREATE: + // Get pointer to the CPlayerITunes class from the CreateWindow call + player = (CPlayerITunes*)(((CREATESTRUCT*)lParam)->lpCreateParams); + return 0; + + case WM_USER: + if (wParam == ITEventAboutToPromptUserToQuit) + { + // Event handler calls this through a PostMessage when iTunes quits + player->Uninitialize(); + } + return 0; + + case WM_TIMER: + if (wParam == TIMER_CHECKACTIVE) + { + if (!FindWindow(L"iTunes", L"iTunes")) + { + player->m_iTunesActive = false; + KillTimer(hwnd, TIMER_CHECKACTIVE); + } + } + return 0; + + default: + return DefWindowProc(hwnd, msg, wParam, lParam); } } @@ -248,23 +310,17 @@ void CPlayerITunes::Uninitialize() bool CPlayerITunes::CheckWindow() { static DWORD oldTime = 0; - DWORD time = GetTickCount(); + DWORD time = GetTickCount(); if (time - oldTime > 5000) { oldTime = time; HWND wnd = FindWindow(L"iTunes", L"iTunes"); - if (wnd) + if (wnd && !m_iTunesActive) { - if (!m_UserQuitPrompt) - { - Initialize(); - } - } - else if (m_UserQuitPrompt) - { - m_UserQuitPrompt = false; + m_iTunesActive = true; + Initialize(); } } @@ -526,9 +582,9 @@ void CPlayerITunes::SetVolume(int volume) */ void CPlayerITunes::ClosePlayer() { - m_UserQuitPrompt = true; m_iTunes->Quit(); Uninitialize(); + SetTimer(m_CallbackWindow, TIMER_CHECKACTIVE, 500, NULL); } /* diff --git a/Plugins/PluginNowPlaying/PlayerITunes.h b/Plugins/PluginNowPlaying/PlayerITunes.h index 7d5d5e81..293c5c8d 100644 --- a/Plugins/PluginNowPlaying/PlayerITunes.h +++ b/Plugins/PluginNowPlaying/PlayerITunes.h @@ -33,6 +33,8 @@ #include #include +const int TIMER_CHECKACTIVE = 1; + class CPlayerITunes : public CPlayer { public: @@ -88,9 +90,12 @@ private: void OnVolumeChange(int volume); bool CheckWindow(); - static CPlayer* c_Player; + static LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam); - bool m_UserQuitPrompt; + static CPlayer* c_Player; + + HWND m_CallbackWindow; + bool m_iTunesActive; IiTunes* m_iTunes; CEventHandler* m_iTunesEvent; }; diff --git a/Plugins/PluginNowPlaying/PluginNowPlaying.rc b/Plugins/PluginNowPlaying/PluginNowPlaying.rc index 32ed3dc1..6da67e5a 100644 --- a/Plugins/PluginNowPlaying/PluginNowPlaying.rc +++ b/Plugins/PluginNowPlaying/PluginNowPlaying.rc @@ -12,7 +12,7 @@ // VS_VERSION_INFO VERSIONINFO - FILEVERSION 1,1,3,0 + FILEVERSION 1,1,3,1 PRODUCTVERSION PRODUCTVER FILEFLAGSMASK 0x17L #ifdef _DEBUG @@ -29,7 +29,7 @@ BEGIN BLOCK "040904E4" BEGIN VALUE "FileDescription", "NowPlaying Plugin for Rainmeter" - VALUE "FileVersion", "1.1.3.0" + VALUE "FileVersion", "1.1.3.1" VALUE "InternalName", "NowPlaying" VALUE "LegalCopyright", "Copyright (C) 2011 - Birunthan Mohanathas" VALUE "OriginalFilename", "NowPlaying.dll"