Link to home
Start Free TrialLog in
Avatar of mutrus
mutrus

asked on

Previous Instance and Minimize to System Tray

I have included in my app a routine that minimizes the program to the Tray.

I have just added another routine to check for a Previous Instance.

If an attempt is made to run a second copy of the program when it is minimized to the System Tray the Previous Instance routine prevents it from running, however, the first instance is only returned to the task bar not the desktop

Is there an API or some code that I can include to get the program on the desktop?

Avatar of cmgarnett
cmgarnett
Flag of United Kingdom of Great Britain and Northern Ireland image

This might help to give you an idea. I can't remember where I found the code originally.


Option Explicit

Public Const SW_SHOW As Long = 5&
Public Const SW_RESTORE As Long = 9&

Public Const GW_CHILD As Long = 5&
Public Const GW_HWNDNEXT As Long = 2&

Public Declare Function AttachThreadInput Lib "user32" (ByVal idAttach&, ByVal idAttachTo&, ByVal fAttach&) As Long
Public Declare Function BringWindowToTop Lib "user32" (ByVal Hwnd&) As Long
Public Declare Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal lpClassName$, ByVal lpWindowName$) As Long
Public Declare Function GetDesktopWindow Lib "user32" () As Long
Public Declare Function GetForegroundWindow Lib "user32" () As Long
Public Declare Function GetWindow Lib "user32" (ByVal Hwnd&, ByVal wCmd&) As Long
Public Declare Function GetWindowText Lib "user32" Alias "GetWindowTextA" (ByVal Hwnd&, ByVal lpString$, ByVal cch&) As Long
Public Declare Function GetWindowThreadProcessId Lib "user32" (ByVal Hwnd&, lpdwProcessId&) As Long
Public Declare Function IsIconic Lib "user32" (ByVal Hwnd&) As Long
Public Declare Function SetForegroundWindow Lib "user32" (ByVal Hwnd&) As Long
Public Declare Function ShowWindow Lib "user32" (ByVal Hwnd&, ByVal nCmdShow&) As Long

Sub pActivateApplication(ByVal strApplication As String, _
   Optional ByVal blnWholeName As Boolean)

   On Error GoTo ErrpActivateApplication
'====================================================================
'Procedure to activate a previous existence of an application.
'Will only work with VB6 applications
'Input:  strApplication Title of application to activate
'        blnWholeName   True if strApplication is the whole title
'                             of application to activate
'                       False if strApplication is the start of
'                             title of application to activate
'====================================================================
   Dim hAppWIndow&
   Dim strTemp As String
   
   If Not blnWholeName Then
      hAppWIndow = GetWindow(GetDesktopWindow(), GW_CHILD)
      Do
         strTemp = String$(180, False)
         Call GetWindowText(hAppWIndow, strTemp, 179)
         If InStr(strTemp, strApplication) Then
            pActivateInstance hAppWIndow
            Exit Do
         End If
         hAppWIndow = GetWindow(hAppWIndow, GW_HWNDNEXT)
      Loop Until hAppWIndow = 0
   Else
      hAppWIndow = FindWindow("ThunderRT6FormDC", strApplication)
      pActivateInstance hAppWIndow
   End If
   
   Exit Sub

ErrpActivateApplication:

   Select Case Err.Number
   Case Else
      MsgBox Err.Description & "(" & Err.Number & ")", , "Sub pActivateApplication"
   End Select

End Sub

Private Sub pActivateInstance(ByVal hAppWIndow&)

   On Error GoTo ErrpActivateInstance
'====================================================================
'Procedure used by pActivateApplication to activate an existing
'instanace of an application.
'Input:  hAppWindow& Handle of application to be activated
'====================================================================
   Dim fShowWindowFlag&, hWndForeground&
   Dim nCurThreadID&, nNextThreadID&
   
   If IsIconic(hAppWIndow) Then
      fShowWindowFlag = SW_RESTORE
   Else
      fShowWindowFlag = SW_SHOW
   End If
   
   Call ShowWindow(hAppWIndow, fShowWindowFlag)
   
   hWndForeground = GetForegroundWindow()
   
   If hAppWIndow <> hWndForeground Then
      nCurThreadID = GetWindowThreadProcessId(hWndForeground, ByVal 0&)
      nNextThreadID = GetWindowThreadProcessId(hAppWIndow, ByVal 0&)
     
      If nCurThreadID <> nNextThreadID Then
         Call AttachThreadInput(nCurThreadID, nNextThreadID, True)
         Call BringWindowToTop(hAppWIndow)
         Call SetForegroundWindow(hAppWIndow)
         Call AttachThreadInput(nCurThreadID, nNextThreadID, False)
      Else
         Call BringWindowToTop(hAppWIndow)
         Call SetForegroundWindow(hAppWIndow)
      End If
   End If

   Exit Sub

ErrpActivateInstance:

   Select Case Err.Number
   Case Else
      MsgBox Err.Description & "(" & Err.Number & ")", , "Sub pActivateInstance"
   End Select

End Sub
ASKER CERTIFIED SOLUTION
Avatar of priya_pbk
priya_pbk

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of pierrecampe
pierrecampe

>>the first instance is only returned to the task bar not the desktop
if you do as priya_pbk said, the first instance will not be influenced in any way
Avatar of mutrus

ASKER

>>the first instance is only returned to the task bar not the desktop

The PreviousInstance routine I use restores the 1st instance to the desktop if it is running minimized on the taskbar.

However if the program is minimized to the SystemTray then PreviousInstance restores to the task bar not the desktop which is what I want
>>The PreviousInstance routine I use restores the 1st instance to the desktop if it is running minimized on the taskbar.
how do you do that ?, is showintaskbar not design-time only

>>However if the program is minimized to the SystemTray then PreviousInstance restores to the task bar not the desktop which is what I want
how do you minimize to the systemtray ?

i find all this very confusing
so could you post your PreviousInstance routine
and from where it is used



Avatar of mutrus

ASKER

sorry folks about delay - got side tracked by another project and then forgot about this one.

OK - if the first application was minimized it was sent to the system tray (minimize might be a bad choice of words) - I was using a SystemTray class (found on PSC) to do this.

then if a second application was attempted to be started it was stopped by the app.previous instance routine however the first instance instead of opening up on the desktop moved from being in the system tray to being minimized on the task bar.

I found the following code which fixes the problem

Private Sub ActivatePrevInstance()
   
    Dim strOldTitle As String
    Dim lngPrevhndl As Long
    Dim lngResult   As Long
   
    ' save the title of the application
    strOldTitle = App.Title
   
    'rename the title of this application so FindWindow
    'will not find this application instance.
    App.Title = "unwanted instance"
   
    'attempt to get window handle using VB4 class name
    lngPrevhndl = FindWindow("ThunderRTMain", strOldTitle)
   
    'check for no success
    If lngPrevhndl = 0 Then
        'attempt to get window handle using VB5 class name
        lngPrevhndl = FindWindow("ThunderRT5Main", strOldTitle)
    End If
   
    If lngPrevhndl = 0 Then
        'attempt to get window using VB6 class name
        lngPrevhndl = FindWindow("ThunderRT6Main", strOldTitle)
    End If
   
    If lngPrevhndl = 0 Then
        'no previous instance found
        Exit Sub
    End If
   
    'get handle to previous window
    lngPrevhndl = GetWindow(lngPrevhndl, GW_HWNDPREV)
   
    'restore the program
    lngResult = OpenIcon(lngPrevhndl)
   
    'end the application
    End
       
End Sub

Even though none of the comments really answered the question it is closed by virtue of the problem being fixed by this code.

pierrecampe - I posted you some points too as you took time to comment