?
Solved

Performing an event in another running instance of a VB6 application

Posted on 2003-03-27
11
Medium Priority
?
182 Views
Last Modified: 2010-05-01
I've ripped some code off the net to bail out of my program if it detects another running instance. It works fine, and even activates the other window before ending itself.

Here's what I need it to do, though. I need it to launch an event in the other instance after it detects the other program is running. I've got a "cmdReload" button on the "frmPayments" form, and I need it to either click the button somehow (it has the Default property set to true, if that makes it easier), or run the "cmdReload_click" procedure.

My guess is that there is a simple statement that will do it, I just don't have any experience with that sort of stuff. I started researching "SendMessage" stuff in the Windows API, but I'm not sure if that's what I need.

Here's the existing code: (most of this is straight off the net)
     
Option Explicit
Private Declare Function ShowWindow Lib "user32" _
    (ByVal hwnd As Long, ByVal nCmdShow As Long) As Long

Private Declare Function FindWindow Lib "user32" _
   Alias "FindWindowA" _
   (ByVal lpClassName As String, ByVal lpWindowName _
   As String) As Long

Private Declare Function IsIconic Lib "user32" _
    (ByVal hwnd As Long) As Long

Private Declare Function SetForegroundWindow Lib "user32" _
    (ByVal hwnd As Long) As Long

Const SW_RESTORE = 9

'Conatants used for the return of the MultiInst function
Private Const OPEN_APPLICATION = 0
Private Const SINGLE_INSTANCE_OPEN = 1

Sub Main()
Dim MultiInstResult As Integer

'Call procedure to determine if an instance of
'the application is already loaded
MultiInstResult = MultiInst

'Handle the result from the MultiInst function
If MultiInstResult = OPEN_APPLICATION Then
     frmPayments.Show
     'No instance of the application is already open,
     'continue to load the login form
ElseIf MultiInstResult = SINGLE_INSTANCE_OPEN Then
   'An instance already exists cancel the
   'current application load
    End
End If
End Sub

Private Function MultiInst() As Integer
'This function determines if a single instance of the
'application is already running.

Dim hwndFound As Long   'The window handle
Dim strWindowName       'The Caption on the window

'Set the caption of the application form
strWindowName = "Insurance Payments"    ' <<< This is the only line I actually had to modify

'Get the handle of the application if it is open
hwndFound = FindWindow(vbNullString, strWindowName)

If hwndFound Then
     'Set the function return
     MultiInst = SINGLE_INSTANCE_OPEN
     'MsgBox "A instance of the application is already open." & _   '<<<OK, commented this out, too.
         vbCrLf & vbCrLf & _
         "Only one open instance allowed.", vbOKOnly + _
         vbExclamation, "App Name"

'>>> My guess is the extra code will go right here<<<
     'If application minimized, restore, show it on top
     If IsIconic(hwndFound) Then
          ShowWindow hwndFound, SW_RESTORE
          'Show the window infront of all other windows
          SetForegroundWindow hwndFound
     Else
          'Bring the application top most on the screen
          SetForegroundWindow hwndFound
    End If
'>>> or maybe here<<<

ElseIf hwndFound = 0 Then
    'Set the function return so it will continue loading
    MultiInst = OPEN_APPLICATION
End If
End Function

THANKS for your help!
0
Comment
Question by:MegaTrain
11 Comments
 
LVL 27

Expert Comment

by:Dabas
ID: 8228072
This is interesting stuff, and although I also am not a guru in API calls, may I suggest you just use a simple SendKeys command?
Once your other application is in the foreground, I assume it will also have the focus?

In that case probably SendKeys "{Enter}" will press the default button for you.

Give it a try!

Dabas
0
 

Author Comment

by:MegaTrain
ID: 8239575
Didn't seem to work, which is odd because this example in the VB help DOES work:

ReturnValue = Shell("calc.exe", 1)   ' Run Calculator.
AppActivate ReturnValue    ' Activate the Calculator.
For I = 1 To 100   ' Set up counting loop.
   SendKeys I & "{+}", True   ' Send keystrokes to Calculator
Next I   ' to add each value of I.
SendKeys "=", True   ' Get grand total.
SendKeys "%{F4}", True   ' Send ALT+F4 to close Calculator.

I even modified my code to user the "AppActivate" instead of the "SetForegroundWindow", and it didn't seem to make a difference. Other ideas?
0
 

Author Comment

by:MegaTrain
ID: 8239702
Even when I pare it down to the following, it still doesn't work:

Sub Main()
    If App.PrevInstance = True Then
        AppActivate "Insurance Payments"
        SendKeys "{Enter}"
        End
    Else
        frmPayments.Show
    End If
End Sub

I tried to make it as simple and similar to the Calculator example as possible. Any ideas why neither of these is working?
0
Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
LVL 27

Expert Comment

by:Dabas
ID: 8241103
Maybe if you do not just make the button the default but also name it using the ampersand so that pressing a key, or Ctrl-Key will "click" it?
Lets say that instead of OK, the caption is &OK, making the O highlighted. Then you can send a "%O"

Good luck!

Dabas
0
 

Author Comment

by:MegaTrain
ID: 8248848
I had already tried that as well. No luck there, either. I may just make it a point of training that they have to click on the reload button.

Any other ideas?
0
 
LVL 27

Expert Comment

by:Dabas
ID: 8249426
Question is, what makes your application different from the Help sample. As you say, why does one work and the other one does not?

Dabas
0
 

Author Comment

by:MegaTrain
ID: 8286941
Well, I made a new solo VB project with a form and the following code, and it doesn't work either:

Sub Main()
   If App.PrevInstance = True Then
       AppActivate "Insurance Payments"
       SendKeys "{Enter}", True
   Else
       frmPayments.Show
   End If
End Sub

I even tried putting all sorts of things between the AppActivate and the Sendkeys, like Timer delays or DoEvents.

So it's not just my large App. The only difference between this little program and the Calculator example above is the Shell statement, but I don't think thats the issue, because the "AppActivate" statement does work correctly... I think there is something weird going on with multiple instances that isn't illustrated by the Calculator example.

I'm still thinking that this would be possible with some "SendMessage" stuff, but I really don't know anything about that area.
0
 
LVL 27

Expert Comment

by:Dabas
ID: 8287681
MegaTrain

There is a major difference:

AppActivate ReturnValue    ' Activate the Calculator.

ReturnValue is numeric

    AppActivate "Insurance Payments"
Not numeric.

The help for AppActivate implicates that you are right.
Question is: do you actually see the "Insurance Payments" window come to the front and get the focus?

Have you tried to play with the wait parameter, such as

AppActivate "Insurance Payments", True

?

Good Luck!

Dabas
0
 

Expert Comment

by:CleanupPing
ID: 8531484
Hi MegaTrain,
This old question (QID 20565522) needs to be finalized -- accept an answer, split points, or get a refund.  Please see http://www.cityofangels.com/Experts/Closing.htm for information and options.
0
 

Accepted Solution

by:
MegaTrain earned 0 total points
ID: 8533180
I ended up leaving the application as is--the user has to click "reload". Thanks for your dialog. I'm going to ask that this be closed and the points refunded.
0
 
LVL 1

Expert Comment

by:Computer101
ID: 8571451
Points refunded and placed in PAQ

Computer101
E-E Admin
0

Featured Post

Concerto's Cloud Advisory Services

Want to avoid the missteps to gaining all the benefits of the cloud? Learn more about the different assessment options from our Cloud Advisory team.

Question has a verified solution.

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

When trying to find the cause of a problem in VBA or VB6 it's often valuable to know what procedures were executed prior to the error. You can use the Call Stack for that but it is often inadequate because it may show procedures you aren't intereste…
Since upgrading to Office 2013 or higher installing the Smart Indenter addin will fail. This article will explain how to install it so it will work regardless of the Office version installed.
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…
Suggested Courses
Course of the Month8 days, 23 hours left to enroll

621 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