Link to home
Start Free TrialLog in
Avatar of astrohelp
astrohelp

asked on

File association, open only one instance of file

Hey Experts
   I am working on an app that is run via file associations. I need to only have one instance running, but change the loaded file when it is double clicked. I have the code for the single instance, but it does not change the loaded file. I was wondering how this is accomplished.

Here is the code I have:

FORM1---------------------------------------------------------------------------------------------------------------------------------------
Private Sub Form_Load()
'test code
   If App.PrevInstance Then
      ActivatePrevInstance
   End If
'end test code
On Error GoTo Form_Err
 
  Dim strFilename As String
  Dim iFileNumber As Integer
 
  strFilename = Replace$(Command$, Chr$(34), vbNullString)
  If strFilename <> vbNullString Then
    If Dir$(strFilename) <> vbNullString Then
      iFileNumber = FreeFile()
      Open strFilename For Input As #iFileNumber
      RichText1.Text = Input$(LOF(iFileNumber), #iFileNumber)
      Close #iFileNumber
    End If
  End If
Form_Err:
  MsgBox "Error " & Err.Number & Err.Description & vbNewLine & strFilename
End Sub
------------------------------------------------------------------------------------------------------------------

MODULE1---------------------------------------------------------------------------------------------------------

Option Explicit

Public Const GW_HWNDPREV = 3
Declare Function OpenIcon Lib "user32" (ByVal hwnd As Long) As Long
Declare Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As Long
Declare Function GetWindow Lib "user32" (ByVal hwnd As Long, ByVal wCmd As Long) As Long
Declare Function SetForegroundWindow Lib "user32" (ByVal hwnd As Long) As Long

Sub ActivatePrevInstance()

   Dim OldTitle As String
   Dim PrevHndl As Long
   Dim result As Long

   'Save the title of the application.
   OldTitle = 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 VB6 class name
        PrevHndl = FindWindow("ThunderRT6Main", OldTitle)

   'Check if found
   If PrevHndl = 0 Then
      'No previous instance found.
      Exit Sub
   End If

   'Get handle to previous window.
   PrevHndl = GetWindow(PrevHndl, GW_HWNDPREV)

   'Restore the program.
   result = OpenIcon(PrevHndl)

   'Activate the application.
   result = SetForegroundWindow(PrevHndl)

   'End the application.
   End

End Sub
---------------------------------------------------------------------------------------------------------------------------


thanks
-Bob
Avatar of Erick37
Erick37
Flag of United States of America image

This article demonstrates how to register associations and an easy-to-use module which can pass any parameters to an existing instance of your application.

http://www.vbaccelerator.com/home/VB/Code/Libraries/Shell_Projects/Registering_File_Associations/article.asp
Avatar of codeconqueror
codeconqueror

The problem is that your killing the instance that got the new file name without passing the file name over to the other instance.

Instead of activating the other instance, do this:

Add the following to your declarations:
Const WM_QUIT = &H12
Declare Function SendMessage Lib "user32" Alias "SendMessageA" (ByVal hwnd As Long, ByVal wMsg As Long, ByVal wParam As Long, lParam As Any) As Long

Then call it using:

SendMessage PrevHndl, WM_QUIT, 0&, 0&

Here is the updated code:

<CODE SNIPPET>
Private Sub Form_Load()
'test code
   If App.PrevInstance Then
      KillPrevInstance
   End If
'end test code
On Error GoTo Form_Err
 
  Dim strFilename As String
  Dim iFileNumber As Integer
 
  strFilename = Replace$(Command$, Chr$(34), vbNullString)
  If strFilename <> vbNullString Then
    If Dir$(strFilename) <> vbNullString Then
      iFileNumber = FreeFile()
      Open strFilename For Input As #iFileNumber
      RichText1.Text = Input$(LOF(iFileNumber), #iFileNumber)
      Close #iFileNumber
    End If
    Me.Show
  Else
     Unload Me
  End If
  Exit Sub
Form_Err:
  MsgBox "Error " & Err.Number & Err.Description & vbNewLine & strFilename
End Sub
</CODE SNIPPET>

Here's the module code:

<CODE SNIPPET>
Option Explicit

Public Const GW_HWNDPREV = 3
Const WM_QUIT = &H12
Declare Function SendMessage Lib "user32" Alias "SendMessageA" (ByVal hwnd As Long, ByVal wMsg As Long, ByVal wParam As Long, lParam As Any) As Long
Declare Function OpenIcon Lib "user32" (ByVal hwnd As Long) As Long
Declare Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As Long
Declare Function GetWindow Lib "user32" (ByVal hwnd As Long, ByVal wCmd As Long) As Long
Declare Function SetForegroundWindow Lib "user32" (ByVal hwnd As Long) As Long

Sub ActivatePrevInstance()

   Dim OldTitle As String
   Dim PrevHndl As Long
   Dim result As Long

   'Save the title of the application.
   OldTitle = 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 VB6 class name
        PrevHndl = FindWindow("ThunderRT6Main", OldTitle)

   'Check if found
   If PrevHndl = 0 Then
      'No previous instance found.
      Exit Sub
   End If

   'Get handle to previous window.
   PrevHndl = GetWindow(PrevHndl, GW_HWNDPREV)
   SendMessage PrevHndl, WM_QUIT, 0&, 0& '*** Tell the other instance to shut down
    App.Title = OldTitle
End Sub
</CODE SNIPPET>
Woops, forgot to change the name of the sub to:

Sub KillPrevInstance
Here is the complete corrected code:

<CODE SNIPPET>
Private Sub Form_Load()
   If App.PrevInstance Then
       KillPrevInstance
   End If
   
   On Error GoTo Form_Err
 
  Dim strFilename As String
  Dim iFileNumber As Integer
 
  strFilename = Replace$(Command$, Chr$(34), vbNullString)
  If Lenb(strFilename) > 0 Then
      If Lenb(Dir$(strFilename)) > 0 Then
           iFileNumber = FreeFile
           Open strFilename For Input As #iFileNumber
           RichText1.Text = Input$(LOF(iFileNumber), #iFileNumber)
           Close #iFileNumber
       End If
       Me.Show
  Else
       Unload Me
  End If
  Exit Sub

Form_Err:
  MsgBox "Error " & Err.Number & ": " & Err.Description & vbNewLine & "File Requested: " & strFilename
End Sub
</CODE SNIPPET>

Here's the module code:

<CODE SNIPPET>
Option Explicit

Public Const GW_HWNDPREV = 3
Const WM_QUIT = &H12
Declare Function SendMessage Lib "user32" Alias "SendMessageA" (ByVal hwnd As Long, ByVal wMsg As Long, ByVal wParam As Long, lParam As Any) As Long
Declare Function OpenIcon Lib "user32" (ByVal hwnd As Long) As Long
Declare Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As Long
Declare Function GetWindow Lib "user32" (ByVal hwnd As Long, ByVal wCmd As Long) As Long
Declare Function SetForegroundWindow Lib "user32" (ByVal hwnd As Long) As Long

Public Function KillPrevInstance()

   Dim OldTitle As String
   Dim PrevHndl As Long
   Dim result As Long

   'Save the title of the application.
   OldTitle = 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 VB6 class name
        PrevHndl = FindWindow("ThunderRT6Main", OldTitle)

   'Check if found
   If PrevHndl = 0 Then
      'No previous instance found.
      Exit Sub
   End If

   'Get handle to previous window.
   PrevHndl = GetWindow(PrevHndl, GW_HWNDPREV)
   SendMessage PrevHndl, WM_QUIT, 0&, 0& '*** Tell the other instance to shut down
   App.Title = OldTitle
End Function
</CODE SNIPPET>
Avatar of astrohelp

ASKER

Hey CC, thanks for the code, but it is not closing the previous instance...
any thoughts?
Here is updated module code, should work:

<CODE SNIPPET>
Option Explicit

Public Const GW_HWNDPREV = 3
Const WM_QUIT = &H12
Declare Function SendMessage Lib "user32" Alias "SendMessageA" (ByVal hwnd As Long, ByVal wMsg As Long, ByVal wParam As Long, lParam As Any) As Long
Declare Function OpenIcon Lib "user32" (ByVal hwnd As Long) As Long
Declare Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As Long
Declare Function GetWindow Lib "user32" (ByVal hwnd As Long, ByVal wCmd As Long) As Long
Declare Function SetForegroundWindow Lib "user32" (ByVal hwnd As Long) As Long

Public Function KillPrevInstance()

   Dim OldTitle As String
   Dim PrevHndl As Long
   Dim result As Long

   'Save the title of the application.
   OldTitle = App.Title

   'Rename the title of this application so FindWindow
   'will not find this application instance.
   App.Title = "Wanted Instance"

        'Attempt to get window handle using VB6 class name
        PrevHndl = FindWindow("ThunderRT6Main", OldTitle) '**** You may want to try passing the caption of the other instance instead if this doesn't find it

   If PrevHndl <> 0 Then
       SendMessage PrevHndl, WM_QUIT, 0&, 0& '*** Tell the other instance to shut down
   End If

   App.Title = OldTitle
End Function
</CODE SNIPPET>
Still need help on this Astrohelp?
Yes please Erick37, none of the previous suggestions have worked. If you have a solution, please let me know.

thanks
ASKER CERTIFIED SOLUTION
Avatar of Erick37
Erick37
Flag of United States of America image

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
nothing but net