Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • World
  • Users
  • Groups
Skins
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Code Project
  1. Home
  2. General Programming
  3. C / C++ / MFC
  4. Single application instance

Single application instance

Scheduled Pinned Locked Moved C / C++ / MFC
helpquestion
11 Posts 7 Posters 1 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • J Offline
    J Offline
    Joe Moldovan
    wrote on last edited by
    #1

    Does anyone know of a simple way to ensure that an application has only a single instance running? When the app is clicked again the running instance should be restored and activated. I am doing all this now with an event and a background thread. It works fine but I seem to recall that there is a simpler way of doing this and I can't find it anywhere. Apropos, is it possible to send a windows message, like WM_SHOWWINDOW, between applications rather than within an application? By the way I have no problem getting the PID or the window handle if they are needed for the solution. Have Fun all.

    T L S J B 5 Replies Last reply
    0
    • J Joe Moldovan

      Does anyone know of a simple way to ensure that an application has only a single instance running? When the app is clicked again the running instance should be restored and activated. I am doing all this now with an event and a background thread. It works fine but I seem to recall that there is a simpler way of doing this and I can't find it anywhere. Apropos, is it possible to send a windows message, like WM_SHOWWINDOW, between applications rather than within an application? By the way I have no problem getting the PID or the window handle if they are needed for the solution. Have Fun all.

      T Offline
      T Offline
      Tim Deveaux
      wrote on last edited by
      #2

      Re Q1: In 16 bit windows, which was an 'all one process' affair, you could check the hInstance param passed to the entry fn to do this. Nowadays, the de jure standard is to use shared memory - a named memory mapped file (see CreateFileMapping and MapViewOfFile) that the app creates on startup - if it already exists, exit, perhaps passing control to the first instance. There was an excellent intro to this stuff in Jeff Prosise's Wicked Code MSJ November 1998. A background thread approach sounds interesting though.

      1 Reply Last reply
      0
      • J Joe Moldovan

        Does anyone know of a simple way to ensure that an application has only a single instance running? When the app is clicked again the running instance should be restored and activated. I am doing all this now with an event and a background thread. It works fine but I seem to recall that there is a simpler way of doing this and I can't find it anywhere. Apropos, is it possible to send a windows message, like WM_SHOWWINDOW, between applications rather than within an application? By the way I have no problem getting the PID or the window handle if they are needed for the solution. Have Fun all.

        L Offline
        L Offline
        l a u r e n
        wrote on last edited by
        #3

        and remember we went through the mutex idea here a whiles ago --- "every year we invent better idiot proof systems and every year they invent better idiots"

        1 Reply Last reply
        0
        • J Joe Moldovan

          Does anyone know of a simple way to ensure that an application has only a single instance running? When the app is clicked again the running instance should be restored and activated. I am doing all this now with an event and a background thread. It works fine but I seem to recall that there is a simpler way of doing this and I can't find it anywhere. Apropos, is it possible to send a windows message, like WM_SHOWWINDOW, between applications rather than within an application? By the way I have no problem getting the PID or the window handle if they are needed for the solution. Have Fun all.

          S Offline
          S Offline
          Stan Shannon
          wrote on last edited by
          #4

          This is the way I've done it for about 100 years now, works like a charm : // Global declaration in CWinApp: LPCTSTR lpszUniqueClass = _T("MyUnigueClassName"); CMyWinApp::OnInitInstance() { // Check status of class name... if( DoIExist()) { return( FALSE ); } . . . // Register our unique class name that we wish to use WNDCLASS wndcls; . . . // Specify our own class name for using FindWindow later wndcls.lpszClassName = lpszUniqueClass; // Register new class and exit if it fails if(!AfxRegisterClass(&wndcls)) { TRACE("Class Registration Failed\n"); return FALSE; } . . . } BOOL CMyWinApp::DoIExist() { CWnd *pWndPrev, *pWndChild; if(( pWndPrev = CWnd::FindWindow(lpszUniqueClass, NULL ) )) { if( pWndPrev->IsIconic() ) { // If iconic, restore the main window pWndPrev->ShowWindow(SW_RESTORE); } // if alive, does it have any popups? if(( pWndChild = pWndPrev->GetLastActivePopup()) != NULL ) { pWndChild->SetForegroundWindow(); } return TRUE; } return FALSE; }

          V 1 Reply Last reply
          0
          • J Joe Moldovan

            Does anyone know of a simple way to ensure that an application has only a single instance running? When the app is clicked again the running instance should be restored and activated. I am doing all this now with an event and a background thread. It works fine but I seem to recall that there is a simpler way of doing this and I can't find it anywhere. Apropos, is it possible to send a windows message, like WM_SHOWWINDOW, between applications rather than within an application? By the way I have no problem getting the PID or the window handle if they are needed for the solution. Have Fun all.

            J Offline
            J Offline
            Joe Moldovan
            wrote on last edited by
            #5

            Great ideas but just as much work as my original. Pity that hInstance is not atomic across multi-cpu systems but that's asking a lot. Here is my solution for anyone who is interested. I don't think its very elegant but it works. At the beginning of xxxApp::InitInstance()look for an event. BOOL CTestApp::InitInstance() { // See if an instance of myself is already running if (( eDoIExist = OpenEvent( EVENT_ALL_ACCESS, NULL, "YesIExist" )) != NULL ) { // Yes. There is someone out there. Wake it up. SetEvent( eDoIExist ); // And get out return FALSE; } // No. I am the first so set up an event. eDoIExist = CreateEvent( NULL, TRUE, FALSE, "YesIExist" ); ..... Later in the init code when the main window (in my case a dialog) is ..... set up CTestDlg dlg; m_pMainWnd = &dlg; // Create a background thread to look for any other instance and send it // the main window ::CreateThread( NULL, 0, LookForMyself, m_pMainWnd , 0, NULL ); ..... At the end of the same source DWORD WINAPI LookForMyself( LPVOID lpParameter ) { // Forever do { WaitForSingleObject( eDoIExist, INFINITE ); // This is just a little flashy way of re-activating the running // instance ((CDialog *)lpParameter)->ShowWindow( SW_SHOWMINIMIZED ); ((CDialog *)lpParameter)->ShowWindow( SW_RESTORE ); // Reset and wait for more intruders ResetEvent( eDoIExist ); } while ( TRUE ); return 0; } Thank you all for your responses!

            L 1 Reply Last reply
            0
            • J Joe Moldovan

              Great ideas but just as much work as my original. Pity that hInstance is not atomic across multi-cpu systems but that's asking a lot. Here is my solution for anyone who is interested. I don't think its very elegant but it works. At the beginning of xxxApp::InitInstance()look for an event. BOOL CTestApp::InitInstance() { // See if an instance of myself is already running if (( eDoIExist = OpenEvent( EVENT_ALL_ACCESS, NULL, "YesIExist" )) != NULL ) { // Yes. There is someone out there. Wake it up. SetEvent( eDoIExist ); // And get out return FALSE; } // No. I am the first so set up an event. eDoIExist = CreateEvent( NULL, TRUE, FALSE, "YesIExist" ); ..... Later in the init code when the main window (in my case a dialog) is ..... set up CTestDlg dlg; m_pMainWnd = &dlg; // Create a background thread to look for any other instance and send it // the main window ::CreateThread( NULL, 0, LookForMyself, m_pMainWnd , 0, NULL ); ..... At the end of the same source DWORD WINAPI LookForMyself( LPVOID lpParameter ) { // Forever do { WaitForSingleObject( eDoIExist, INFINITE ); // This is just a little flashy way of re-activating the running // instance ((CDialog *)lpParameter)->ShowWindow( SW_SHOWMINIMIZED ); ((CDialog *)lpParameter)->ShowWindow( SW_RESTORE ); // Reset and wait for more intruders ResetEvent( eDoIExist ); } while ( TRUE ); return 0; } Thank you all for your responses!

              L Offline
              L Offline
              Lost User
              wrote on last edited by
              #6

              You could use a mutex to check if you are the first instance, and if not send a app specific message with BroadcastSystemMessage(). (never actually tried it, but i think it should work and be quite a simple solution)

              L 1 Reply Last reply
              0
              • L Lost User

                You could use a mutex to check if you are the first instance, and if not send a app specific message with BroadcastSystemMessage(). (never actually tried it, but i think it should work and be quite a simple solution)

                L Offline
                L Offline
                Lost User
                wrote on last edited by
                #7

                Maybe the mutex is not even needed, sending the app specific message with BroadcastSystemMessage() and the flag BSF_QUERY and checking the retval might do the trick.

                L 1 Reply Last reply
                0
                • L Lost User

                  Maybe the mutex is not even needed, sending the app specific message with BroadcastSystemMessage() and the flag BSF_QUERY and checking the retval might do the trick.

                  L Offline
                  L Offline
                  Lost User
                  wrote on last edited by
                  #8

                  Great ideas people! I am going to try all of these just to see what works and what don't.

                  1 Reply Last reply
                  0
                  • J Joe Moldovan

                    Does anyone know of a simple way to ensure that an application has only a single instance running? When the app is clicked again the running instance should be restored and activated. I am doing all this now with an event and a background thread. It works fine but I seem to recall that there is a simpler way of doing this and I can't find it anywhere. Apropos, is it possible to send a windows message, like WM_SHOWWINDOW, between applications rather than within an application? By the way I have no problem getting the PID or the window handle if they are needed for the solution. Have Fun all.

                    B Offline
                    B Offline
                    Bret Faller
                    wrote on last edited by
                    #9

                    If you have a custom mainframe class (RegisterWndClass()) you can just do a FindWindow(clasname, window caption) and then send a message to the HWND that gets returned. Bret Faller Odyssey Computing, Inc.

                    1 Reply Last reply
                    0
                    • S Stan Shannon

                      This is the way I've done it for about 100 years now, works like a charm : // Global declaration in CWinApp: LPCTSTR lpszUniqueClass = _T("MyUnigueClassName"); CMyWinApp::OnInitInstance() { // Check status of class name... if( DoIExist()) { return( FALSE ); } . . . // Register our unique class name that we wish to use WNDCLASS wndcls; . . . // Specify our own class name for using FindWindow later wndcls.lpszClassName = lpszUniqueClass; // Register new class and exit if it fails if(!AfxRegisterClass(&wndcls)) { TRACE("Class Registration Failed\n"); return FALSE; } . . . } BOOL CMyWinApp::DoIExist() { CWnd *pWndPrev, *pWndChild; if(( pWndPrev = CWnd::FindWindow(lpszUniqueClass, NULL ) )) { if( pWndPrev->IsIconic() ) { // If iconic, restore the main window pWndPrev->ShowWindow(SW_RESTORE); } // if alive, does it have any popups? if(( pWndChild = pWndPrev->GetLastActivePopup()) != NULL ) { pWndChild->SetForegroundWindow(); } return TRUE; } return FALSE; }

                      V Offline
                      V Offline
                      Vu Nguyen
                      wrote on last edited by
                      #10

                      Hi! I tried your example, but failed to get the result. the AfxRegisterClass() always returns false. DO you know why? I use appWizard to make my dialog base application Thank You very much Vu vucsuf

                      V 1 Reply Last reply
                      0
                      • V Vu Nguyen

                        Hi! I tried your example, but failed to get the result. the AfxRegisterClass() always returns false. DO you know why? I use appWizard to make my dialog base application Thank You very much Vu vucsuf

                        V Offline
                        V Offline
                        Vu Nguyen
                        wrote on last edited by
                        #11

                        This is where the answer is: http://support.microsoft.com/default.aspx?scid=kb;EN-US;q243953 I found this out after failing to ask for help on this forum. I guess there are more than 1 way to do it. It just happened to me that all the solutions provided by this forum does not work for me at all. Vu http://support.microsoft.com/default.aspx?scid=kb;EN-US;q243953 vucsuf

                        1 Reply Last reply
                        0
                        Reply
                        • Reply as topic
                        Log in to reply
                        • Oldest to Newest
                        • Newest to Oldest
                        • Most Votes


                        • Login

                        • Don't have an account? Register

                        • Login or register to search.
                        • First post
                          Last post
                        0
                        • Categories
                        • Recent
                        • Tags
                        • Popular
                        • World
                        • Users
                        • Groups