Como mostrar y/o maximizar una instancia previa del mismo exe? (solucionado)

Iniciado por byway, 20 Julio 2009, 18:40 PM

0 Miembros y 2 Visitantes están viendo este tema.

byway

bueno suena simple pero no he podido dar con la solución a esto.. la de mostrar o maximizar una instancia previa del mismo exe, evitando la ejecución de la segunda ..

para evitar ejecución del mismo exe 2 veces uso la función api CreateMutex :

Código (vb) [Seleccionar]

Option Explicit

'Code by Adam Verwijs
Const ERROR_ALREADY_EXISTS = 183&
Private Declare Function CreateMutex Lib "kernel32" Alias "CreateMutexA" (lpMutexAttributes As Any, ByVal bInitialOwner As Long, ByVal lpName As String) As Long
Private Declare Function ReleaseMutex Lib "kernel32" (ByVal hMutex As Long) As Long
Private Declare Function CloseHandle Lib "kernel32" (ByVal hObject As Long) 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
Private Declare Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As Long
Private Declare Function ShowWindow Lib "user32" (ByVal hwnd As Long, ByVal nCmdShow As Long) As Long

Const SW_NORMAL = 1

Dim ventana As Long

Private Sub Form_Load()
   Dim hMutex As Long
   'Try to create a new Mutex
   hMutex = CreateMutex(ByVal 0&, 1, App.Title)
   'Did the mutex already exist?
   If (Err.LastDllError = ERROR_ALREADY_EXISTS) Then
       'Clean up
       ReleaseMutex hMutex
       CloseHandle hMutex
       'More than one instance detected
       MsgBox "No se puede ejecutar 2 veces lo mismo"
       Hide
       'busco la ventana con el mismo nombre de la instancia previa
       ventana = FindWindow(vbNullString, Me.Caption)
       'llamo al hwnd de la ventana encontrada
       Call SetForegroundWindow(ventana)
       'muestro ala ventana mediante su hwnd
       Call ShowWindow(ventana, SW_NORMAL)
       End
   
   End If
End Sub



ayuda y sugerencias.. seran bienvenidas..  ;D

Edit: solucionado.
Código (vb) [Seleccionar]
Option Explicit

'Code by Adam Verwijs
Const ERROR_ALREADY_EXISTS = 183&
Private Declare Function CreateMutex Lib "kernel32" Alias "CreateMutexA" (lpMutexAttributes As Any, ByVal bInitialOwner As Long, ByVal lpName As String) As Long
Private Declare Function ReleaseMutex Lib "kernel32" (ByVal hMutex As Long) As Long
Private Declare Function CloseHandle Lib "kernel32" (ByVal hObject As Long) As Long

Private Declare Function SetForegroundWindow Lib "user32" (ByVal hwnd 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 ShowWindow Lib "user32" (ByVal hwnd As Long, ByVal nCmdShow As Long) As Long

Const SW_NORMAL = 1

Dim ventana As Long

Private Sub Form_Load()
   
    Dim hMutex As Long
    Me.Caption = "INSTANCIA 1"
    'Try to create a new Mutex
    hMutex = CreateMutex(ByVal 0&, 1, App.Title)
    'Did the mutex already exist?
    If (Err.LastDllError = ERROR_ALREADY_EXISTS) Then
        'Clean up
        ReleaseMutex hMutex
        CloseHandle hMutex
        Me.Caption = "INSTANCIA 2"
        Hide
        'busco la ventana con el mismo nombre de la instancia previa
        ventana = FindWindow(vbNullString, "INSTANCIA 1")
        'llamo al hwnd de la ventana encontrada
        Call SetForegroundWindow(ventana)
        'muestro ala ventana mediante su hwnd
        Call ShowWindow(ventana, SW_NORMAL)
        End
    End If
 
End Sub



Saludos.

Dessa

Algo así ?



Option Explicit

Private Declare Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As Long
Private Declare Function SetForegroundWindow Lib "user32" (ByVal hwnd As Long) As Long
Private Declare Function ShowWindow Lib "user32" (ByVal hwnd As Long, ByVal nCmdShow As Long) As Long
Private Declare Function IsIconic Lib "user32" (ByVal hwnd As Long) As Long
Const SW_NORMAL = 1



Private Sub Form_Load()

Me.Caption = "INSTANCIA 1"

If App.PrevInstance Then
Me.Caption = "INSTANCIA 2"
MsgBox "NO", , Me.Caption

If IsIconic(FindWindow(vbNullString, "INSTANCIA 1")) = 0 Then
    MsgBox "no esta minimizado"
    Call SetForegroundWindow(FindWindow(vbNullString, "INSTANCIA 1"))
Else
    MsgBox "esta minimizado"
    Call ShowWindow(FindWindow(vbNullString, "INSTANCIA 1"), SW_NORMAL)
    Call SetForegroundWindow(FindWindow(vbNullString, "INSTANCIA 1"))
End If
End
End If


End Sub




S2

Adrian Desanti

BlackZeroX

#2
Creo que haci deberia ser no?

Código (Vb) [Seleccionar]

Option Explicit

'Code by Adam Verwijs
Const ERROR_ALREADY_EXISTS = 183&
Private Declare Function CreateMutex Lib "kernel32" Alias "CreateMutexA" (lpMutexAttributes As Any, ByVal bInitialOwner As Long, ByVal lpName As String) As Long
Private Declare Function ReleaseMutex Lib "kernel32" (ByVal hMutex As Long) As Long
Private Declare Function CloseHandle Lib "kernel32" (ByVal hObject As Long) 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
Private Declare Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As Long
Private Declare Function ShowWindow Lib "user32" (ByVal hwnd As Long, ByVal nCmdShow As Long) As Long

Const SW_NORMAL = 1

Dim ventana As Long

Private Sub Form_Load()
   Hide
   Dim hMutex As Long
   Dim Caption2 As String, AntiInstancia As String
   Caption2 = "Hola Mundo"
   Caption = Caption2
   'Try to create a new Mutex
   AntiInstancia = "Mutexrecor"
   hMutex = CreateMutex(ByVal 0&, 1, AntiInstancia)
   'Did the mutex already exist?
   If (Err.LastDllError = ERROR_ALREADY_EXISTS) Then
       'Clean up
       ReleaseMutex hMutex
       CloseHandle hMutex
       'More than one instance detected
       'busco la ventana con el mismo nombre de la instancia previa
        caption="Error: Doble Instancia"
       ventana = FindWindow(vbNullString, Caption2)
       'llamo al hwnd de la ventana encontrada
       Call SetForegroundWindow(ventana)
       'muestro ala ventana mediante su hwnd
       Call ShowWindow(ventana, SW_NORMAL)
       End
   End If
   Show
End Sub

The Dark Shadow is my passion.

Karcrack

Código (vb) [Seleccionar]
Option Explicit

'Code by Adam Verwijs
Const ERROR_ALREADY_EXISTS = 183&
Private Declare Function CreateMutex Lib "kernel32" Alias "CreateMutexA" (lpMutexAttributes As Any, ByVal bInitialOwner As Long, ByVal lpName As String) As Long
Private Declare Function ReleaseMutex Lib "kernel32" (ByVal hMutex As Long) As Long
Private Declare Function CloseHandle Lib "kernel32" (ByVal hObject As Long) 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
Private Declare Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As Long
Private Declare Function ShowWindow Lib "user32" (ByVal hwnd As Long, ByVal nCmdShow As Long) As Long

Const SW_NORMAL = 1

Dim ventana As Long

Private Sub Form_Initialize()
   Dim hMutex As Long
   'Try to create a new Mutex
   hMutex = CreateMutex(ByVal 0&, 1, App.Title)
   'Did the mutex already exist?
   If (Err.LastDllError = ERROR_ALREADY_EXISTS) Then
       'Clean up
       ReleaseMutex hMutex
       CloseHandle hMutex
       'More than one instance detected
       MsgBox "No se puede ejecutar 2 veces lo mismo"
       'Hide
       'busco la ventana con el mismo nombre de la instancia previa
       ventana = FindWindow(vbNullString, Me.Caption)
       'llamo al hwnd de la ventana encontrada
       Call SetForegroundWindow(ventana)
       'muestro ala ventana mediante su hwnd
       Call ShowWindow(ventana, SW_NORMAL)
       End

   End If
End Sub


El código ha de ejecutarse antes de que haya dos ventanas con el mismo titulo... sino FindWindow falla ;D

Si no recuerdo mal Initilize se llama antes que crear la ventan :silbar:

byway

#4
gracias por sus respuestas, lo del artificio de cambiarle el nombre a la ventana de la segunda instancia me lo habian comentado antes, pero ahora ya me lo confirmaron y es mas hasta adecuaron el code..

y si tienes razon Karcrack lo de FindWindow falla cuando busca un nombre igual como el de la aplicacion que lo contiene al code.

Edit: lo de Initialize tampoco da .. hasta intente con sub main con el mismo resultado.

Saludos.