Implemented a more correct way to initialize the ITaskbarList3 interface. We now actually wait for the "TaskbarButtonCreated" message.

This commit is contained in:
LoRd_MuldeR 2011-11-07 17:13:41 +01:00
parent b9a2ebf660
commit 5a32fc3b82
14 changed files with 148 additions and 89 deletions

View File

@ -27,10 +27,10 @@
#define VER_LAMEXP_MAJOR 4
#define VER_LAMEXP_MINOR_HI 0
#define VER_LAMEXP_MINOR_LO 3
#define VER_LAMEXP_TYPE Final
#define VER_LAMEXP_MINOR_LO 4
#define VER_LAMEXP_TYPE Alpha
#define VER_LAMEXP_PATCH 1
#define VER_LAMEXP_BUILD 767
#define VER_LAMEXP_BUILD 769
///////////////////////////////////////////////////////////////////////////////
// Tools versions

View File

@ -891,6 +891,11 @@ bool MainWindow::eventFilter(QObject *obj, QEvent *event)
return false;
}
bool MainWindow::winEvent(MSG *message, long *result)
{
return WinSevenTaskbar::handleWinEvent(message, result);
}
////////////////////////////////////////////////////////////
// Slots
////////////////////////////////////////////////////////////

View File

@ -146,6 +146,7 @@ protected:
bool eventFilter(QObject *obj, QEvent *event);
void resizeEvent(QResizeEvent *event);
void showEvent(QShowEvent *event);
bool winEvent(MSG *message, long *result);
private:
void addFiles(const QStringList &files);

View File

@ -304,6 +304,11 @@ bool ProcessingDialog::eventFilter(QObject *obj, QEvent *event)
return false;
}
bool ProcessingDialog::winEvent(MSG *message, long *result)
{
return WinSevenTaskbar::handleWinEvent(message, result);
}
////////////////////////////////////////////////////////////
// SLOTS
////////////////////////////////////////////////////////////
@ -328,7 +333,6 @@ void ProcessingDialog::initEncoding(void)
checkBox_shutdownComputer->setEnabled(true);
checkBox_shutdownComputer->setChecked(false);
WinSevenTaskbar::initTaskbar();
WinSevenTaskbar::setTaskbarState(this, WinSevenTaskbar::WinSevenTaskbarNormalState);
WinSevenTaskbar::setTaskbarProgress(this, 0, m_pendingJobs.count());
WinSevenTaskbar::setOverlayIcon(this, &QIcon(":/icons/control_play_blue.png"));

View File

@ -74,6 +74,7 @@ protected:
void showEvent(QShowEvent *event);
void closeEvent(QCloseEvent *event);
bool eventFilter(QObject *obj, QEvent *event);
bool winEvent(MSG *message, long *result);
private:
void setCloseButtonEnabled(bool enabled);

View File

@ -27,6 +27,8 @@
#include <QMovie>
#include <QKeyEvent>
#include "WinSevenTaskbar.h"
#define EPS (1.0E-5)
////////////////////////////////////////////////////////////
@ -79,22 +81,26 @@ void SplashScreen::showSplash(QThread *thread)
splashScreen->show();
QApplication::processEvents();
//Setup event loop
QEventLoop *loop = new QEventLoop(splashScreen);
connect(thread, SIGNAL(terminated()), loop, SLOT(quit()), Qt::QueuedConnection);
connect(thread, SIGNAL(finished()), loop, SLOT(quit()), Qt::QueuedConnection);
//Start the thread
thread->start();
bool flag = false;
//Fade in
for(double d = 0.0; d <= 1.0 + EPS; d = d + 0.01)
{
splashScreen->setWindowOpacity(d);
QApplication::processEvents();
if(!flag) flag = WinSevenTaskbar::setTaskbarState(splashScreen, WinSevenTaskbar::WinSevenTaskbarIndeterminateState);
Sleep(6);
}
//Loop while thread is running
while(thread->isRunning())
{
QApplication::processEvents(QEventLoop::AllEvents | QEventLoop::WaitForMoreEvents);
}
loop->exec();
//Fade out
for(double d = 1.0; d >= 0.0; d = d - 0.01)
@ -104,10 +110,14 @@ void SplashScreen::showSplash(QThread *thread)
Sleep(6);
}
//Restore taskbar
WinSevenTaskbar::setTaskbarState(splashScreen, WinSevenTaskbar::WinSevenTaskbarNoState);
//Hide splash
splashScreen->m_canClose = true;
splashScreen->close();
LAMEXP_DELETE(loop);
LAMEXP_DELETE(splashScreen);
}
@ -129,3 +139,8 @@ void SplashScreen::closeEvent(QCloseEvent *event)
{
if(!m_canClose) event->ignore();
}
bool SplashScreen::winEvent(MSG *message, long *result)
{
return WinSevenTaskbar::handleWinEvent(message, result);
}

View File

@ -45,4 +45,5 @@ protected:
void keyPressEvent(QKeyEvent *event);
void keyReleaseEvent(QKeyEvent *event);
void closeEvent(QCloseEvent *event);
bool winEvent(MSG *message, long *result);
};

View File

@ -264,6 +264,11 @@ void UpdateDialog::keyPressEvent(QKeyEvent *e)
}
}
bool UpdateDialog::winEvent(MSG *message, long *result)
{
return WinSevenTaskbar::handleWinEvent(message, result);
}
void UpdateDialog::updateInit(void)
{
setMinimumSize(size());

View File

@ -52,6 +52,7 @@ protected:
void showEvent(QShowEvent *event);
void closeEvent(QCloseEvent *event);
void keyPressEvent(QKeyEvent *e);
bool winEvent(MSG *message, long *result);
const bool m_betaUpdates;

View File

@ -50,9 +50,6 @@ WorkingBanner::WorkingBanner(QWidget *parent)
//Set wait cursor
setCursor(Qt::WaitCursor);
//Init taskbar
WinSevenTaskbar::initTaskbar();
}
////////////////////////////////////////////////////////////
@ -158,6 +155,11 @@ void WorkingBanner::closeEvent(QCloseEvent *event)
if(!m_canClose) event->ignore();
}
bool WorkingBanner::winEvent(MSG *message, long *result)
{
return WinSevenTaskbar::handleWinEvent(message, result);
}
////////////////////////////////////////////////////////////
// SLOTS
////////////////////////////////////////////////////////////

View File

@ -54,4 +54,5 @@ protected:
void keyPressEvent(QKeyEvent *event);
void keyReleaseEvent(QKeyEvent *event);
void closeEvent(QCloseEvent *event);
bool winEvent(MSG *message, long *result);
};

View File

@ -30,6 +30,7 @@
#include "Model_FileList.h"
#include "Model_AudioFile.h"
#include "Encoder_Abstract.h"
#include "WinSevenTaskbar.h"
//Qt includes
#include <QApplication>
@ -127,6 +128,9 @@ static int lamexp_main(int argc, char* argv[])
InitializationThread::selfTest();
}
//Taskbar init
WinSevenTaskbar::init();
//Create models
FileListModel *fileListModel = new FileListModel();
AudioFileModel *metaInfo = new AudioFileModel();
@ -168,6 +172,9 @@ static int lamexp_main(int argc, char* argv[])
LAMEXP_DELETE(metaInfo);
LAMEXP_DELETE(settingsModel);
//Taskbar un-init
WinSevenTaskbar::uninit();
//Final clean-up
qDebug("Shutting down, please wait...\n");

View File

@ -23,81 +23,112 @@
#include <QWidget>
#include <QIcon>
#include <ShObjIdl.h>
#ifdef __ITaskbarList3_INTERFACE_DEFINED__
UINT WinSevenTaskbar::m_winMsg = 0;
ITaskbarList3 *WinSevenTaskbar::m_ptbl = NULL;
WinSevenTaskbar::WinSevenTaskbar(void)
{
throw "Cannot create instance of this class!";
}
WinSevenTaskbar::~WinSevenTaskbar(void)
{
}
void WinSevenTaskbar::initTaskbar(void)
{
OSVERSIONINFOW version;
memset(&version, 0, sizeof(OSVERSIONINFOW));
version.dwOSVersionInfoSize = sizeof(OSVERSIONINFOW);
GetVersionEx(&version);
if(version.dwMajorVersion >= 6 && version.dwMinorVersion >= 1)
{
if(!m_ptbl)
{
ITaskbarList3 *ptbl;
HRESULT hr = CoCreateInstance(CLSID_TaskbarList, NULL, CLSCTX_INPROC_SERVER, IID_PPV_ARGS(&ptbl));
////////////////////////////////////////////////////////////
if (SUCCEEDED(hr))
{
HRESULT hr2 = ptbl->HrInit();
if(SUCCEEDED(hr2))
{
m_ptbl = ptbl;
}
else
{
ptbl->Release();
qWarning("ITaskbarList3::HrInit() has failed.");
}
}
else
{
qWarning("ITaskbarList3 could not be created.");
}
}
}
else
#ifdef __ITaskbarList3_INTERFACE_DEFINED__
void WinSevenTaskbar::init(void)
{
m_winMsg = RegisterWindowMessageW(L"TaskbarButtonCreated");
m_ptbl = NULL;
}
void WinSevenTaskbar::uninit(void)
{
if(m_ptbl)
{
qWarning("This OS doesn't support the ITaskbarList3 interface (needs NT 6.1 or later)");
m_ptbl->Release();
m_ptbl = NULL;
}
}
void WinSevenTaskbar::setTaskbarState(QWidget *window, WinSevenTaskbarState state)
bool WinSevenTaskbar::handleWinEvent(MSG *message, long *result)
{
bool stopEvent = false;
if(message->message == m_winMsg)
{
if(!m_ptbl) createInterface();
*result = (m_ptbl) ? S_OK : S_FALSE;
stopEvent = true;
}
return stopEvent;
}
void WinSevenTaskbar::createInterface(void)
{
if(!m_ptbl)
{
ITaskbarList3 *ptbl = NULL;
HRESULT hr = CoCreateInstance(CLSID_TaskbarList, NULL, CLSCTX_INPROC_SERVER, IID_PPV_ARGS(&ptbl));
if (SUCCEEDED(hr))
{
HRESULT hr2 = ptbl->HrInit();
if(SUCCEEDED(hr2))
{
m_ptbl = ptbl;
/*qDebug("ITaskbarList3::HrInit() succeeded.");*/
}
else
{
ptbl->Release();
qWarning("ITaskbarList3::HrInit() has failed.");
}
}
else
{
qWarning("ITaskbarList3 could not be created.");
}
}
}
bool WinSevenTaskbar::setTaskbarState(QWidget *window, WinSevenTaskbarState state)
{
bool result = false;
if(m_ptbl && window)
{
HRESULT hr = HRESULT(-1);
switch(state)
{
case WinSevenTaskbarNoState:
m_ptbl->SetProgressState(window->winId(), TBPF_NOPROGRESS);
hr = m_ptbl->SetProgressState(window->winId(), TBPF_NOPROGRESS);
break;
case WinSevenTaskbarNormalState:
m_ptbl->SetProgressState(window->winId(), TBPF_NORMAL);
hr = m_ptbl->SetProgressState(window->winId(), TBPF_NORMAL);
break;
case WinSevenTaskbarIndeterminateState:
m_ptbl->SetProgressState(window->winId(), TBPF_INDETERMINATE);
hr = m_ptbl->SetProgressState(window->winId(), TBPF_INDETERMINATE);
break;
case WinSevenTaskbarErrorState:
m_ptbl->SetProgressState(window->winId(), TBPF_ERROR);
hr = m_ptbl->SetProgressState(window->winId(), TBPF_ERROR);
break;
case WinSevenTaskbarPausedState:
m_ptbl->SetProgressState(window->winId(), TBPF_PAUSED);
hr = m_ptbl->SetProgressState(window->winId(), TBPF_PAUSED);
break;
}
result = SUCCEEDED(hr);
}
return result;
}
void WinSevenTaskbar::setTaskbarProgress(QWidget *window, unsigned __int64 currentValue, unsigned __int64 maximumValue)
@ -116,4 +147,15 @@ void WinSevenTaskbar::setOverlayIcon(QWidget *window, QIcon *icon)
}
}
#endif //__ITaskbarList3_INTERFACE_DEFINED__
#else //__ITaskbarList3_INTERFACE_DEFINED__
LAMEXP_COMPILER_WARNING("ITaskbarList3 not defined. Compiling *without* support for Win7 taskbar!")
void WinSevenTaskbar::init(void) {}
void WinSevenTaskbar::uninit(void) {}
bool WinSevenTaskbar::handleWinEvent(MSG *message, long *result) { return false; }
void WinSevenTaskbar::createInterface(void) {}
void WinSevenTaskbar::setTaskbarState(QWidget *window, WinSevenTaskbarState state) {}
void WinSevenTaskbar::setTaskbarProgress(QWidget *window, unsigned __int64 currentValue, unsigned __int64 maximumValue) {}
void WinSevenTaskbar::setOverlayIcon(QWidget *window, QIcon *icon) {}
#endif //__ITaskbarList3_INTERFACE_DEFINED__

View File

@ -22,12 +22,10 @@
#pragma once
#include "Global.h"
#include <ShObjIdl.h>
class QWidget;
class QIcon;
#ifdef __ITaskbarList3_INTERFACE_DEFINED__
struct ITaskbarList3;
class WinSevenTaskbar
{
@ -46,40 +44,16 @@ public:
};
//Public interface
static void initTaskbar(void);
static void setTaskbarState(QWidget *window, WinSevenTaskbarState state);
static bool handleWinEvent(MSG *message, long *result);
static bool setTaskbarState(QWidget *window, WinSevenTaskbarState state);
static void setTaskbarProgress(QWidget *window, unsigned __int64 currentValue, unsigned __int64 maximumValue);
static void setOverlayIcon(QWidget *window, QIcon *icon);
static void init(void);
static void uninit(void);
private:
static ITaskbarList3 *m_ptbl;
static UINT m_winMsg;
static void createInterface(void);
};
#else //__ITaskbarList3_INTERFACE_DEFINED__
LAMEXP_COMPILER_WARNING("ITaskbarList3 not defined. Compiling *without* support for Win7 taskbar!")
class WinSevenTaskbar
{
public:
WinSevenTaskbar(void);
~WinSevenTaskbar(void);
//Taskbar states
enum WinSevenTaskbarState
{
WinSevenTaskbarNoState = 0,
WinSevenTaskbarNormalState = 1,
WinSevenTaskbarIndeterminateState = 2,
WinSevenTaskbarPausedState = 3,
WinSevenTaskbarErrorState = 4
};
//Public interface
static void initTaskbar(void) {}
static void setTaskbarState(QWidget *window, WinSevenTaskbarState state) {}
static void setTaskbarProgress(QWidget *window, unsigned __int64 currentValue, unsigned __int64 maximumValue) {}
static void setOverlayIcon(QWidget *window, QIcon *icon) {}
};
#endif //__ITaskbarList3_INTERFACE_DEFINED__