From b2159683d761e1de46db4af1ae3bf297eafa6496 Mon Sep 17 00:00:00 2001 From: Geoffroy Couprie Date: Thu, 20 Aug 2009 00:05:17 +0200 Subject: [PATCH] Win7: add support for the taskbar's "oh, look, it's shiny" buttons. We need prettier buttons, and in some cases, the play/pause button's picture isn't updated. --- modules/gui/qt4/main_interface.cpp | 149 +++++++++++++++++++++++++++++ modules/gui/qt4/main_interface.hpp | 9 ++ modules/gui/qt4/qt4.cpp | 4 + modules/gui/qt4/util/qvlcapp.hpp | 37 +++++++ 4 files changed, 199 insertions(+) diff --git a/modules/gui/qt4/main_interface.cpp b/modules/gui/qt4/main_interface.cpp index a4f6da20b5..ea7d0cc799 100644 --- a/modules/gui/qt4/main_interface.cpp +++ b/modules/gui/qt4/main_interface.cpp @@ -58,6 +58,11 @@ #include #include +#ifdef WIN32 + #include + #include +#endif + #include #include /* Wheel event */ @@ -281,6 +286,84 @@ MainInterface::MainInterface( intf_thread_t *_p_intf ) : QVLCMW( _p_intf ) updateGeometry(); resize( sizeHint() ); +#ifdef WIN32 + /*Here is the code for the taskbar thumb buttons + FIXME:We need pretty buttons in 16x16 px that are handled correctly by masks in Qt + FIXME:the play button's picture doesn't changed to pause when clicked + */ + OSVERSIONINFO winVer; + winVer.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); + if( GetVersionEx(&winVer) && winVer.dwMajorVersion > 5 && winVer.dwMajorVersion > 0 ) + { + if(himl = ImageList_Create( 15, //cx + 18, //cy + ILC_COLOR,//flags + 4,//initial nb of images + 0//nb of images that can be added + )) + { + QPixmap img = QPixmap(":/toolbar/previous_b"); + QPixmap img2 = QPixmap(":/toolbar/pause_b"); + QPixmap img3 = QPixmap(":/toolbar/play_b"); + QPixmap img4 = QPixmap(":/toolbar/next_b"); + QBitmap mask = img.createMaskFromColor(Qt::transparent); + QBitmap mask2 = img2.createMaskFromColor(Qt::transparent); + QBitmap mask3 = img3.createMaskFromColor(Qt::transparent); + QBitmap mask4 = img4.createMaskFromColor(Qt::transparent); + + if(-1 == ImageList_Add(himl, img.toWinHBITMAP(QPixmap::PremultipliedAlpha),mask.toWinHBITMAP())) + msg_Err( p_intf, "ImageList_Add failed" ); + if(-1 == ImageList_Add(himl, img2.toWinHBITMAP(QPixmap::PremultipliedAlpha),mask2.toWinHBITMAP())) + msg_Err( p_intf, "ImageList_Add failed" ); + if(-1 == ImageList_Add(himl, img3.toWinHBITMAP(QPixmap::PremultipliedAlpha),mask3.toWinHBITMAP())) + msg_Err( p_intf, "ImageList_Add failed" ); + if(-1 == ImageList_Add(himl, img4.toWinHBITMAP(QPixmap::PremultipliedAlpha),mask4.toWinHBITMAP())) + msg_Err( p_intf, "ImageList_Add failed" ); + } + + CoInitialize( 0 ); + + if( S_OK == CoCreateInstance( &clsid_ITaskbarList, + NULL, CLSCTX_INPROC_SERVER, + &IID_ITaskbarList3, + (void **)&p_taskbl) ) + { + p_taskbl->vt->HrInit(p_taskbl); + + int msg_value = RegisterWindowMessage("TaskbarButtonCreated"); + //msg_Info( p_intf, "msg value: %04x", msg_value ); + + // Define an array of two buttons. These buttons provide images through an + // image list and also provide tooltips. + DWORD dwMask = THB_BITMAP | THB_FLAGS; + + THUMBBUTTON thbButtons[2]; + thbButtons[0].dwMask = dwMask; + thbButtons[0].iId = 0; + thbButtons[0].iBitmap = 0; + thbButtons[0].dwFlags = THBF_HIDDEN; + + thbButtons[1].dwMask = dwMask; + thbButtons[1].iId = 1; + thbButtons[1].iBitmap = 2; + thbButtons[1].dwFlags = THBF_HIDDEN; + + thbButtons[2].dwMask = dwMask; + thbButtons[2].iId = 2; + thbButtons[2].iBitmap = 3; + thbButtons[2].dwFlags = THBF_HIDDEN; + + HRESULT hr = p_taskbl->vt->ThumbBarSetImageList(p_taskbl, GetForegroundWindow(), himl ); + if(S_OK != hr) + msg_Err( p_intf, "ThumbBarSetImageList failed with error %08x", hr ); + if(S_OK != p_taskbl->vt->ThumbBarAddButtons(p_taskbl, GetForegroundWindow(), 3, thbButtons)) + msg_Err( p_intf, "ThumbBarAddButtons failed with error %08x", GetLastError() ); + + } + CONNECT( THEMIM->getIM(), statusChanged( int ), this, changeThumbbarButtons( int ) ); + } +#endif + } MainInterface::~MainInterface() @@ -299,6 +382,13 @@ MainInterface::~MainInterface() delete playlistWidget; } +#ifdef WIN32 + ImageList_Destroy( himl ); + if(p_taskbl) + p_taskbl->vt->Release(p_taskbl); + CoUninitialize(); +#endif + /* Be sure to kill the actionsManager... FIXME */ ActionsManager::killInstance(); @@ -1284,6 +1374,65 @@ void MainInterface::toggleFullScreen( void ) } +//moc doesn't know about #ifdef, so we have to build this method for every platform +void MainInterface::changeThumbbarButtons( int i_status) +{ +#ifdef WIN32 + // Define an array of two buttons. These buttons provide images through an + // image list and also provide tooltips. + DWORD dwMask = THB_BITMAP | THB_FLAGS; + + THUMBBUTTON thbButtons[3]; + //prev + thbButtons[0].dwMask = dwMask; + thbButtons[0].iId = 0; + thbButtons[0].iBitmap = 0; + + //play/pause + thbButtons[1].dwMask = dwMask; + thbButtons[1].iId = 1; + + //next + thbButtons[2].dwMask = dwMask; + thbButtons[2].iId = 2; + thbButtons[2].iBitmap = 3; + + switch( i_status ) + { + case 0: + case END_S: + { + thbButtons[0].dwFlags = THBF_HIDDEN; + thbButtons[1].dwFlags = THBF_HIDDEN; + thbButtons[2].dwFlags = THBF_HIDDEN; + break; + } + case PLAYING_S: + { + thbButtons[0].dwFlags = THBF_ENABLED; + thbButtons[1].dwFlags = THBF_ENABLED; + thbButtons[2].dwFlags = THBF_ENABLED; + thbButtons[1].iBitmap = 1; + break; + } + case PAUSE_S: + { + //thbButtons[0].dwFlags = THBF_ENABLED; + //thbButtons[1].dwFlags = THBF_ENABLED; + //thbButtons[2].dwFlags = THBF_ENABLED; + thbButtons[1].iBitmap = 2; + break; + } + } + + HRESULT hr = p_taskbl->vt->ThumbBarUpdateButtons(p_taskbl, GetForegroundWindow(), 3, thbButtons); + if(S_OK != hr) + msg_Err( p_intf, "ThumbBarUpdateButtons failed with error %08x", hr ); +#else + ; +#endif +} + /***************************************************************************** * PopupMenuCB: callback triggered by the intf-popupmenu playlist variable. * We don't show the menu directly here because we don't want the diff --git a/modules/gui/qt4/main_interface.hpp b/modules/gui/qt4/main_interface.hpp index 274d4a96f0..e2458c957e 100644 --- a/modules/gui/qt4/main_interface.hpp +++ b/modules/gui/qt4/main_interface.hpp @@ -29,6 +29,9 @@ #include "util/qvlcframe.hpp" #include "components/preferences_widgets.hpp" /* First Start */ +#ifdef WIN32 + #include +#endif #include @@ -147,6 +150,11 @@ private: QLabel *nameLabel; QLabel *cryptedLabel; +#ifdef WIN32 + HIMAGELIST himl; + LPTASKBARLIST3 p_taskbl; +#endif + public slots: void undockPlaylist(); void dockPlaylist( pl_dock_e i_pos = PL_BOTTOM ); @@ -157,6 +165,7 @@ public slots: void toggleFullScreen(); void toggleFSC(); void popupMenu( const QPoint& ); + void changeThumbbarButtons( int ); /* Manage the Video Functions from the vout threads */ void getVideoSlot( WId *p_id, int *pi_x, int *pi_y, diff --git a/modules/gui/qt4/qt4.cpp b/modules/gui/qt4/qt4.cpp index 06dea2432c..a6b44c3394 100644 --- a/modules/gui/qt4/qt4.cpp +++ b/modules/gui/qt4/qt4.cpp @@ -359,7 +359,11 @@ static void *Thread( void *obj ) argv[argc] = NULL; } #endif +#ifdef WIN32 + QVLCApp app( p_intf, argc, argv ); +#else QVLCApp app( argc, argv ); +#endif p_intf->p_sys->p_app = &app; diff --git a/modules/gui/qt4/util/qvlcapp.hpp b/modules/gui/qt4/util/qvlcapp.hpp index f43c1b526a..525e979235 100644 --- a/modules/gui/qt4/util/qvlcapp.hpp +++ b/modules/gui/qt4/util/qvlcapp.hpp @@ -30,6 +30,10 @@ #if defined(Q_WS_WIN) # include +# include +# include +# include "qt4.hpp" +# include "input_manager.hpp" #endif class QVLCApp : public QApplication @@ -37,10 +41,20 @@ class QVLCApp : public QApplication Q_OBJECT public: +#ifdef WIN32 + QVLCApp( intf_thread_t *p_intf, int & argc, char ** argv ) : QApplication( argc, argv, true ) + { + connect( this, SIGNAL(quitSignal()), this, SLOT(quit()) ); + CONNECT( this, playPauseSignal(), THEMIM, togglePlayPause() ); + CONNECT( this, prevSignal(), THEMIM, prev() ); + CONNECT( this, nextSignal(), THEMIM, next() ); + } +#else QVLCApp( int & argc, char ** argv ) : QApplication( argc, argv, true ) { connect( this, SIGNAL(quitSignal()), this, SLOT(quit()) ); } +#endif static void triggerQuit() { @@ -58,6 +72,7 @@ public: #endif #if defined(Q_WS_WIN) +#define THBN_CLICKED 0x1800 protected: virtual bool winEventFilter( MSG *msg, long *result ) { @@ -67,6 +82,25 @@ protected: DefWindowProc( msg->hwnd, msg->message, msg->wParam, msg->lParam ); break; + case 0xC0C2: /* TaskbarButtonCreated */ + break; + case WM_COMMAND: + if (HIWORD(msg->wParam) == THBN_CLICKED) + { + switch(LOWORD(msg->wParam)) + { + case 0: + emit prevSignal(); + break; + case 1: + emit playPauseSignal(); + break; + case 2: + emit nextSignal(); + break; + } + } + break; } return false; } @@ -75,6 +109,9 @@ protected: signals: void quitSignal(); + void playPauseSignal(); + void prevSignal(); + void nextSignal(); }; -- 2.39.2