To pass command line arguments you have to start another instance. But this instance can check if another one is already running, pass the arguments and terminate.
This requires three steps:
- Detect running instances
- Passing arguments
- Handling passed arguments
Detect running instances
A common method to do this is using global mutexes. See
CreateMutex function (Windows)[
^] and
Avoiding Multiple Application Instances[
^].
Passing arguments
As already mentioned this requires some kind of IPC (Inter Process Communication). One solution is broadcasting a registered message. See
RegisterWindowMessage function (Windows)[
^] and
BroadcastSystemMessage function (Windows)[
^].
Handling passed arguments
This depends on your application and must be implemented by you.
Here an untested example (portions has been copied from existing code):
BOOL CMyApp::InitInstance()
{
m_nPrivateMessage =
::RegisterWindowMessage(_T("my_unique_application_identifier"));
HANDLE hMutexAppRunning = ::CreateMutex(NULL, FALSE,
_T("Global\\my_unique_application_identifier"));
DWORD dwErr = ::GetLastError();
if (dwErr == ERROR_ALREADY_EXISTS || dwErr == ERROR_ACCESS_DENIED)
{
int cmdSize = 1;
for (int i = 0; i < __argc; i++)
cmdSize += 1 + _tcslen(__argv[i]);
HGLOBAL hGlobal = ::GlobalAlloc(GMEM_MOVEABLE, cmdSize * sizeof(TCHAR));
LPTSTR lpBuf = ::GlobalLock(hGlobal);
for (int i = 0; i < __argc; i++)
{
size_t len = 1 + _tcslen(__argv[i]);
memcpy(lpBuf, __argv[i], len);
lpBuf += len;
}
*lpBuf = _T('\0');
::GlobalUnlock(hGlobal);
DWORD dwRecipients = BSM_APPLICATIONS;
::BroadcastSystemMessage(
BSF_IGNORECURRENTTASK | BSF_ALLOWSFW,
&dwRecipients,
m_nPrivateMessage,
(WPARAM)hGlobal,
(LPARAM)::GetDesktopWindow());
return FALSE;
}
return TRUE;
}
ON_REGISTERED_MESSAGE(App()->m_nPrivateMessage, OnPrivateBroadcast)
LRESULT CMainFrame::OnPrivateBroadcast(WPARAM wParam, LPARAM lParam)
{
int argc = 0;
LPTSTR args = ::GlobalLock((HGLOBAL)wParam);
while (*args)
{
args += 1 + _tcslen(args);
++argc;
}
::GlobalUnlock((HGLOBAL)wParam);
::GlobalFree((HGLOBAL)wParam);
if (NULL == lParam || ::GetDesktopWindow() == reinterpret_cast<HWND>(lParam))
{
if (IsIconic())
ShowWindow(SW_RESTORE);
CWnd *pWndChild = GetLastActivePopup();
if (pWndChild)
pWndChild->SetForegroundWindow();
}
return TRUE;
}