diff --git a/Library/MeterButton.cpp b/Library/MeterButton.cpp index 68c01120..9140907e 100644 --- a/Library/MeterButton.cpp +++ b/Library/MeterButton.cpp @@ -287,8 +287,7 @@ bool CMeterButton::MouseUp(POINT pos, CMeterWindow* window) { if (window && m_Clicked && m_Executable && HitTest2(pos.x, pos.y, true)) { - // Do a delayed execute or ortherwise !RainmeterRefresh crashes - PostMessage(window->GetWindow(), WM_DELAYED_EXECUTE, (WPARAM)NULL, (LPARAM)m_Command.c_str()); + Rainmeter->ExecuteCommand(m_Command.c_str(), window); } m_State = BUTTON_STATE_NORMAL; m_Clicked = false; diff --git a/Library/MeterWindow.cpp b/Library/MeterWindow.cpp index abdc4782..5ea5c33f 100644 --- a/Library/MeterWindow.cpp +++ b/Library/MeterWindow.cpp @@ -4312,7 +4312,7 @@ LRESULT CMeterWindow::OnDelayedExecute(WPARAM wParam, LPARAM lParam) COPYDATASTRUCT copyData; copyData.dwData = 1; - copyData.cbData = (DWORD)((lstrlen(szExecute))* sizeof(WCHAR)); + copyData.cbData = (DWORD)((wcslen(szExecute) + 1) * sizeof(WCHAR)); copyData.lpData = (void*)szExecute; OnCopyData(NULL, (LPARAM)©Data); @@ -4402,6 +4402,16 @@ LRESULT CMeterWindow::OnCopyData(WPARAM wParam, LPARAM lParam) } std::wstring str = (const WCHAR*)pCopyDataStruct->lpData; + + if (wcsnicmp(L"PLAY ", str.c_str(), 5) == 0 || + wcsnicmp(L"PLAYLOOP ", str.c_str(), 9) == 0 || + wcsnicmp(L"PLAYSTOP", str.c_str(), 8) == 0) + { + // Audio commands are special cases. + Rainmeter->ExecuteCommand(str.c_str(), this); + return TRUE; + } + std::wstring bang; std::wstring arg; diff --git a/Library/Rainmeter.cpp b/Library/Rainmeter.cpp index 34ead7e9..bb036bd4 100644 --- a/Library/Rainmeter.cpp +++ b/Library/Rainmeter.cpp @@ -2653,10 +2653,31 @@ void CRainmeter::ExecuteCommand(const WCHAR* command, CMeterWindow* meterWindow) if (!strCommand.empty()) { - // Check for build-ins - if (wcsncmp(L"PLAY ", strCommand.c_str(), 5) == 0) + // Check for built-ins + if (wcsnicmp(L"PLAY ", strCommand.c_str(), 5) == 0 || + wcsnicmp(L"PLAYLOOP ", strCommand.c_str(), 9) == 0) { - BOOL ret = PlaySound(strCommand.c_str() + 5, NULL, SND_FILENAME | SND_ASYNC); + // Strip built-in command + size_t pos = strCommand.find(L' '); + strCommand.erase(0, pos + 1); + + if (!strCommand.empty()) + { + DWORD flags = SND_FILENAME | SND_ASYNC; + if (pos == 8) // PLAYLOOP + { + flags |= SND_LOOP | SND_NODEFAULT; + } + + // Strip the quotes + std::wstring::size_type len = strCommand.length(); + if (len >= 2 && strCommand[0] == L'\"' && strCommand[len - 1] == L'\"') + { + strCommand.swap(strCommand.substr(1, len - 2)); + } + + PlaySound(strCommand.c_str(), NULL, flags); + } return; } else if (wcsncmp(L"PLAYSTOP", strCommand.c_str(), 8) == 0) @@ -2664,11 +2685,6 @@ void CRainmeter::ExecuteCommand(const WCHAR* command, CMeterWindow* meterWindow) PlaySound(NULL, NULL, SND_PURGE); return; } - else if (wcsncmp(L"PLAYLOOP ", strCommand.c_str(), 9) == 0) - { - PlaySound(strCommand.c_str() + 9, NULL, SND_ASYNC | SND_FILENAME | SND_LOOP | SND_NODEFAULT); - return; - } // Run the command if(strCommand.c_str()[0] == L'!' && Rainmeter->GetDummyLitestep()) diff --git a/Library/TrayWindow.cpp b/Library/TrayWindow.cpp index afd5b4de..46787d35 100644 --- a/Library/TrayWindow.cpp +++ b/Library/TrayWindow.cpp @@ -588,15 +588,7 @@ LRESULT CALLBACK CTrayWindow::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARA if (!bang.empty()) { - std::wstring arg; - size_t pos = bang.find(L' '); - if (pos != std::wstring::npos) - { - arg = bang; - arg.erase(0, pos + 1); - bang = bang.substr(0, pos); - } - Rainmeter->ExecuteBang(bang, arg, NULL); + Rainmeter->ExecuteCommand(bang.c_str(), NULL); } else if (uMouseMsg == WM_RBUTTONDOWN) {