Index: Mptrack.cpp =================================================================== --- Mptrack.cpp (revision 10509) +++ Mptrack.cpp (working copy) @@ -58,7 +58,22 @@ OPENMPT_NAMESPACE_BEGIN +static const TCHAR IPCClassName[] = _T("OpenMPT_IPC_Wnd"); +static LRESULT CALLBACK IPCWindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) +{ + if(uMsg == WM_COPYDATA) + { + const auto ©Data = *reinterpret_cast(lParam); + const auto str = static_cast(copyData.lpData); + const std::wstring name(str, str + copyData.dwData / sizeof(WCHAR)); + theApp.GetModDocTemplate()->OpenDocumentFile(mpt::PathString::FromWide(name).AsNative().c_str()); + return TRUE; + } + return ::DefWindowProc(hwnd, uMsg, wParam, lParam); +} + + ///////////////////////////////////////////////////////////////////////////// // The one and only CTrackApp object @@ -130,6 +145,7 @@ class CMPTCommandLineInfo: public CCommandLineInfo { public: + std::vector m_fileNames; bool m_bNoDls = false, m_bNoPlugins = false, m_bNoAssembly = false, m_bNoSysCheck = false, m_bNoWine = false, m_bPortable = false, m_bNoCrashHandler = false, m_bDebugCrashHandler = false; #ifdef ENABLE_TESTS @@ -139,7 +155,7 @@ public: void ParseParam(LPCTSTR lpszParam, BOOL bFlag, BOOL bLast) override { - if ((lpszParam) && (bFlag)) + if(lpszParam && bFlag) { if (!lstrcmpi(lpszParam, _T("nologo"))) { m_bShowSplash = FALSE; return; } if (!lstrcmpi(lpszParam, _T("nodls"))) { m_bNoDls = true; return; } @@ -154,6 +170,10 @@ #ifdef ENABLE_TESTS if (!lstrcmpi(lpszParam, _T("noTests"))) { m_bNoTests = true; return; } #endif + } else if(lpszParam && !bFlag) + { + m_fileNames.push_back(mpt::PathString::FromNative(lpszParam)); + // return; } CCommandLineInfo::ParseParam(lpszParam, bFlag, bLast); } @@ -786,6 +806,26 @@ _CrtSetDebugFillThreshold(0); // Disable buffer filling in secure enhanced CRT functions. #endif + auto ipcWnd = FindWindow(IPCClassName, nullptr); + // Still have to create our own window in case the other process closes... + { + WNDCLASS ipcWindowClass = + { + 0, + IPCWindowProc, + 0, + 0, + m_hInstance, + nullptr, + nullptr, + nullptr, + nullptr, + IPCClassName + }; + auto ipcAtom = RegisterClass(&ipcWindowClass); + CreateWindow(MAKEINTATOM(ipcAtom), _T("OpenMPT IPC Window"), 0, 0, 0, 0, 0, nullptr, nullptr, m_hInstance, 0); + } + // Initialize OLE MFC support BOOL oleinit = AfxOleInit(); ASSERT(oleinit != FALSE); // no MPT_ASSERT here! @@ -797,7 +837,24 @@ // Parse command line for standard shell commands, DDE, file open ParseCommandLine(cmdInfo); - + + if(ipcWnd && !cmdInfo.m_fileNames.empty()) + { + for(const auto &filename : cmdInfo.m_fileNames) + { + auto filenameW = filename.ToWide(); + const DWORD size = static_cast(filenameW.size() * sizeof(WCHAR)); + COPYDATASTRUCT copyData{ 0, size, &filenameW[0] }; + + DWORD_PTR result = 0; + bool success = ::SendMessageTimeout(ipcWnd, WM_COPYDATA, 0, reinterpret_cast(©Data), SMTO_ABORTIFHUNG | SMTO_BLOCK, 10000, &result) != 0; + if(success && result != 0) + { + ExitProcess(0); + } + } + } + if(IsDebuggerPresent() && cmdInfo.m_bDebugCrashHandler) { ExceptionHandler::useAnyCrashHandler = true; @@ -1030,6 +1087,7 @@ // we do not want to open an empty new one on startup. cmdInfo.m_nShellCommand = CCommandLineInfo::FileNothing; } + // TODO handle multiple files (MultiSelectModel = Player) if(!ProcessShellCommand(cmdInfo)) { EndWaitCursor();