Re: can't bring "single instance" tray app to foreground
"Frank Cusack" <fcusack@fcusack.com> wrote in message
news:m2abuaig6h.fsf@sucksless.local...
CTrayApp::CTrayApp()
: CSingleInstanceApp(TEXT("{...}"))
{
// if this is the 2nd instance, allow the 1st instance to come to fg
if (!AllowSetForegroundWindow(ASFW_ANY))
throw 1;
}
CTrayApp theApp;
BOOL
CTrayApp::InitInstance()
{
if (!AmITheFirst()) {
// wait just a bit so ASFW() in 2nd instance works
// (don't exit before 2nd instance calls SFW())
Sleep(500);
return FALSE;
}
CMainFrame *pMainFrame = new CMainFrame;
m_pMainWnd = pMainFrame;
if (!pMainFrame->Create(NULL, "foo"))
return FALSE;
m_pMainWnd->ShowWindow(SW_HIDE);
m_pMainWnd->UpdateWindow();
return TRUE;
}
void CTrayApp::OnSecondInstance(UINT, LPARAM)
{
m_pMainWnd->SetForegroundWindow(); // no effect (but main wnd was hidden)
AfxMessageBox("hello world!", MB_OK|MB_SETFOREGROUND); // not in fg
}
====
OK, let's start from scratch:
//////////////////////////////////////////////////////////////////////////
// Shared global variables - visible to all instances of this .exe
#pragma data_seg(".sdata")
HWND sh_hwndMainFrame = NULL;
#pragma data_seg()
// This comment makes the above data segment shareable
// It replaces having to add a linker option to the project
#pragma comment(linker, "/SECTION:.sdata,rws")
CTrayApp::CTrayApp()
: CSingleInstanceApp(TEXT("{...}"))
{
}
CTrayApp theApp;
BOOL
CTrayApp::InitInstance()
{
if (!AmITheFirst()) {
// this instance (the second instance) has the focus and must explicity
give it away
AllowSetForegroundWindow(ASFW_ANY);
// Request the first instance to bring its window to foreground
// Post message to CMainFrame of first instance
// Assume CMainFrame::OnSecondInstance() is called when it receives a
UWM_SECOND_INSTANCE message
ASSERT (sh_hwndMainFrame != NULL);
::PostMessage ( sh_hwndMainFrame, UWM_SECOND_INSTANCE, 0, 0);
return FALSE;
}
// First instance - create mainframe window that is hidden
CMainFrame *pMainFrame = new CMainFrame;
m_pMainWnd = pMainFrame;
if (!pMainFrame->Create(NULL, "foo"))
return FALSE;
// No need to show or update the window, as it is hidden --- comment out
//m_pMainWnd->ShowWindow(SW_HIDE);
//m_pMainWnd->UpdateWindow();
// Save main window handle for use in second instance
sh_hwndMainFrame = m_pMainWnd->GetSafeHwnd();
return TRUE;
}
Does this make sense?
-- David