Bring an application at foreground

Hi all,
I'm trying to hava only one cpy of my app running at once, to do that i get the sample code on "Hello World" generated app on embedded C++ 4.0


bool ActivatePreviousInstance()
{
bool activated =false;
int cTries;
HANDLE hMutex = NULL;

cTries = 5;
while(cTries > 0)
{
hMutex = CreateMutex(NULL, FALSE, TEXT("myMutex") );// NOTE: We don't want to own the object.

if(GetLastError() == ERROR_ALREADY_EXISTS)
{
HWND hwnd;

CloseHandle(hMutex);
hMutex = NULL;

// There is already an instance of this app
// running. Try to bring it to the foreground.

hwnd = ::FindWindow(TEXT("Dialog"), TEXT("WinTelecopie") );

if(NULL == hwnd)
{
// It's possible that the other window is in the process of being created...
Sleep(500);
hwnd = ::FindWindow(TEXT("Dialog"), TEXT("WinTelecopie") );
}

if(NULL != hwnd)
{
// Set the previous instance as the foreground window

// The "| 0x01" in the code below activates
// the correct owned window of the
// previous instance's main window.
::SetForegroundWindow((HWND) (((ULONG) hwnd) | 0x01));

// We are done.
activated = true;
break;
}

// It's possible that the instance we found isn't coming up,
// but rather is going down. Try again.
cTries--;
}
else
{
// We were the first one to create the mutex
// so that makes us the main instance. 'leak'
// the mutex in this function so it gets cleaned
// up by the OS when this instance exits.
break;
}
}

return activated;
}


This works, but it takes near 10/15 seconds to display the existing app
I trace windows messages :


WM_GETTEXT
WM_SETFOCUS
WM_IME_NOTIFY
WM_IME_SETCONTEXT
WM_ACTIVATE
WM_QUERYNEWPALETTE
WM_NCACTIVATE
WM_WINDOWPOSCHANGED
**
**
15 secondebreak
**
**
WM_CTLCOLORDLG
WM_ERASEBCKGND
WM_PAINT/////// From heere i can see my dialog boxe
and other msgs...

The probleme is that i'm not using any of these msgs so i guess, Windows take a lot of time to bring my dilaog box to the foreground :o(
As it work on "Hello World" sample i guess i make a mistake but in can't see where.

Thanks for replies

[3022 byte] By [lmussier] at [2008-2-27]
# 1

The following is what we do in Whidbey MFC (winmain.cpp), let me know if that work for you also.

#ifdef _WIN32_WCE
int aygshellUIModel = AfxGetAygshellUIModel();
if (aygshellUIModel == PocketPC || aygshellUIModel == Smartphone)
{
// only one application instance can be run
wchar_t szTempFileName[MAX_PATH], szModuleFileName[MAX_PATH];
int nFileNameLen = ::GetModuleFileName(NULL, szModuleFileName, MAX_PATH);
int idxTempFileName = 0;
for (int idxModuleFileName = 0; idxModuleFileName < nFileNameLen; idxModuleFileName++)
{
if (szModuleFileName[idxModuleFileName] == L'\\')
{
szTempFileName[idxTempFileName++] = L'/';
}
else
{
szTempFileName[idxTempFileName++] = szModuleFileName[idxModuleFileName];
}
}
szTempFileName[idxTempFileName] = L'\0';

HANDLE hMutex = ::CreateMutex(NULL, FALSE, szTempFileName);
if (hMutex != NULL)
{
if (::GetLastError() == ERROR_ALREADY_EXISTS)
{
BOOL bGoAway = FALSE;

MODULEINFO moduleInfo;
ZeroMemory(&moduleInfo, sizeof(MODULEINFO));
moduleInfo.pszModuleFileName = szModuleFileName;

int nThreadPriority = pThread->GetThreadPriority();

// Retry for 10 seconds (40 * 250 millisecons = 10000 milliseconds)
for (int i = 0; i < 40; ++i)
{
::EnumWindows(_AfxFindModuleInfoProc, (LPARAM)&moduleInfo);

if (moduleInfo.hwnd)
{
::SetForegroundWindow((HWND)(((DWORD)moduleInfo.hwnd) | 0x00000001));
bGoAway = TRUE;
break;
}
// wait for other app to finish starting or stopping
pThread->SetThreadPriority(THREAD_PRIORITY_IDLE);
Sleep(250); // sleep for one quarter second (arbitrary)
pThread->SetThreadPriority(nThreadPriority);
}

if (bGoAway)
{
::ReleaseMutex(hMutex);
goto InitFailure;
}
}
::ReleaseMutex(hMutex);
}
}
#endif

The helper function _AfxFindModuleInfoProc was defined below (in the same file)

#ifdef _WIN32_WCE
typedef struct ModuleInfo
{
wchar_t *pszModuleFileName;
HWND hwnd;
}
MODULEINFO, *PMODULEINFO;

BOOL CALLBACK _AfxFindModuleInfoProc(HWND hwnd, LPARAM lParam)
{
DWORD dwProcessID;
PMODULEINFO pModuleInfo = (PMODULEINFO)lParam;

::GetWindowThreadProcessId(hwnd, &dwProcessID);
if (!dwProcessID)
{
return TRUE;
}

wchar_t szModuleFileName[MAX_PATH];
if (!::GetModuleFileName((HMODULE)dwProcessID, szModuleFileName, MAX_PATH))
{
return TRUE;
}

if (!::wcsicmp(szModuleFileName, pModuleInfo->pszModuleFileName))
{
pModuleInfo->hwnd = hwnd;
return FALSE;
}

return TRUE;
}
#endif // _WIN32_WCE

TaoMa-MSFT at 2007-9-9 > top of Msdn Tech,Smart Device Development,Smart Devices Native C++ Development...