Solved

Previous Instance and Minimize to System Tray

Posted on 2002-07-17
6
306 Views
Last Modified: 2012-05-04
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?

0
Comment
Question by:mutrus
6 Comments
 
LVL 3

Expert Comment

by:cmgarnett
ID: 7159148
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
0
 
LVL 2

Accepted Solution

by:
priya_pbk earned 100 total points
ID: 7159161
If you wish to check if a new instance of the running application exists, just do this

Sub main()
If App.PrevInstance = True Then MsgBox "Application already running"
End
End Sub


>>, the first instance is only returned to the task bar not the desktop
..this is not clear
0
 
LVL 6

Expert Comment

by:pierrecampe
ID: 7159535
>>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
0
Free Tool: IP Lookup

Get more info about an IP address or domain name, such as organization, abuse contacts and geolocation.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

 

Author Comment

by:mutrus
ID: 7160795
>>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
0
 
LVL 6

Expert Comment

by:pierrecampe
ID: 7161014
>>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



0
 

Author Comment

by:mutrus
ID: 7744550
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

0

Featured Post

Free Tool: Site Down Detector

Helpful to verify reports of your own downtime, or to double check a downed website you are trying to access.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Have you ever wanted to restrict the users input in a textbox to numbers, and while doing that make sure that they can't 'cheat' by pasting in non-numeric text? Of course you can do that with code you write yourself but it's tedious and error-prone …
You can of course define an array to hold data that is of a particular type like an array of Strings to hold customer names or an array of Doubles to hold customer sales, but what do you do if you want to coordinate that data? This article describes…
Get people started with the process of using Access VBA to control Outlook using automation, Microsoft Access can control other applications. An example is the ability to programmatically talk to Microsoft Outlook. Using automation, an Access applic…
Get people started with the utilization of class modules. Class modules can be a powerful tool in Microsoft Access. They allow you to create self-contained objects that encapsulate functionality. They can easily hide the complexity of a process from…

839 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question