PLUGIN_EXPORT void Initialize(void** data, void* rm) { Measure* measure = new Measure; *data = measure; // Get the path to the settings data file measure->dataFile = RmGetSettingsFile(); }
void SetupGlobalProxySetting() { if (!g_ProxyCachePool) { WCHAR buffer[MAX_PATH] = {0}; LPCWSTR file = RmGetSettingsFile(); GetPrivateProfileString(L"WebParser.dll", L"ProxyServer", nullptr, buffer, MAX_PATH, file); g_ProxyCachePool = new ProxyCachePool(buffer); } }
/* ** Create receiver window. ** */ void PlayerCAD::Initialize() { // Create windows class WNDCLASS wc = {0}; wc.hInstance = g_Instance; wc.lpfnWndProc = WndProc; wc.lpszClassName = L"NowPlayingCADClass"; RegisterClass(&wc); // Create reciever window m_Window = CreateWindow( L"NowPlayingCADClass", L"CD Art Display 1.x Class", WS_DISABLED, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, nullptr, nullptr, g_Instance, this); // Add WM_USER/WM_COPYDATA to allowed messages from lower level processes const HMODULE hUser32 = GetModuleHandle(L"user32"); // Try ChangeWindowMessageFilterEx first (Win7+) auto changeWindowMessageFilterEx = (decltype(ChangeWindowMessageFilterEx)*)GetProcAddress(hUser32, "ChangeWindowMessageFilterEx"); if (changeWindowMessageFilterEx) { changeWindowMessageFilterEx(m_Window, WM_USER, MSGFLT_ALLOW, nullptr); changeWindowMessageFilterEx(m_Window, WM_COPYDATA, MSGFLT_ALLOW, nullptr); } else { // Try ChangeWindowMessageFilter (Vista) auto changeWindowMessageFilter = (decltype(ChangeWindowMessageFilter)*)GetProcAddress(hUser32, "ChangeWindowMessageFilter"); if (changeWindowMessageFilter) { changeWindowMessageFilter(WM_USER, MSGFLT_ALLOW); changeWindowMessageFilter(WM_COPYDATA, MSGFLT_ALLOW); } } WCHAR buffer[MAX_PATH]; LPCTSTR file = RmGetSettingsFile(); // Read saved settings GetPrivateProfileString(L"NowPlaying.dll", L"ClassName", nullptr, buffer, MAX_PATH, file); std::wstring className = buffer; GetPrivateProfileString(L"NowPlaying.dll", L"WindowName", nullptr, buffer, MAX_PATH, file); std::wstring windowName = buffer; GetPrivateProfileString(L"NowPlaying.dll", L"PlayerPath", nullptr, buffer, MAX_PATH, file); m_PlayerPath = buffer; LPCTSTR classSz = className.empty() ? nullptr : className.c_str(); LPCTSTR windowSz = windowName.empty() ? nullptr : windowName.c_str(); if (classSz || windowSz) { m_PlayerWindow = FindWindow(classSz, windowSz); } else { classSz = L"CD Art Display IPC Class"; m_PlayerWindow = FindWindow(classSz, nullptr); if (m_PlayerWindow) { WritePrivateProfileString(L"NowPlaying.dll", L"ClassName", classSz, file); windowSz = (GetWindowText(m_PlayerWindow, buffer, MAX_PATH) > 0) ? buffer : nullptr; WritePrivateProfileString(L"NowPlaying.dll", L"WindowName", windowSz, file); DWORD pID; GetWindowThreadProcessId(m_PlayerWindow, &pID); HANDLE hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, pID); if (hProcess) { if (GetModuleFileNameEx(hProcess, nullptr, buffer, MAX_PATH) > 0) { WritePrivateProfileString(L"NowPlaying.dll", L"PlayerPath", buffer, file); } CloseHandle(hProcess); } } } if (m_PlayerWindow) { m_Initialized = true; if (classSz && wcscmp(classSz, L"CD Art Display IPC Class") == 0) { m_ExtendedAPI = true; } SendMessage(m_PlayerWindow, WM_USER, (WPARAM)m_Window, IPC_SET_CALLBACK_HWND); m_State = (StateType)SendMessage(m_PlayerWindow, WM_USER, 0, IPC_GET_STATE); if (m_State != STATE_STOPPED) { SendMessage(m_PlayerWindow, WM_USER, 0, IPC_GET_CURRENT_TRACK); } } }
/* ** Window procedure for the reciever window. ** */ LRESULT CALLBACK PlayerCAD::WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) { static PlayerCAD* player; switch (msg) { case WM_CREATE: { // Get pointer to the PlayerCAD class from the CreateWindow call player = (PlayerCAD*)((CREATESTRUCT*)lParam)->lpCreateParams; return 0; } case WM_DESTROY: { SendMessage(player->m_PlayerWindow, WM_USER, 0, IPC_SHUTDOWN_NOTIFICATION); return 0; } case WM_USER: switch (lParam) { case IPC_TRACK_CHANGED_NOTIFICATION: { PostMessage(player->m_PlayerWindow, WM_USER, 0, IPC_GET_CURRENT_TRACK); break; } case IPC_STATE_CHANGED_NOTIFICATION: { player->m_State = (StateType)wParam; if (player->m_State == STATE_STOPPED) { player->ClearData(false); } break; } case IPC_VOLUME_CHANGED_NOTIFICATION: { player->m_Volume = (UINT)wParam; break; } case IPC_REPEAT_CHANGED_NOTIFICATION: { player->m_Repeat = wParam != 0; break; } case IPC_SHUFFLE_CHANGED_NOTIFICATION: { player->m_Shuffle = wParam != 0; break; } case IPC_RATING_CHANGED_NOTIFICATION: { player->m_Rating = ((UINT)wParam + 1) / 2; // From 0 - 10 to 0 - 5 break; } case IPC_SHUTDOWN_NOTIFICATION: { player->m_Initialized = false; player->ClearData(); break; } } return 0; case WM_COPYDATA: { PCOPYDATASTRUCT cds = (PCOPYDATASTRUCT)lParam; if (cds->dwData == IPC_CURRENT_TRACK_NOTIFICATION) { player->m_Shuffle = SendMessage(player->m_PlayerWindow, WM_USER, 0, IPC_GET_SHUFFLE) != 0; player->m_Repeat = SendMessage(player->m_PlayerWindow, WM_USER, 0, IPC_GET_REPEAT) != 0; // TODO: Sent on track update? ++player->m_TrackCount; WCHAR* data = (WCHAR*)cds->lpData; WCHAR* pos; UINT index = 1; while ((pos = wcschr(data, '\t')) != nullptr) { switch (index) { case 1: player->m_Title.assign(data, pos - data); break; case 2: player->m_Artist.assign(data, pos - data); break; case 3: player->m_Album.assign(data, pos - data); break; case 4: player->m_Genre.assign(data, pos - data); break; case 5: player->m_Year = (UINT)_wtoi(data); break; case 7: player->m_Number = (UINT)_wtoi(data); break; case 8: player->m_Duration = (UINT)_wtoi(data); break; case 9: player->m_FilePath.assign(data, pos - data); break; case 10: player->m_Rating = ((UINT)_wtoi(data) + 1) / 2; // 0 - 10 -> 0 - 5 break; case 11: if (*data == L' ') { player->FindCover(); } else { player->m_CoverPath.assign(data, pos - data); } break; } data = pos + 1; ++index; if (index == 12) { break; } } if (player->m_Measures & MEASURE_LYRICS) { player->FindLyrics(); } } else if (cds->dwData == IPC_NEW_COVER_NOTIFICATION) { WCHAR* data = (WCHAR*)cds->lpData; if (data) { player->m_CoverPath.assign(data); } } else if (cds->dwData == IPC_REGISTER_NOTIFICATION && !player->m_Initialized) { std::wstring data = (WCHAR*)cds->lpData; if (data[0] == L'1') { data.erase(0, 2); // Get rid of the 1\t at the beginning std::wstring::size_type len = data.find_first_of(L'\t'); std::wstring className(data, 0, len); data.erase(0, ++len); len = data.find_first_of(L'\t'); std::wstring windowName(data, 0, len); data.erase(0, ++len); len = data.find_first_of(L'\t'); player->m_PlayerPath.assign(data, 0, len); data.erase(0, ++len); LPCTSTR classSz = className.empty() ? nullptr : className.c_str(); LPCTSTR windowSz = windowName.empty() ? nullptr : windowName.c_str(); LPCTSTR file = RmGetSettingsFile(); WritePrivateProfileString(L"NowPlaying.dll", L"ClassName", classSz, file); WritePrivateProfileString(L"NowPlaying.dll", L"WindowName", windowSz, file); WritePrivateProfileString(L"NowPlaying.dll", L"PlayerPath", player->m_PlayerPath.c_str(), file); player->m_PlayerWindow = FindWindow(classSz, windowSz); if (player->m_PlayerWindow) { player->m_Initialized = true; player->m_ExtendedAPI = (classSz && wcscmp(classSz, L"CD Art Display IPC Class") == 0); player->m_State = (StateType)SendMessage(player->m_PlayerWindow, WM_USER, 0, IPC_GET_STATE); if (player->m_State != STATE_STOPPED) { PostMessage(player->m_PlayerWindow, WM_USER, 0, IPC_GET_CURRENT_TRACK); } if (player->m_Open) { if (windowSz && wcscmp(windowSz, L"foobar2000") == 0) { // Activate foobar2000 in case it starts minimized SendMessage(player->m_PlayerWindow, WM_USER, 0, IPC_SHOW_WINDOW); } player->m_Open = false; } } } } } return 0; default: return DefWindowProc(hwnd, msg, wParam, lParam); } }