Announcement

Collapse
No announcement yet.

Sending a message from one app to the same app already running

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

  • Sending a message from one app to the same app already running

    I usually use a Mutex to keep my app from running twice and I
    display a message to the user that it is running.

    But rather than do that, if my app is running in the system tray and I try to re-launch my app,
    how can I send a message to the running app to come up and show_normal ?

    Tx

    Code:
    Say I am here:
    If IsTrue App_PrevInstance(szClassName) Then
        MessageBox ByVal 0, "Another instance of " & g_szMine & " is already running!", ByVal StrPtr(g_szMine), ByVal %MB_ICONSTOP
        Exit Function
    Else
        hMutex = CreateMutex(ByVal %Null, 0, szClassName)
    End If
    
    
    I want to do something like this:
    If IsTrue App_PrevInstance(szClassName) Then
        lResult = MaximizeAlreadyRunningApp()
        Exit Function
    Else
        hMutex = CreateMutex(ByVal %Null, 0, szClassName)
    End If
    
    Function MaximizeAlreadyRunningApp() As Long
    ?????????
    End Function
    ------------------
    Scott Turchin
    MCSE, MCP+I
    Computer Creations Software http://www.tngbbs.com/ccs



    [This message has been edited by Scott Turchin (edited January 08, 2006).]
    Scott Turchin
    MCSE, MCP+I
    http://www.tngbbs.com
    ----------------------
    True Karate-do is this: that in daily life, one's mind and body be trained and developed in a spirit of humility; and that in critical times, one be devoted utterly to the cause of justice. -Gichin Funakoshi

  • #2
    Code:
      hwnd = FindWindow(szClassName, ByVal %Null)
      If (IsWindow(hwnd)) Then
        SetForegroundWindow(hwnd)
        If (IsIconic(hwnd)) Then ShowWindow(hwnd,%SW_RESTORE)
        Function = False
        Exit Function
      End If
    Regards,
    RValois.


    ------------------
    http://www.rvalois.com.br/downloads/free/
    http://www.rvalois.com.br/downloads/free/

    Comment


    • #3
      related: share data among multiple instances of a program demo:
      win32: memory mapped files/control user count april 26, 2001

      (save the hwnd as part of the shared data)

      Michael Mattias
      Tal Systems (retired)
      Port Washington WI USA
      [email protected]
      http://www.talsystems.com

      Comment


      • #4
        Well the function above did not work
        Bummer.....

        ------------------
        Scott Turchin
        MCSE, MCP+I
        Computer Creations Software
        http://www.tngbbs.com/ccs
        Scott Turchin
        MCSE, MCP+I
        http://www.tngbbs.com
        ----------------------
        True Karate-do is this: that in daily life, one's mind and body be trained and developed in a spirit of humility; and that in critical times, one be devoted utterly to the cause of justice. -Gichin Funakoshi

        Comment


        • #5
          Scott,
          This is may work for you.. (based on code posted by Semen)

          Code:
          'Mutex check in PBMain()
          Dim WinName As Asciiz * %MAX_PATH
          Dim hMutex As Dword, hForWnd As Dword, hWin As Dword
           
          WinName = $AppTitle
          hMutex = CreateMutex(ByVal %NULL, 0, WinName)
           
            If hMutex = %NULL Then Exit Function
            If GetLastError = %ERROR_ALREADY_EXISTS Then    'already running!
              hWin = FindWindow (ByVal %Null, WinName)      'find handle of target window
              hForWnd = GetForegroundWindow                 'handle of current foreground window
                'Set own window to the top in Z-order with %HWND_TOP
                SetWindowpos hWin, %HWND_TOP, 0, 0, 0, 0, %SWP_NOMOVE Or %SWP_NOSIZE Or %SWP_SHOWWINDOW
                'Disable current foreground window.
                EnableWindow hForWnd, 0 
                'Redirect focus to next window in Z-order / move to foreground and activate
                SetForegroundWindow hWin                    
                'Re-enable previous foreground window
                EnableWindow hForWnd, 1
              Exit Function
            End If
          Rgds Dave

          ------------------


          [This message has been edited by Dave Biggs (edited January 08, 2006).]
          Rgds, Dave

          Comment


          • #6
            Here is another one...
            Pierre

            Code:
            #COMPILE EXE '#Win 8.01#     
            #DIM ALL
            #INCLUDE "win32api.inc" '2005-01-27
             
            %WM_TRAYICON    = 501 + %WM_USER 
            '______________________________________________________________________________
             
            CALLBACK FUNCTION MainCB () AS LONG
             STATIC hIcon    AS DWORD
             STATIC TrayData AS NOTIFYICONDATA
             
             SELECT CASE CBMSG
             
               CASE %WM_INITDIALOG  
                 hIcon = LoadIcon(BYVAL %NULL, ByVal %IDI_INFORMATION) 'Get an icon from Windows
                 SetClassLong CBHNDL, %GCL_HICON, hIcon                'Set program with this icon
             
                 TrayData.cbSize            = SIZEOF (TrayData)
                 TrayData.hWnd              = CBHNDL
                 TrayData.uID               = GetmoduleHandle(BYVAL %NULL)
                 TrayData.uFlags            = %NIF_ICON OR %NIF_MESSAGE OR %NIF_TIP
                 TrayData.uCallBackMessage  = %WM_TRAYICON
                 TrayData.hIcon             = hIcon
                 TrayData.szTip             = "Click me !"
             
               CASE %WM_TRAYICON 'Message received from tray icon
                 SELECT CASE LOWRD(CBLPARAM)
                   CASE %WM_LBUTTONUP, %WM_RBUTTONUP        'Mouse clicked on tray icon
                     Shell_NotifyIcon %NIM_DELETE, TrayData 'Remove tray icon
                     ShowWindow CBHNDL, %SW_RESTORE         'Restore dialog
                     SetForegroundWindow CBHNDL             'Bring dialog on top
                 END SELECT
             
               CASE %WM_SIZE
                 IF CBWPARAM = %SIZE_MINIMIZED THEN         'Dialog is minimized
                   Shell_NotifyIcon %NIM_ADD, TrayData      'Show tray icon
                   ShowWindow CBHNDL, %SW_HIDE              'Hide dialog
                 END IF
             
               CASE %WM_DESTROY
                 Shell_NotifyIcon %NIM_DELETE, TrayData     'Remove tray icon when application terminate
             
             END SELECT
             
            END FUNCTION
            '______________________________________________________________________________
             
            FUNCTION PBMAIN() AS LONG
             LOCAL hDlg   AS DWORD
             LOCAL hMutex AS DWORD 
             LOCAL hTry   AS DWORD  
             LOCAL zMyApp AS ASCIIZ * %MAX_PATH 
             
             %MyUniqueNumber = 197346285
             zMyApp          = "TrayIcon and Mutex"
             hMutex = CreateMutex(BYVAL %NULL, 0, zMyApp)
             IF GetLastError = %ERROR_ALREADY_EXISTS THEN                     'Application already running
             
               '1) Method using  window name                                  
               'hTry = FindWindow(BYVAL %NULL, zMyApp)                        'Find handle by window caption
               'ShowWindow hTry, %SW_RESTORE                                  'Restore it
               'ShowWindow hTry, %SW_Show                                     'Show it
               'SetForegroundWindow hTry                                      'Put it to foreground
               'BEEP                                                          'Proove that it works by emmiting a sound
               'EXIT FUNCTION                                                 'End this program instance
             
               '2) Method using  SetWindowLong with GWL_USERDATA -
               hTry = GetTopWindow(%HWND_DESKTOP)                             'Get first windos handle
               DO WHILE hTry                                                  'Scan all windows handle
                 IF GetWindowLong(hTry, %GWL_USERDATA) = %MyUniqueNumber THEN 'Found the other instance
                   ShowWindow hTry, %SW_RESTORE                               'Restore it
                   ShowWindow hTry, %SW_Show                                  'Show it
                   SetForegroundWindow hTry                                   'Put it to foreground
                   BEEP                                                       'Proove that it works by emmiting a sound
                   EXIT FUNCTION                                              'End this program instance
                 END IF                                                       
                 hTry = GetWindow(hTry, %GW_HWNDNEXT)                         'Try next windows 
               LOOP  
               EXIT FUNCTION
             
             END IF
             
             DIALOG NEW %HWND_DESKTOP, zMyApp, , , 180, 50, %WS_SYSMENU OR %WS_CAPTION OR %WS_MINIMIZEBOX, 0 TO hDlg
             
             SetWindowLong hDlg, %GWL_USERDATA, %MyUniqueNumber               'Set window user data with %MyUniqueNumber 
             
             CONTROL ADD LABEL, hDlg, -1, "Try to start program again...", 5, 5, 100, 15 
             
             DIALOG SHOW MODAL hDlg, CALL MainCB
             
             ReleaseMutex hMutex
             
            END FUNCTION
            '______________________________________________________________________________


            [This message has been edited by Pierre Bellisle (edited January 08, 2006).]

            Comment


            • #7
              PMFJI unasked

              regarding Roberto's code you need some extra code to get it working.
              MS changed the behavior for focus interchanging from application level.

              See MSDN -> SetForegroundWindow() description

              you need an AttachThreadInput() first
              This get you the needed permission for above sample code
              you need an second AttachThreadInput() at the end too -
              for detaching.

              Regarding your origin question.

              You should register an user windows message at top of your app
              UWM_THIS_IS_ME = RegisterWindowMessage("Here_I_am")


              later API
              SendMessageTimeout(hOther, UWM_THIS_IS_ME, 1, NULL, %SMTO_BLOCK OR %SMTO_ABORTIFHUNG, 200, result)

              only your app know what to do when receiving your UWM_MESSAGE

              eg. an example - unfortunately I have no PB code

              find other instance with API
              EnumWindows(SearchOtherInstance, &hOther);
              ...
              ...


              BOOL CALLBACK SearchOtherInstance(HWND hWnd, LPARAM lParam)
              {
              DWORD result = 0;
              LRESULT ok = SendMessageTimeout(hWnd, UWM_THIS_IS_ME, 0,
              (LPARAM) NULL, SMTO_BLOCK | SMTO_ABORTIFHUNG,
              200, &result);

              if (ok == 0)
              return TRUE; // time out error - continue

              if (result == UWM_THIS_IS_ME) // other instance reflect same message back
              { // found it - for some other reasons you might store hWnd in caller
              HWND* target = (HWND*) lParam;
              *target = hWnd; // store hWnd to lParam == return value for caller (hOther)
              return FALSE; // stop enum
              }
              return TRUE; // continue
              }


              I hope this is of some help and sorry - English is not my native

              Ahoj
              -Uwe

              ------------------


              [This message has been edited by Uwe Heyer (edited January 08, 2006).]

              Comment


              • #8
                Thanks guys, I'll play with these and see what I can come up with.....

                Haven't had much time lately so it may be a few days....


                Scott

                ------------------
                Scott Turchin
                MCSE, MCP+I
                Computer Creations Software
                http://www.tngbbs.com/ccs
                Scott Turchin
                MCSE, MCP+I
                http://www.tngbbs.com
                ----------------------
                True Karate-do is this: that in daily life, one's mind and body be trained and developed in a spirit of humility; and that in critical times, one be devoted utterly to the cause of justice. -Gichin Funakoshi

                Comment


                • #9
                  Turns out the RegisterWindow appears to be the way to do this.
                  I read up on it at MSDN and it's the current method for application communication so it appears.

                  It even has a block capability to block other apps. Kinda like email!

                  Now the question is, how do I process a message from another application?


                  Thanks Uwe


                  Scott

                  ------------------
                  Scott Turchin
                  MCSE, MCP+I
                  Computer Creations Software
                  http://www.tngbbs.com/ccs
                  Scott Turchin
                  MCSE, MCP+I
                  http://www.tngbbs.com
                  ----------------------
                  True Karate-do is this: that in daily life, one's mind and body be trained and developed in a spirit of humility; and that in critical times, one be devoted utterly to the cause of justice. -Gichin Funakoshi

                  Comment


                  • #10
                    >Now the question is, how do I process a message from another application?

                    Messages are 'source application agnostic'. Either you get the message, or you don't..when you get the message, you process it...

                    Code:
                    FUNCTION WndProc (...
                    
                      STATIC myMessage AS LONG
                    
                      SELECT CASE uMSG
                         CASE %WM_CREATE
                           myMessage = RegisterWindowMessage ("same string used by the other application")
                           ...
                         CASE MyMessage
                            do whatever
                    MCM


                    [This message has been edited by Michael Mattias (edited January 09, 2006).]
                    Michael Mattias
                    Tal Systems (retired)
                    Port Washington WI USA
                    [email protected]
                    http://www.talsystems.com

                    Comment

                    Working...
                    X