#include "master.h" #include #include #include #include #include #include #include "stream.h" #include "gui.h" #include "misc.h" #include "playlist.h" #include "systray.h" #include "flags.h" #include "metaparse.h" #include "menu.h" #include "comfunct/comfunct.h" LRESULT StopStream(HWND hwnd, short *sOptions, REFERENCE_TIME rtStartTime) { extern bool bCanSeek; extern IMediaSeeking *pSeek; extern IMediaControl *pControl; TCHAR* szAudioStatusText = GetStatusText(hwnd, 0); if(_tcscmp(szAudioStatusText, GetLocalText(83)) == 0) /* Downloading */ { StopInternetDownload(); } else { OAFilterState fsState; REFERENCE_TIME rtTimeNow; pControl->lpVtbl->GetState(pControl, 10, &fsState); if(SUCCEEDED(pControl->lpVtbl->Stop(pControl))) { KillTimer(hwnd, IDT_TIMETICK); *sOptions &= (~(TIMER_ON)); } pSeek->lpVtbl->SetPositions(pSeek, &rtStartTime, AM_SEEKING_AbsolutePositioning, NULL, AM_SEEKING_NoPositioning); pSeek->lpVtbl->GetCurrentPosition(pSeek, &rtTimeNow); SetStatus(hwnd, IDI_STATUS, 0, GetLocalText(37)); SendDlgItemMessage(hwnd, IDI_SLIDER, TBM_SETPOS, true, 0); if(bCanSeek == true) { ElapsedTimeUpdate(hwnd, rtTimeNow); } if(fsState == State_Paused) { SetDlgItemText(hwnd, IDI_CONT_PAUSE, GetLocalText(2)); } } free(szAudioStatusText); MSNCheckAndUpdate(hwnd, true); UpdateTrayToolTip(hwnd); return 0; } LRESULT TogglePause(HWND hwnd, short* sOptions, bool bMediaKeyPlay) { OAFilterState fsState; extern bool bCanSeek; extern IMediaControl *pControl; pControl->lpVtbl->GetState(pControl, 10, &fsState); if(fsState == State_Running) { if(SUCCEEDED(pControl->lpVtbl->Pause(pControl))) { if(bCanSeek == true) { KillTimer(hwnd, IDT_TIMETICK); *sOptions &= (~(TIMER_ON)); } SetStatus(hwnd, IDI_STATUS, 0, GetLocalText(38)); SetDlgItemText(hwnd, IDI_CONT_PAUSE, GetLocalText(12)); } } else if(fsState == State_Paused || bMediaKeyPlay == true) { if(SUCCEEDED(pControl->lpVtbl->Run(pControl))); { if(bCanSeek == true) { SetTimer(hwnd, IDT_TIMETICK, 1000, (TIMERPROC)NULL); *sOptions |= TIMER_ON; } SetDlgItemText(hwnd, IDI_CONT_PAUSE, GetLocalText(2)); SetStatus(hwnd, IDI_STATUS, 0, GetLocalText(39)); } } UpdateTrayToolTip(hwnd); return 0; } LRESULT PlayLocalFile(HWND hwnd, bool bTrayed, LPTSTR szFilePath) { if(PathFileExists(szFilePath) == false) { ErrorMessage(GetLocalText(40)); return 0; } if(GetPlaylistType(szFilePath) != PLAYLIST_ERROR) { SendMessage(hwnd, WM_COMMAND, MAKEWPARAM(IDI_PLAYLIST_COMMANDLINE, 0), (LPARAM)szFilePath); } else if(IsFileAudio(szFilePath) == false) { ErrorMessage(GetLocalText(41)); } else { ProcessFile(hwnd, bTrayed, szFilePath, NULL); } return 0; } LRESULT PlayNonMP3URL(HWND hwnd, LPTSTR szFilePath, HANDLE* hDownloadedStream, DWORD capable) { WCHAR* WideFilePath = NULL; HRESULT hr = 0; extern bool bCanSeek; extern IMediaSeeking *pSeek; extern IGraphBuilder *pGraph; extern IMediaControl *pControl; if(pGraph == NULL) { DShowInit(); } #ifndef UNICODE /* we're doing the same unicode conversion hack as elsewhere */ WideFilePath = UnicodeConversion(szFilePath); hr = pGraph->lpVtbl->RenderFile(pGraph, WideFilePath, NULL); FreePointer(WideFilePath); #else hr = pGraph->lpVtbl->RenderFile(pGraph, szFilePath, NULL); #endif /* end of !UNICODE 'if' */ if(FAILED(hr)) { ErrorMessage(GetLocalText(42)); HRErrorInfo(hr); CloseStream(hwnd, hDownloadedStream); return 0; } if(_tcsicmp(PathFindExtension(szFilePath), TEXT(".ogg")) == 0) { bCanSeek = false; /* Finding the file duration isn't implemented in all ogg codecs If we continue to try and seek and it isn't implemented, we'll get a divide by zero exception */ } else { bCanSeek = (S_OK == pSeek->lpVtbl->CheckCapabilities(pSeek, &capable)); } FileOpen(hwnd, szFilePath, bCanSeek); hr = 0; hr = pControl->lpVtbl->Run(pControl); /* This just tests to see if we can play the file and error out if not */ if(FAILED(hr)) { ErrorMessage(GetLocalText(41)); HRErrorInfo(hr); CloseStream(hwnd, hDownloadedStream); return 0; } pControl->lpVtbl->Stop(pControl); PostMessage(hwnd, WM_COMMAND, MAKEWPARAM(IDI_CONT_PLAY, 0), (LPARAM)NULL); return 0; } LRESULT PrepareAndPlayMP3Stream(HWND hwnd, LPARAM lParam, bool bTrayed, HANDLE* hDownloadedStream) { const size_t sMaxLen = (MAX_PATH * sizeof(TCHAR)); TCHAR* szAudioFile = malloc(sMaxLen); HMENU hParentMenu = GetMenu(hwnd), hOpenMenu = NULL, hControlMenu = NULL; CopyMemory(szAudioFile, (LPVOID)lParam, sMaxLen); hOpenMenu = GetSubMenu(hParentMenu, FILE_MENU); EnableMenuItem(hParentMenu, IDI_FILE_SAVESTREAM, MF_BYCOMMAND | MF_ENABLED); ToggleButton(hwnd, true, false); hControlMenu = GetSubMenu(hParentMenu, CONTROL_MENU); EnableMenuItem(hControlMenu, IDI_CONT_PAUSE, MF_BYCOMMAND | MF_ENABLED); EnableMenuItem(hControlMenu, IDI_CONT_PLAY, MF_BYCOMMAND | MF_ENABLED); DrawMenuBar(hwnd); ProcessFile(hwnd, bTrayed, szAudioFile, NULL); if(*hDownloadedStream != NULL) { CloseHandle(*hDownloadedStream); } *hDownloadedStream = CreateFile(szAudioFile, GENERIC_READ | DELETE, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_TEMPORARY | FILE_FLAG_DELETE_ON_CLOSE, NULL); if(*hDownloadedStream == NULL || *hDownloadedStream == INVALID_HANDLE_VALUE) { ErrorInfo(); ErrorMessage(GetLocalText(43)); free(szAudioFile); CloseStream(hwnd, hDownloadedStream); return 1; } SaveAudioStream(*hDownloadedStream, NULL); free(szAudioFile); return 0; } LRESULT ParseDroppedFile(HWND hwnd, WPARAM wParam, PLAYLISTDATA* pld) { HDROP hFilesInfo = NULL; extern IGraphBuilder *pGraph; unsigned long lFileCount = 0L; TCHAR szFileName[MAX_PATH] = {0}; HCURSOR hWait = LoadCursor(NULL, IDC_WAIT), hArrow = LoadCursor(NULL, IDC_ARROW); SetCursor(hWait); hFilesInfo = (HDROP)wParam; lFileCount = DragQueryFile(hFilesInfo, 0xFFFFFFFF, NULL, 0); if(pGraph != NULL) { SendMessage(hwnd, WM_COMMAND, MAKEWPARAM(IDI_FILE_CLOSE, 0), (LPARAM)NULL); } if(lFileCount == 1L) { DragQueryFile(hFilesInfo, 0, szFileName, MAX_PATH); CommandLineOpen(szFileName, hwnd); } else { unsigned long lLoopCounter = 0L; size_t s_tStrlen = 0; TCHAR szBuffer[MAX_PATH] = TEXT(""); HWND hPlaylistItems = GetDlgItem(hwnd, IDI_PLAYLIST_VIEW); DWORD dwThreadId = 0; pld->PlaylistItems = malloc(lFileCount * sizeof(TCHAR*)); pld->lNumOfFilesinPlaylist = lFileCount; SetStatus(hwnd, IDI_STATUS, 0, GetLocalText(44)); for(; lLoopCounter < lFileCount; ++lLoopCounter) { DragQueryFile(hFilesInfo, lLoopCounter, szBuffer, MAX_PATH); s_tStrlen = (_tcslen(szBuffer) + sizeof(TCHAR)); pld->PlaylistItems[lLoopCounter] = malloc(s_tStrlen * sizeof(TCHAR)); _tcscpy(pld->PlaylistItems[lLoopCounter], szBuffer); } StartPlaylist(pld, hwnd); CloseHandle(CreateThread(NULL, 0, BuildPlaylistView, (LPVOID)pld, 0, &dwThreadId)); } DragFinish(hFilesInfo); SetCursor(hArrow); return 0; } LRESULT LyricsHandler(HWND hwnd) { TCHAR szFile[MAX_PATH] = TEXT(""); GetWindowText(GetDlgItem(hwnd, IDI_FILENAME), szFile, MAX_PATH); DisplayLyrics(hwnd, szFile); return 0; } LRESULT NotifyMessage(HWND hwnd, LPARAM lParam, PLAYLISTDATA* pld, short sOptions) { LPNMHDR lpnmHdr = (LPNMHDR)lParam; switch(lpnmHdr->code) { case NM_DBLCLK: { NMITEMACTIVATE nmItem = *(NMITEMACTIVATE*)lParam; LVITEM lvi = {LVIF_PARAM}; //Find the item and get its' LPARAM value to use to index pld lvi.iItem = nmItem.iItem; ListView_GetItem(lpnmHdr->hwndFrom, &lvi); pld->lCurrentPlayingFile = lvi.lParam; CloseStream(hwnd, NULL); ProcessFile(hwnd, sOptions & IS_TRAYED, pld->PlaylistItems[lvi.lParam], pld); } break; case NM_RCLICK: { POINT pt = {0}; GetCursorPos(&pt); DestroyMenu(MakePViewMenu(hwnd, pt)); } break; } return 0; } LRESULT PlayFolder(HWND hwnd, PLAYLISTDATA* pld) { BROWSEINFO bi = {0}; LPITEMIDLIST pid = NULL; TCHAR szPattern[MAX_PATH] = TEXT(""); WIN32_FIND_DATA wfd = {0}; HANDLE hFile = NULL; unsigned long lFileCount = 0; extern IGraphBuilder *pGraph; bi.lpszTitle = GetLocalText(45); bi.hwndOwner = hwnd; pid = SHBrowseForFolder(&bi); if(pid == NULL) { return 1; } SHGetPathFromIDList(pid, szPattern); SetStatus(hwnd, IDI_STATUS, 0, GetLocalText(44)); _tcscat(szPattern, TEXT("\\*.*")); if(pGraph != NULL) { SendMessage(hwnd, WM_COMMAND, MAKEWPARAM(IDI_FILE_CLOSE, 0), 0); } hFile = FindFirstFile(szPattern, &wfd); while(FindNextFile(hFile, &wfd) != 0) { /* not interested in any directories */ if(wfd.cFileName[0] == TEXT('.') || (wfd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) { continue; } ++lFileCount; } FindClose(hFile); pld->lNumOfFilesinPlaylist = lFileCount; pld->PlaylistItems = malloc(lFileCount * sizeof(TCHAR*)); FolderFilesToPlaylist(szPattern, pld); return 0; } #ifdef UNICODE LRESULT AppCommand(HWND hwnd, LPARAM lParam) { short dwCommand = ((short)(HIWORD(lParam) & ~0xF000)); //GET_APPCOMMAND_LPARAM(lParam) not defined in MinGW Win32API 3.6 switch(dwCommand) { /*avoiding more icky ifdef's here by just using the number since some of these are only defines for XPSP1 or above */ case 46: /* APPCOMMAND_MEDIA_PLAY */ { SendMessage(hwnd, WM_COMMAND, MAKEWPARAM(IDI_CONT_PLAY, 0), 0); } break; case 47: /* APPCOMMAND_MEDIA_PAUSE */ case 14: /*APPCOMMAND_MEDIA_PLAY_PAUSE */ { SendMessage(hwnd, WM_COMMAND, MAKEWPARAM(IDI_CONT_PAUSE, 0), 0); } break; case 13: /* APPCOMMAND_MEDIA_STOP */ { SendMessage(hwnd, WM_COMMAND, MAKEWPARAM(IDI_CONT_STOP, 0), 0); } break; case 11: /* APPCOMMAND_MEDIA_NEXTTRACK */ { SendMessage(hwnd, WM_COMMAND, MAKEWPARAM(IDI_PLAYLIST_NEXT, 0), 0); } break; case 8: /* APPCOMMAND_VOLUME_MUTE */ { SendMessage(hwnd, WM_COMMAND, MAKEWPARAM(IDI_VOL_MUTE, 0), 0); } break; } return TRUE; } LRESULT ToggleHook(HWND hwnd, short* sOptions) { static HHOOK hMediaKeyHook = NULL; if(!(*sOptions & MEDIA_HOOK)) { HMODULE hComFunct = GetModuleHandle(TEXT("comfunct.dll")); HOOKPROC MultiMediaHook = (HOOKPROC)GetProcAddress(hComFunct, "MultiMediaKeyHook"); MenuCheck(hwnd, TOOLS_MENU, IDI_TOOLS_MEDIAHOOK, true); *sOptions |= MEDIA_HOOK; hMediaKeyHook = SetWindowsHookEx(WH_KEYBOARD_LL, MultiMediaHook, hComFunct, 0); } else { MenuCheck(hwnd, TOOLS_MENU, IDI_TOOLS_MEDIAHOOK, false); UnhookWindowsHookEx(hMediaKeyHook); *sOptions &= (~(MEDIA_HOOK)); } return 0; } #endif