// ======================================================================================= // WndprocRebar is called once every second during playback // ======================================================================================= // In Toolbar::Create() the progress bar is called the Seekbar //////////////////////////////////////////////////////////////////////////////// // Plainamp, Open source Winamp core // // Copyright © 2005 Sebastian Pipping // // --> http://www.hartwork.org // // This source code is released under the GNU General Public License (GPL). // See GPL.txt for details. Any non-GPL usage is strictly forbidden. //////////////////////////////////////////////////////////////////////////////// #include "Rebar.h" #include "Font.h" #include "Main.h" #include "Playlist.h" #include "Playback.h" #include "Console.h" #include "Util.h" #include "Config.h" #include "Winamp/wa_ipc.h" #include "Resources/resrc1.h" #define BAND_ORDER 1 #define BAND_EQ 2 #define BAND_SEEK 3 #define BAND_VOL 4 #define BAND_PAN 5 #define BAND_BUTTONS 6 #define BAND_VIS 7 #define BAND_FIRST BAND_ORDER #define BAND_LAST BAND_VIS #define IMAGE_PREV 0 #define IMAGE_PLAY 1 #define IMAGE_PAUSE 2 #define IMAGE_STOP 3 #define IMAGE_NEXT 4 #define IMAGE_OPEN 5 HWND WindowRebar = NULL; // extern int iRebarHeight = 40; // extern HMENU rebar_menu = NULL; WNDPROC WndprocRebarBackup = NULL; LRESULT CALLBACK WndprocRebar( HWND hwnd, UINT message, WPARAM wp, LPARAM lp ); HWND WindowOrder = NULL; // extern HWND WindowEq = NULL; // extern HWND WindowSeek = NULL; // extern WNDPROC WndprocSeekBackup = NULL; LRESULT CALLBACK WndprocSeek( HWND hwnd, UINT message, WPARAM wp, LPARAM lp ); HWND WindowVol = NULL; WNDPROC WndprocVolBackup = NULL; LRESULT CALLBACK WndprocVol( HWND hwnd, UINT message, WPARAM wp, LPARAM lp ); HWND WindowPan = NULL; WNDPROC WndprocPanBackup = NULL; LRESULT CALLBACK WndprocPan( HWND hwnd, UINT message, WPARAM wp, LPARAM lp ); HWND WindowButtons = NULL; HWND WindowVis = NULL; // extern WNDPROC WndprocVisBackup = NULL; LRESULT CALLBACK WndprocVis( HWND hwnd, UINT message, WPARAM wp, LPARAM lp ); bool Rebar_BuildOrderBand(); bool Rebar_BuildEqBand(); bool Rebar_BuildSeekBand(); bool Rebar_BuildVolBand(); bool Rebar_BuildPanBand(); bool Rebar_BuildButtonsBand(); bool Rebar_BuildVisBand(); BandInfo biOrderBand = { 0 }; BandInfo biEqBand = { 0 }; BandInfo biSeekBand = { 0 }; BandInfo biVolBand = { 0 }; BandInfo biPanBand = { 0 }; BandInfo biButtonsBand = { 0 }; BandInfo biVisBand = { 0 }; const BandInfo biOrderBandDefault = { 0, 184, true, true }; const BandInfo biVolBandDefault = { 1, 450, false, true }; const BandInfo biPanBandDefault = { 2, 138, false, true }; const BandInfo biEqBandDefault = { 3, 170, true, true }; const BandInfo biVisBandDefault = { 4, 350, false, true }; const BandInfo biButtonsBandDefault = { 5, 147, true, true }; const BandInfo biSeekBandDefault = { 6, 373, false, true }; void BandCallback( ConfVar * var ); ConfBandInfoCallback cbiOrderBand ( &biOrderBand, TEXT( "OrderBand" ), ( BandInfo * )&biOrderBandDefault, BandCallback ); ConfBandInfoCallback cbiEqBand ( &biEqBand, TEXT( "EqBand" ), ( BandInfo * )&biEqBandDefault, BandCallback ); ConfBandInfoCallback cbiSeekBand ( &biSeekBand, TEXT( "SeekBand" ), ( BandInfo * )&biSeekBandDefault, BandCallback ); ConfBandInfoCallback cbiVolBand ( &biVolBand, TEXT( "VolBand" ), ( BandInfo * )&biVolBandDefault, BandCallback ); ConfBandInfoCallback cbiPanBand ( &biPanBand, TEXT( "PanBand" ), ( BandInfo * )&biPanBandDefault, BandCallback ); ConfBandInfoCallback cbiButtonsBand( &biButtonsBand, TEXT( "ButtonsBand" ), ( BandInfo * )&biButtonsBandDefault, BandCallback ); ConfBandInfoCallback cbiVisBand ( &biVisBand, TEXT( "VisBand" ), ( BandInfo * )&biVisBandDefault, BandCallback ); bool bInvertPanSlider; ConfBool cbInvertPanSlider( &bInvertPanSlider, TEXT( "InvertPanSlider" ), CONF_MODE_PUBLIC, false ); //////////////////////////////////////////////////////////////////////////////// /// //////////////////////////////////////////////////////////////////////////////// void BandCallback( ConfVar * var ) { BandInfo * band; int id; if( var == &cbiOrderBand ) { band = &biOrderBand; id = BAND_ORDER; } else if( var == &cbiEqBand ) { band = &biEqBand; id = BAND_EQ; } else if( var == &cbiSeekBand ) { band = &biSeekBand; id = BAND_SEEK; } else if( var == &cbiVolBand ) { band = &biVolBand; id = BAND_VOL; } else if( var == &cbiPanBand ) { band = &biPanBand; id = BAND_PAN; } else if( var == &cbiButtonsBand ) { band = &biButtonsBand; id = BAND_BUTTONS; } else if( var == &cbiVisBand ) { band = &biVisBand; id = BAND_VIS; } else { return; } band->m_iIndex = ( int )SendMessage( WindowRebar, RB_IDTOINDEX, id, 0 ); if( band->m_iIndex == -1 ) return; REBARBANDINFO rbbi; rbbi.cbSize = sizeof( REBARBANDINFO ); rbbi.fMask = RBBIM_SIZE | RBBIM_STYLE; SendMessage( WindowRebar, RB_GETBANDINFO, band->m_iIndex, ( LPARAM )&rbbi ); band->m_iWidth = rbbi.cx; band->m_bBreak = ( ( rbbi.fStyle & RBBS_BREAK ) == RBBS_BREAK ); band->m_bVisible = ( ( rbbi.fStyle & RBBS_HIDDEN ) != RBBS_HIDDEN ); } //////////////////////////////////////////////////////////////////////////////// /// //////////////////////////////////////////////////////////////////////////////// bool Toolbar::Create() { LoadCommonControls(); WindowRebar = CreateWindowEx( WS_EX_TOOLWINDOW | WS_EX_LEFT | WS_EX_LTRREADING | WS_EX_RIGHTSCROLLBAR, REBARCLASSNAME, NULL, WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS | WS_CLIPCHILDREN | WS_BORDER | RBS_VARHEIGHT | RBS_BANDBORDERS | RBS_DBLCLKTOGGLE | // RBS_AUTOSIZE CCS_TOP | CCS_NOPARENTALIGN | CCS_NODIVIDER, // | CCS_ADJUSTABLE, 0, 0, 0, 0, WindowMain, NULL, g_hInstance, NULL ); /* #define STYLE 1 #if STYLE == 1 // Normal MoveWindow( rebar, 0, 0, width, 30, TRUE ); #elif STYLE == 2 // Left ONLY MoveWindow( rebar, 1, 0, width - 1, 30, TRUE ); #endif */ REBARINFO rbi = { sizeof( REBARINFO ), // UINT cbSize; 0, // UINT fMask NULL // HIMAGELIST himl }; if( !SendMessage( WindowRebar, RB_SETBARINFO, 0, ( LPARAM )&rbi ) ) { return false; } // Exchange window procedure WndprocRebarBackup = ( WNDPROC )GetWindowLong( WindowRebar, GWL_WNDPROC ); //WndprocRebarBackup = ( WNDPROC )GetWindowLongPtr( WindowRebar, GWLP_WNDPROC ); // 64 bit if( WndprocRebarBackup != NULL ) { SetWindowLong( WindowRebar, GWL_WNDPROC, ( LONG )WndprocRebar ); //SetWindowLongPtr( WindowRebar, GWLP_WNDPROC, ( LONG )WndprocRebar ); } rebar_menu = CreatePopupMenu(); AppendMenu( rebar_menu, MF_STRING, BAND_BUTTONS, TEXT( "Buttons" ) ); AppendMenu( rebar_menu, MF_STRING, BAND_EQ, TEXT( "Equalizer" ) ); AppendMenu( rebar_menu, MF_STRING, BAND_ORDER, TEXT( "Order" ) ); AppendMenu( rebar_menu, MF_STRING, BAND_PAN, TEXT( "Panning" ) ); AppendMenu( rebar_menu, MF_STRING, BAND_SEEK, TEXT( "Seekbar" ) ); AppendMenu( rebar_menu, MF_STRING, BAND_VIS, TEXT( "Visualization" ) ); AppendMenu( rebar_menu, MF_STRING, BAND_VOL, TEXT( "Volume" ) ); Rebar_BuildOrderBand(); Rebar_BuildEqBand(); Rebar_BuildSeekBand(); Rebar_BuildVolBand(); Rebar_BuildPanBand(); Rebar_BuildButtonsBand(); Rebar_BuildVisBand(); cbiOrderBand.Apply ( WindowRebar, BAND_ORDER ); cbiEqBand.Apply ( WindowRebar, BAND_EQ ); cbiSeekBand.Apply ( WindowRebar, BAND_SEEK ); cbiVolBand.Apply ( WindowRebar, BAND_VOL ); cbiPanBand.Apply ( WindowRebar, BAND_PAN ); cbiButtonsBand.Apply( WindowRebar, BAND_BUTTONS ); cbiVisBand.Apply ( WindowRebar, BAND_VIS ); return true; } //////////////////////////////////////////////////////////////////////////////// /// //////////////////////////////////////////////////////////////////////////////// bool Rebar_BuildOrderBand() { if( !WindowRebar ) return false; WindowOrder = CreateWindowEx( 0, TEXT( "COMBOBOX" ), TEXT( "" ), CBS_HASSTRINGS | CBS_DROPDOWNLIST | WS_CHILD, 0, 0, 133, 200, WindowRebar, NULL, g_hInstance, NULL ); if( !WindowOrder ) return false; // Add mode names TCHAR * szName; for( int i = ORDER_FIRST; i <= ORDER_LAST; i++ ) { szName = Playback::Order::GetModeName( i ); SendMessage( WindowOrder, CB_ADDSTRING, 0, ( LPARAM )szName ); } // Initial value SendMessage( WindowOrder, CB_SETCURSEL, Playback::Order::GetCurMode(), 0 ); RECT rc; GetWindowRect( WindowOrder, &rc ); REBARBANDINFO rbBand; rbBand.cbSize = sizeof( REBARBANDINFO ); rbBand.fMask = 0 | // RBBIM_BACKGROUND | // The hbmBack member is valid or must be filled. RBBIM_CHILD | // The hwndChild member is valid or must be filled. RBBIM_CHILDSIZE | // The cxMinChild, cyMinChild, cyChild, cyMaxChild, and cyIntegral members are valid or must be filled. // RBBIM_COLORS | // The clrFore and clrBack members are valid or must be filled. // RBBIM_HEADERSIZE | // Version 4.71. The cxHeader member is valid or must be filled. RBBIM_IDEALSIZE | // Version 4.71. The cxIdeal member is valid or must be filled. RBBIM_ID | // The wID member is valid or must be filled. // RBBIM_IMAGE | // The iImage member is valid or must be filled. // RBBIM_LPARAM | // Version 4.71. The lParam member is valid or must be filled. RBBIM_SIZE | // The cx member is valid or must be filled. RBBIM_STYLE | // The fStyle member is valid or must be filled. RBBIM_TEXT | // The lpText member is valid or must be filled. 0; rbBand.fStyle = RBBS_GRIPPERALWAYS | RBBS_CHILDEDGE | ( biOrderBand.m_bBreak ? RBBS_BREAK : 0 ); rbBand.lpText = TEXT( " Order " ); rbBand.hwndChild = WindowOrder; rbBand.cxMinChild = rc.right - rc.left; rbBand.cyMinChild = 21; // IMP rbBand.cx = biOrderBand.m_iWidth; rbBand.wID = BAND_ORDER; rbBand.cyChild = 21; rbBand.cyMaxChild = 21; rbBand.cyIntegral = 1; rbBand.cxIdeal = 200; // Add band SendMessage( WindowRebar, RB_INSERTBAND, ( WPARAM )-1, ( LPARAM )&rbBand ); Font::Apply( WindowOrder ); return true; } //////////////////////////////////////////////////////////////////////////////// /// //////////////////////////////////////////////////////////////////////////////// bool AddPreset( TCHAR * szPresetName ) { const int iLen = _tcslen( szPresetName ); TCHAR * szFinal = new TCHAR[ iLen + 2 + 1 ]; szFinal[ 0 ] = TEXT( ' ' ); szFinal[ iLen + 1 ] = TEXT( ' ' ); szFinal[ iLen + 2 ] = TEXT( '\0' ); memcpy( szFinal + 1, szPresetName, iLen * sizeof( TCHAR ) ); SendMessage( WindowEq, CB_ADDSTRING, 0, ( LPARAM )szFinal ); delete [] szFinal; return true; } //////////////////////////////////////////////////////////////////////////////// /// //////////////////////////////////////////////////////////////////////////////// bool Rebar_BuildEqBand() { if( !WindowRebar ) return false; WindowEq = CreateWindowEx( 0, TEXT( "COMBOBOX" ), TEXT( "" ), CBS_HASSTRINGS | CBS_DROPDOWNLIST | WS_CHILD, 0, 0, 133, 300, WindowRebar, NULL, g_hInstance, NULL ); if( !WindowEq ) return false; // Add preset names SendMessage( WindowEq, CB_ADDSTRING, 0, ( LPARAM )TEXT( " Disabled " ) ); Playback::Eq::ReadPresets( AddPreset ); // Initial value SendMessage( WindowEq, CB_SETCURSEL, Playback::Eq::GetCurIndex() + 1, 0 ); // TODO Disabled // EnableWindow( WindowEq, FALSE ); RECT rc; GetWindowRect( WindowEq, &rc ); REBARBANDINFO rbBand; rbBand.cbSize = sizeof( REBARBANDINFO ); rbBand.fMask = 0 | // RBBIM_BACKGROUND | // The hbmBack member is valid or must be filled. RBBIM_CHILD | // The hwndChild member is valid or must be filled. RBBIM_CHILDSIZE | // The cxMinChild, cyMinChild, cyChild, cyMaxChild, and cyIntegral members are valid or must be filled. // RBBIM_COLORS | // The clrFore and clrBack members are valid or must be filled. // RBBIM_HEADERSIZE | // Version 4.71. The cxHeader member is valid or must be filled. RBBIM_IDEALSIZE | // Version 4.71. The cxIdeal member is valid or must be filled. RBBIM_ID | // The wID member is valid or must be filled. // RBBIM_IMAGE | // The iImage member is valid or must be filled. // RBBIM_LPARAM | // Version 4.71. The lParam member is valid or must be filled. RBBIM_SIZE | // The cx member is valid or must be filled. RBBIM_STYLE | // The fStyle member is valid or must be filled. RBBIM_TEXT | // The lpText member is valid or must be filled. 0; rbBand.fStyle = RBBS_GRIPPERALWAYS | RBBS_CHILDEDGE | ( biEqBand.m_bBreak ? RBBS_BREAK : 0 ); rbBand.lpText = TEXT( " EQ " ); rbBand.hwndChild = WindowEq; rbBand.cxMinChild = rc.right - rc.left; rbBand.cyMinChild = 21; // IMP rbBand.cx = biEqBand.m_iWidth; rbBand.wID = BAND_EQ; rbBand.cyChild = 21; rbBand.cyMaxChild = 21; rbBand.cyIntegral = 1; rbBand.cxIdeal = 200; // Add band SendMessage( WindowRebar, RB_INSERTBAND, ( WPARAM )-1, ( LPARAM )&rbBand ); Font::Apply( WindowEq ); return true; } //////////////////////////////////////////////////////////////////////////////// /// //////////////////////////////////////////////////////////////////////////////// bool Rebar_BuildSeekBand() { if( !WindowRebar ) return false; WindowSeek = CreateWindowEx( 0, TRACKBAR_CLASS, TEXT( "" ), WS_CHILD | WS_DISABLED | TBS_HORZ | TBS_NOTICKS | TBS_FIXEDLENGTH | TBS_BOTH, 0, 0, 300, 21, WindowRebar, NULL, g_hInstance, NULL ); // Range SendMessage( WindowSeek, TBM_SETRANGE, TRUE, ( LPARAM )MAKELONG( 0, 999 ) ); // Thumb size SendMessage( WindowSeek, TBM_SETTHUMBLENGTH, 14, 0 ); // Exchange window procedure WndprocSeekBackup = ( WNDPROC )GetWindowLong( WindowSeek, GWL_WNDPROC ); if( WndprocSeekBackup != NULL ) { SetWindowLong( WindowSeek, GWL_WNDPROC, ( LONG )WndprocSeek ); } REBARBANDINFO rbbi_seek; rbbi_seek.cbSize = sizeof( REBARBANDINFO ); rbbi_seek.fMask = 0 | // RBBIM_BACKGROUND | // The hbmBack member is valid or must be filled. RBBIM_CHILD | // The hwndChild member is valid or must be filled. RBBIM_CHILDSIZE | // The cxMinChild, cyMinChild, cyChild, cyMaxChild, and cyIntegral members are valid or must be filled. // RBBIM_COLORS | // The clrFore and clrBack members are valid or must be filled. // RBBIM_HEADERSIZE | // Version 4.71. The cxHeader member is valid or must be filled. RBBIM_IDEALSIZE | // Version 4.71. The cxIdeal member is valid or must be filled. RBBIM_ID | // The wID member is valid or must be filled. // RBBIM_IMAGE | // The iImage member is valid or must be filled. // RBBIM_LPARAM | // Version 4.71. The lParam member is valid or must be filled. RBBIM_SIZE | // The cx member is valid or must be filled. RBBIM_STYLE | // The fStyle member is valid or must be filled. RBBIM_TEXT | // The lpText member is valid or must be filled. 0; rbbi_seek.fStyle = RBBS_GRIPPERALWAYS | RBBS_CHILDEDGE | ( biSeekBand.m_bBreak ? RBBS_BREAK : 0 ); rbbi_seek.lpText = " Pos"; rbbi_seek.hwndChild = WindowSeek; rbbi_seek.cxMinChild = 100; rbbi_seek.cyMinChild = 21; // IMP rbbi_seek.cx = biSeekBand.m_iWidth; rbbi_seek.wID = BAND_SEEK; rbbi_seek.cyChild = 21; rbbi_seek.cyMaxChild = 21; rbbi_seek.cyIntegral = 1; rbbi_seek.cxIdeal = 300; // Add band SendMessage( WindowRebar, RB_INSERTBAND, ( WPARAM )-1, ( LPARAM )&rbbi_seek ); return true; } //////////////////////////////////////////////////////////////////////////////// /// //////////////////////////////////////////////////////////////////////////////// bool Rebar_BuildVolBand() { if( !WindowRebar ) return false; WindowVol = CreateWindowEx( 0, TRACKBAR_CLASS, TEXT( "" ), WS_CHILD | TBS_HORZ | TBS_NOTICKS | TBS_FIXEDLENGTH | TBS_BOTH, 0, 0, 200, 21, WindowRebar, NULL, g_hInstance, NULL ); if( !WindowVol ) return false; // Range SendMessage( WindowVol, TBM_SETRANGE, TRUE, ( LPARAM )MAKELONG( 0, 255 ) ); // Initial value SendMessage( WindowVol, TBM_SETPOS, TRUE, Playback::Volume::Get() ); // Thumbs size SendMessage( WindowVol, TBM_SETTHUMBLENGTH, 14, 0 ); // Exchange window procedure WndprocVolBackup = ( WNDPROC )GetWindowLong( WindowVol, GWL_WNDPROC ); if( WndprocVolBackup != NULL ) { SetWindowLong( WindowVol, GWL_WNDPROC, ( LONG )WndprocVol ); } REBARBANDINFO rbbi_vol; rbbi_vol.cbSize = sizeof( REBARBANDINFO ); rbbi_vol.fMask = 0 | // RBBIM_BACKGROUND | // The hbmBack member is valid or must be filled. RBBIM_CHILD | // The hwndChild member is valid or must be filled. RBBIM_CHILDSIZE | // The cxMinChild, cyMinChild, cyChild, cyMaxChild, and cyIntegral members are valid or must be filled. // RBBIM_COLORS | // The clrFore and clrBack members are valid or must be filled. // RBBIM_HEADERSIZE | // Version 4.71. The cxHeader member is valid or must be filled. RBBIM_IDEALSIZE | // Version 4.71. The cxIdeal member is valid or must be filled. RBBIM_ID | // The wID member is valid or must be filled. // RBBIM_IMAGE | // The iImage member is valid or must be filled. // RBBIM_LPARAM | // Version 4.71. The lParam member is valid or must be filled. RBBIM_SIZE | // The cx member is valid or must be filled. RBBIM_STYLE | // The fStyle member is valid or must be filled. RBBIM_TEXT | // The lpText member is valid or must be filled. 0; rbbi_vol.fStyle = RBBS_GRIPPERALWAYS | RBBS_CHILDEDGE | ( biVolBand.m_bBreak ? RBBS_BREAK : 0 ); rbbi_vol.lpText = TEXT( " Vol" ); rbbi_vol.hwndChild = WindowVol; rbbi_vol.cxMinChild = 100; rbbi_vol.cyMinChild = 21; // IMP rbbi_vol.cx = biVolBand.m_iWidth; rbbi_vol.wID = BAND_VOL; rbbi_vol.cyChild = 21; rbbi_vol.cyMaxChild = 21; rbbi_vol.cyIntegral = 1; rbbi_vol.cxIdeal = 100; // Add band SendMessage( WindowRebar, RB_INSERTBAND, ( WPARAM )-1, ( LPARAM )&rbbi_vol ); return true; } //////////////////////////////////////////////////////////////////////////////// /// //////////////////////////////////////////////////////////////////////////////// bool Rebar_BuildPanBand() { if( !WindowRebar ) return false; WindowPan = CreateWindowEx( 0, TRACKBAR_CLASS, TEXT( "" ), WS_CHILD | TBS_HORZ | TBS_NOTICKS | TBS_FIXEDLENGTH | TBS_BOTH, 0, 0, 200, 21, WindowRebar, NULL, g_hInstance, NULL ); if( !WindowPan ) return false; // Range SendMessage( WindowPan, TBM_SETRANGE, TRUE, ( LPARAM )MAKELONG( -127, 127 ) ); // Initial value const int iCurPan = Playback::Pan::Get(); SendMessage( WindowPan, TBM_SETPOS, TRUE, bInvertPanSlider ? -iCurPan : iCurPan ); // Thumb size SendMessage( WindowPan, TBM_SETTHUMBLENGTH, 14, 0 ); // Exchange window procedure WndprocPanBackup = ( WNDPROC )GetWindowLong( WindowPan, GWL_WNDPROC ); if( WndprocPanBackup != NULL ) { SetWindowLong( WindowPan, GWL_WNDPROC, ( LONG )WndprocPan ); } REBARBANDINFO rbbi_pan; rbbi_pan.cbSize = sizeof( REBARBANDINFO ); rbbi_pan.fMask = 0 | // RBBIM_BACKGROUND | // The hbmBack member is valid or must be filled. RBBIM_CHILD | // The hwndChild member is valid or must be filled. RBBIM_CHILDSIZE | // The cxMinChild, cyMinChild, cyChild, cyMaxChild, and cyIntegral members are valid or must be filled. // RBBIM_COLORS | // The clrFore and clrBack members are valid or must be filled. // RBBIM_HEADERSIZE | // Version 4.71. The cxHeader member is valid or must be filled. RBBIM_IDEALSIZE | // Version 4.71. The cxIdeal member is valid or must be filled. RBBIM_ID | // The wID member is valid or must be filled. // RBBIM_IMAGE | // The iImage member is valid or must be filled. // RBBIM_LPARAM | // Version 4.71. The lParam member is valid or must be filled. RBBIM_SIZE | // The cx member is valid or must be filled. RBBIM_STYLE | // The fStyle member is valid or must be filled. RBBIM_TEXT | // The lpText member is valid or must be filled. 0; rbbi_pan.fStyle = RBBS_GRIPPERALWAYS | RBBS_CHILDEDGE | ( biPanBand.m_bBreak ? RBBS_BREAK : 0 ); rbbi_pan.lpText = TEXT( " Pan" ); rbbi_pan.hwndChild = WindowPan; rbbi_pan.cxMinChild = 100; rbbi_pan.cyMinChild = 21; // IMP rbbi_pan.cx = biPanBand.m_iWidth; rbbi_pan.wID = BAND_PAN; rbbi_pan.cyChild = 21; rbbi_pan.cyMaxChild = 21; rbbi_pan.cyIntegral = 1; rbbi_pan.cxIdeal = 100; // Add band SendMessage( WindowRebar, RB_INSERTBAND, ( WPARAM )-1, ( LPARAM )&rbbi_pan ); return true; } //////////////////////////////////////////////////////////////////////////////// /// //////////////////////////////////////////////////////////////////////////////// bool Rebar_BuildButtonsBand() { if( !WindowRebar ) return false; WindowButtons = CreateWindowEx( 0, TOOLBARCLASSNAME, TEXT( "" ), WS_CHILD | TBSTYLE_FLAT | CCS_NORESIZE | // Means we care about the size ourselves CCS_NOPARENTALIGN | // Make it work with the rebar control CCS_NODIVIDER, // No divider on top 0, 0, 100, 21, WindowRebar, NULL, g_hInstance, NULL ); if( !WindowButtons ) return false; SendMessage( WindowButtons, TB_BUTTONSTRUCTSIZE, ( WPARAM )sizeof( TBBUTTON ), 0 ); TBBUTTON tb_button[ 7 ]; // Make image list, TODO delete later HIMAGELIST hImages = ImageList_LoadBitmap( GetModuleHandle( NULL ), // HINSTANCE hi MAKEINTRESOURCE( IDB_BITMAP1 ), // LPCTSTR lpbmp 14, // int cx 6, // int cGrow RGB( 255, 000, 255 ) // COLORREF crMask ); SendMessage( WindowButtons, TB_SETIMAGELIST, 0, ( LPARAM )hImages ); // SendMessage( WindowButtons, TB_SETHOTIMAGELIST, 0, ( LPARAM )hImages ); // SendMessage( WindowButtons, TB_SETDISABLEDIMAGELIST, 0, ( LPARAM )hImages ); // Build buttons tb_button[ 0 ].iBitmap = IMAGE_PREV; tb_button[ 0 ].idCommand = WINAMP_BUTTON1; tb_button[ 0 ].fsState = TBSTATE_ENABLED; tb_button[ 0 ].fsStyle = TBSTYLE_BUTTON; tb_button[ 0 ].dwData = 0; tb_button[ 0 ].iString = SendMessage( WindowButtons, TB_ADDSTRING, 0, ( LPARAM )TEXT( "Previous" )); tb_button[ 1 ].iBitmap = IMAGE_PLAY; tb_button[ 1 ].idCommand = WINAMP_BUTTON2; tb_button[ 1 ].fsState = TBSTATE_ENABLED; tb_button[ 1 ].fsStyle = TBSTYLE_BUTTON; tb_button[ 1 ].dwData = 0; tb_button[ 1 ].iString = SendMessage( WindowButtons, TB_ADDSTRING, 0, ( LPARAM )TEXT( "Play" )); tb_button[ 2 ].iBitmap = IMAGE_PAUSE; tb_button[ 2 ].idCommand = WINAMP_BUTTON3; tb_button[ 2 ].fsState = TBSTATE_ENABLED; tb_button[ 2 ].fsStyle = TBSTYLE_BUTTON; tb_button[ 2 ].dwData = 0; tb_button[ 2 ].iString = SendMessage( WindowButtons, TB_ADDSTRING, 0, ( LPARAM )TEXT( "Pause" )); tb_button[ 3 ].iBitmap = IMAGE_STOP; tb_button[ 3 ].idCommand = WINAMP_BUTTON4; tb_button[ 3 ].fsState = TBSTATE_ENABLED; tb_button[ 3 ].fsStyle = TBSTYLE_BUTTON; tb_button[ 3 ].dwData = 0; tb_button[ 3 ].iString = SendMessage( WindowButtons, TB_ADDSTRING, 0, ( LPARAM )TEXT( "Stop" )); tb_button[ 4 ].iBitmap = IMAGE_NEXT; tb_button[ 4 ].idCommand = WINAMP_BUTTON5; tb_button[ 4 ].fsState = TBSTATE_ENABLED; tb_button[ 4 ].fsStyle = TBSTYLE_BUTTON; tb_button[ 4 ].dwData = 0; tb_button[ 4 ].iString = SendMessage( WindowButtons, TB_ADDSTRING, 0, ( LPARAM )TEXT( "Next" )); tb_button[ 5 ].iBitmap = 0; tb_button[ 5 ].idCommand = -1; tb_button[ 5 ].fsState = TBSTATE_ENABLED; tb_button[ 5 ].fsStyle = TBSTYLE_SEP; tb_button[ 5 ].dwData = 0; tb_button[ 5 ].iString = 0; tb_button[ 6 ].iBitmap = IMAGE_OPEN; tb_button[ 6 ].idCommand = WINAMP_FILE_PLAY; tb_button[ 6 ].fsState = TBSTATE_ENABLED; tb_button[ 6 ].fsStyle = TBSTYLE_BUTTON; tb_button[ 6 ].dwData = 0; tb_button[ 6 ].iString = SendMessage( WindowButtons, TB_ADDSTRING, 0, ( LPARAM )TEXT( "Open" )); // Add buttons SendMessage( WindowButtons, TB_SETBUTTONSIZE, 0, MAKELONG( 14, 14 ) ); SendMessage( WindowButtons, TB_ADDBUTTONS, 7, ( LPARAM )( LPTBBUTTON )&tb_button ); // Disable labels SendMessage( WindowButtons, TB_SETMAXTEXTROWS, 0, 0 ); // Resize RECT r; GetWindowRect( WindowButtons, &r ); SetWindowPos( WindowButtons, NULL, 0, 0, 134, r.bottom - r.top, SWP_NOMOVE ); GetWindowRect( WindowButtons, &r ); REBARBANDINFO rbbi_buttons; rbbi_buttons.cbSize = sizeof( REBARBANDINFO ); rbbi_buttons.fMask = 0 | // RBBIM_BACKGROUND | // The hbmBack member is valid or must be filled. RBBIM_CHILD | // The hwndChild member is valid or must be filled. RBBIM_CHILDSIZE | // The cxMinChild, cyMinChild, cyChild, cyMaxChild, and cyIntegral members are valid or must be filled. // RBBIM_COLORS | // The clrFore and clrBack members are valid or must be filled. // RBBIM_HEADERSIZE | // Version 4.71. The cxHeader member is valid or must be filled. RBBIM_IDEALSIZE | // Version 4.71. The cxIdeal member is valid or must be filled. RBBIM_ID | // The wID member is valid or must be filled. // RBBIM_IMAGE | // The iImage member is valid or must be filled. // RBBIM_LPARAM | // Version 4.71. The lParam member is valid or must be filled. RBBIM_SIZE | // The cx member is valid or must be filled. RBBIM_STYLE | // The fStyle member is valid or must be filled. // RBBIM_TEXT | // The lpText member is valid or must be filled. 0; rbbi_buttons.fStyle = RBBS_GRIPPERALWAYS | RBBS_CHILDEDGE | ( biButtonsBand.m_bBreak ? RBBS_BREAK : 0 ); // rbbi_buttons.lpText = TEXT( " Playback" ); rbbi_buttons.hwndChild = WindowButtons; rbbi_buttons.cxMinChild = r.right - r.left; rbbi_buttons.cyMinChild = 21; // IMP rbbi_buttons.cx = r.right - r.left; rbbi_buttons.wID = BAND_BUTTONS; rbbi_buttons.cyChild = 21; rbbi_buttons.cyMaxChild = 21; rbbi_buttons.cyIntegral = 1; rbbi_buttons.cxIdeal = r.right - r.left; // Add band SendMessage( WindowRebar, RB_INSERTBAND, ( WPARAM )-1, ( LPARAM )&rbbi_buttons ); return true; } //////////////////////////////////////////////////////////////////////////////// /// //////////////////////////////////////////////////////////////////////////////// bool Rebar_BuildVisBand() { if( !WindowRebar ) return false; WindowVis = CreateWindowEx( WS_EX_STATICEDGE, TEXT( "STATIC" ), TEXT( "" ), WS_CHILD | SS_CENTER, 0, 0, 100, 21, WindowRebar, NULL, g_hInstance, NULL ); if( !WindowVis ) return false; Font::Apply( WindowVis ); // Resize RECT r; GetWindowRect( WindowButtons, &r ); // SetWindowPos( WindowButtons, NULL, 0, 0, 146, r.bottom - r.top, SWP_NOMOVE ); // GetWindowRect( WindowButtons, &r ); REBARBANDINFO rbbi_buttons; rbbi_buttons.cbSize = sizeof( REBARBANDINFO ); rbbi_buttons.fMask = 0 | // RBBIM_BACKGROUND | // The hbmBack member is valid or must be filled. RBBIM_CHILD | // The hwndChild member is valid or must be filled. RBBIM_CHILDSIZE | // The cxMinChild, cyMinChild, cyChild, cyMaxChild, and cyIntegral members are valid or must be filled. // RBBIM_COLORS | // The clrFore and clrBack members are valid or must be filled. // RBBIM_HEADERSIZE | // Version 4.71. The cxHeader member is valid or must be filled. RBBIM_IDEALSIZE | // Version 4.71. The cxIdeal member is valid or must be filled. RBBIM_ID | // The wID member is valid or must be filled. // RBBIM_IMAGE | // The iImage member is valid or must be filled. // RBBIM_LPARAM | // Version 4.71. The lParam member is valid or must be filled. RBBIM_SIZE | // The cx member is valid or must be filled. RBBIM_STYLE | // The fStyle member is valid or must be filled. RBBIM_TEXT | // The lpText member is valid or must be filled. 0; rbbi_buttons.fStyle = RBBS_GRIPPERALWAYS | RBBS_CHILDEDGE | ( biVisBand.m_bBreak ? RBBS_BREAK : 0 ); rbbi_buttons.lpText = TEXT( " Vis " ); rbbi_buttons.hwndChild = WindowVis; rbbi_buttons.cxMinChild = r.right - r.left; rbbi_buttons.cyMinChild = 21; // IMP rbbi_buttons.cx = r.right - r.left; rbbi_buttons.wID = BAND_VIS; rbbi_buttons.cyChild = 21; rbbi_buttons.cyMaxChild = 21; rbbi_buttons.cyIntegral = 1; rbbi_buttons.cxIdeal = r.right - r.left; // Add band SendMessage( WindowRebar, RB_INSERTBAND, ( WPARAM )-1, ( LPARAM )&rbbi_buttons ); // Exchange window procedure WndprocVisBackup = ( WNDPROC )GetWindowLong( WindowVis, GWL_WNDPROC ); if( WndprocVisBackup != NULL ) { SetWindowLong( WindowVis, GWL_WNDPROC, ( LONG )WndprocVis ); } return true; } //////////////////////////////////////////////////////////////////////////////// /// //////////////////////////////////////////////////////////////////////////////// void ContextMenuRebar( POINT * p ) { REBARBANDINFO rbbi; rbbi.cbSize = sizeof( REBARBANDINFO ); rbbi.fMask = RBBIM_STYLE; bool bBandVisible[ BAND_LAST - BAND_FIRST + 1 ] = { 0 }; // ID to visibility int iBandIndex [ BAND_LAST - BAND_FIRST + 1 ] = { 0 }; // ID to Index for( int i = BAND_FIRST; i <= BAND_LAST; i++ ) { const int iArrayIndex = i - BAND_FIRST; // Get index iBandIndex[ iArrayIndex ] = ( int )SendMessage( WindowRebar, RB_IDTOINDEX, i, 0 ); if( iBandIndex[ iArrayIndex ] == -1 ) break; // Get info if( !SendMessage( WindowRebar, RB_GETBANDINFO, iBandIndex[ iArrayIndex ], ( LPARAM )&rbbi ) ) { break; } bBandVisible[ iArrayIndex ] = ( ( rbbi.fStyle & RBBS_HIDDEN ) != RBBS_HIDDEN ); // Update menu item CheckMenuItem( rebar_menu, i, bBandVisible[ iArrayIndex ] ? MF_CHECKED : MF_UNCHECKED ); } BOOL iIndex = TrackPopupMenu( rebar_menu, TPM_LEFTALIGN | TPM_TOPALIGN | TPM_NONOTIFY | TPM_RETURNCMD | TPM_RIGHTBUTTON, p->x, p->y, 0, WindowRebar, NULL ); // Toggle visibility if( ( iIndex >= BAND_FIRST ) && ( iIndex <= BAND_LAST ) ) { const int iArrayIndex = iIndex - BAND_FIRST; SendMessage( WindowRebar, RB_SHOWBAND, iBandIndex[ iArrayIndex ], bBandVisible[ iArrayIndex ] ? FALSE : TRUE ); // Turn off vis child if( iIndex == BAND_VIS ) { HWND hChild = GetWindow( WindowVis, GW_CHILD ); if( IsWindow( hChild ) ) { SendMessage( hChild, WM_DESTROY, 0, 0 ); } } } } //////////////////////////////////////////////////////////////////////////////// /// //////////////////////////////////////////////////////////////////////////////// LRESULT CALLBACK WndprocRebar( HWND hwnd, UINT message, WPARAM wp, LPARAM lp ) { //Console::Append( TEXT("Rebar.cpp: WndprocRebar called") ); switch( message ) { case WM_CONTEXTMENU: // This affects the placement of the progress bar { //POINT p; //GetCursorPos( &p ); //ContextMenuRebar( &p ); return 0; } case WM_DESTROY: cbiOrderBand.TriggerCallback(); cbiOrderBand.RemoveCallback(); cbiEqBand.TriggerCallback(); cbiEqBand.RemoveCallback(); cbiSeekBand.TriggerCallback(); cbiSeekBand.RemoveCallback(); cbiVolBand.TriggerCallback(); cbiVolBand.RemoveCallback(); cbiPanBand.TriggerCallback(); cbiPanBand.RemoveCallback(); cbiButtonsBand.TriggerCallback(); cbiButtonsBand.RemoveCallback(); cbiVisBand.TriggerCallback(); cbiVisBand.RemoveCallback(); break; } return CallWindowProc( WndprocRebarBackup, hwnd, message, wp, lp ); } //////////////////////////////////////////////////////////////////////////////// /// //////////////////////////////////////////////////////////////////////////////// LRESULT CALLBACK WndprocSeek( HWND hwnd, UINT message, WPARAM wp, LPARAM lp ) { static bool bDown = false; static int iLastVal = 0; //Console::Append( TEXT("Rebar.cpp: WndprocSeek called") ); switch( message ) { case WM_LBUTTONDOWN: { SetFocus( hwnd ); // Capture mouse SetCapture( hwnd ); bDown = true; // NO BREAK! } case WM_MOUSEMOVE: { if( !bDown ) break; if( !Playback::IsPlaying() ) return 0; // Deny slider move RECT r; GetWindowRect( hwnd, &r ); const int iWidth = r.right - r.left; if( !iWidth ) return 0; int iVal = 1000 * MAX( 0, MIN( ( short )LOWORD( lp ), iWidth ) ) / iWidth; // Snap if( ( short )LOWORD( lp ) < 7 ) { iVal = 0; } else if( abs( iWidth - ( short )LOWORD( lp ) ) < 7 ) { iVal = 999; } // Update slider PostMessage( hwnd, TBM_SETPOS, ( WPARAM )( TRUE ), iVal ); // Seek iLastVal = iVal; Playback::SeekPercent( iLastVal / 10.0f ); // TODO: Seek on slide ON/OFF return 0; } case WM_LBUTTONUP: case WM_NCLBUTTONUP: { // Release capture bDown = false; ReleaseCapture(); if( !Playback::IsPlaying() ) return 0; int ms = Playback::PercentToMs( iLastVal / 10.0f ); if( ms < 0 ) break; int h = ms / 3600000; int m = ( ms / 60000 ) % 60; int s = ( ms / 1000 ) % 60; ms = ms % 1000; TCHAR szBuffer[ 5000 ]; /* bool bShowMs = false; if( h ) { if( bShowMs ) { */ // 00:00:00.000 _stprintf( szBuffer, TEXT( "Jumped to %02i:%02i:%02i.%03i" ), h, m, s, ms ); Console::Append( szBuffer ); Console::Append( " " ); /* } else { // 00:00:00 } } else if( m ) { if( bShowMs ) { // 00:00.000 } else { // 00:00 } } else { if( bShowMs ) { // 00.000 } else { // 00s } } */ return 0; } case WM_KEYDOWN: case WM_KEYUP: SendMessage( WindowPlaylist, message, wp, lp ); return 0; } return CallWindowProc( WndprocSeekBackup, hwnd, message, wp, lp ); } //////////////////////////////////////////////////////////////////////////////// /// //////////////////////////////////////////////////////////////////////////////// LRESULT CALLBACK WndprocVol( HWND hwnd, UINT message, WPARAM wp, LPARAM lp ) { static bool bDown = false; static int iLastVal = 0; switch( message ) { case WM_LBUTTONDOWN: SetFocus( hwnd ); // Capture mouse SetCapture( hwnd ); bDown = true; // NO BREAK! case WM_MOUSEMOVE: { if( !bDown ) break; RECT r; GetWindowRect( hwnd, &r ); const int iWidth = r.right - r.left; if( !iWidth ) return 0; const int x = ( int )( short )LOWORD( lp ); int iVal = 255 * x / ( int )iWidth; if( iVal < 0 ) iVal = 0; else if( ( iVal > 255 ) || ( abs( iWidth - x ) < 7 ) ) // Snap iVal = 255; // Update slider PostMessage( hwnd, TBM_SETPOS , ( WPARAM )( TRUE ), iVal ); // Apply volume iLastVal = iVal; Playback::Volume::Set( iLastVal ); return 0; } case WM_LBUTTONUP: case WM_NCLBUTTONUP: { // Release capture bDown = false; ReleaseCapture(); TCHAR szBuffer[ 5000 ]; _stprintf( szBuffer, TEXT( "Volume changed to %i%%" ), iLastVal * 100 / 255 ); Console::Append( szBuffer ); Console::Append( " " ); return 0; } } return CallWindowProc( WndprocVolBackup, hwnd, message, wp, lp ); } //////////////////////////////////////////////////////////////////////////////// /// //////////////////////////////////////////////////////////////////////////////// LRESULT CALLBACK WndprocPan( HWND hwnd, UINT message, WPARAM wp, LPARAM lp ) { static bool bDown = false; static int iLastVal = 0; switch( message ) { case WM_LBUTTONDOWN: SetFocus( hwnd ); // Capture mouse SetCapture( hwnd ); bDown = true; // NO BREAK! case WM_MOUSEMOVE: { if( !bDown ) break; RECT r; GetWindowRect( hwnd, &r ); const int iWidth = r.right - r.left; if( !iWidth ) return 0; const int x = ( int )( short )LOWORD( lp ); int iVal = 254 * x / ( int )iWidth - 127; if( iVal < -127 ) iVal = -127; else if( iVal > 127 ) iVal = 127; else if( abs( ( int )iWidth / 2 - x ) < 7 ) // Snap iVal = 0; // Update slider PostMessage( hwnd, TBM_SETPOS , ( WPARAM )( TRUE ), iVal ); // Invert if needed (slider needs original value!) if( bInvertPanSlider ) { iVal = -iVal; } // Apply panning iLastVal = iVal; Playback::Pan::Set( iVal ); return 0; } case WM_LBUTTONUP: case WM_NCLBUTTONUP: { // Release capture bDown = false; ReleaseCapture(); TCHAR szBuffer[ 5000 ]; if( iLastVal < 0 ) _stprintf( szBuffer, TEXT( "Panning changed to %i%% left" ), -iLastVal * 100 / 127 ); else if( iLastVal == 0 ) _stprintf( szBuffer, TEXT( "Panning changed to center" ) ); else // if( iLastVal > 0 ) _stprintf( szBuffer, TEXT( "Panning changed to %i%% right" ), iLastVal * 100 / 127 ); Console::Append( szBuffer ); Console::Append( " " ); return 0; } } return CallWindowProc( WndprocPanBackup, hwnd, message, wp, lp ); } //////////////////////////////////////////////////////////////////////////////// /// //////////////////////////////////////////////////////////////////////////////// LRESULT CALLBACK WndprocVis( HWND hwnd, UINT message, WPARAM wp, LPARAM lp ) { switch( message ) { case WM_SHOWWINDOW: { if( wp == FALSE ) { const HWND hChild = GetWindow( hwnd, GW_CHILD ); if( !IsWindow( hChild ) ) break; // Strange workaround ShowWindow( hChild, FALSE ); SetParent( hChild, NULL ); PostMessage( hChild, WM_SYSCOMMAND, SC_CLOSE, 0 ); } } break; case WM_SIZE: { // Resize vis child HWND hChild = GetWindow( hwnd, GW_CHILD ); if( !IsWindow( hChild ) ) break; MoveWindow( hChild, 0, 0, LOWORD( lp ), HIWORD( lp ), TRUE ); } break; } return CallWindowProc( WndprocVisBackup, hwnd, message, wp, lp ); } ///////////////////////// /* // Create the toolbar control to be added. // hwndTB = CreateToolbar(hwndOwner, dwStyle); // Get the height of the toolbar. dwBtnSize = SendMessage(hwndTB, TB_GETBUTTONSIZE, 0,0); // Set values unique to the band with the toolbar. rbBand.lpText = "Tool Bar"; rbBand.hwndChild = hwndTB; rbBand.cxMinChild = 0; rbBand.cyMinChild = HIWORD(dwBtnSize); rbBand.cx = 250; // Add the band that has the toolbar. SendMessage(rebar, RB_INSERTBAND, (WPARAM)-1, (LPARAM)&rbBand); */ /////////////////////////////////////// /* void band_dummy() { REBARBANDINFO rbbi3; rbbi3.cbSize = sizeof( REBARBANDINFO ); rbbi3.fMask = 0 | // RBBIM_BACKGROUND | // The hbmBack member is valid or must be filled. // RBBIM_CHILD | // The hwndChild member is valid or must be filled. // RBBIM_CHILDSIZE | // The cxMinChild, cyMinChild, cyChild, cyMaxChild, and cyIntegral members are valid or must be filled. // RBBIM_COLORS | // The clrFore and clrBack members are valid or must be filled. // RBBIM_HEADERSIZE | // Version 4.71. The cxHeader member is valid or must be filled. RBBIM_IDEALSIZE | // Version 4.71. The cxIdeal member is valid or must be filled. RBBIM_ID | // The wID member is valid or must be filled. // RBBIM_IMAGE | // The iImage member is valid or must be filled. // RBBIM_LPARAM | // Version 4.71. The lParam member is valid or must be filled. RBBIM_SIZE | // The cx member is valid or must be filled. RBBIM_STYLE | // The fStyle member is valid or must be filled. RBBIM_TEXT | // The lpText member is valid or must be filled. 0; rbbi3.fStyle = RBBS_GRIPPERALWAYS; // | RBBS_BREAK; rbbi3.lpText = " "; //NULL; // "Dummy"; rbbi3.hwndChild = NULL; rbbi3.cxMinChild = 10; //rc.right - rc.left; rbbi3.cyMinChild = 21; // IMP rbbi3.cx = 300; rbbi3.wID = BAND_ID_DUMMY; rbbi3.cyChild = 21; //rc.bottom - rc.top; rbbi3.cyMaxChild = 21; // rc.bottom - rc.top; rbbi3.cyIntegral = 1; rbbi3.cxIdeal = 700; //rc.right - rc.left; // Add the band that has the combo box. SendMessage( rebar, RB_INSERTBAND, ( WPARAM )-1, ( LPARAM )&rbbi3 ); } */