StrataFrame Forum

How to Restore application from minimized state

http://forum.strataframe.net/Topic7408.aspx

By Tim Dol - 3/12/2007

If I launch an exe from my menu system and minimizes it, how can I restore the application or bring focus back to the application if they happen to click on the menu option again?
By Trent L. Taylor - 3/12/2007

If the application that your menu launched is not a .NET form then you have to use WinAPI to restore the application.  You will need to retrieve the window handle of the applcation.  You can do this a number of different ways, such as the GetWindow method.  You can use many of the APIs in conjunction with one another in order to retrieve the correct window handle.

In our medical application, we store off the window handle when we call the external program:

Private _ProgramHandle As IntPtr

Private Sub LaunchExternalEXE()
    '-- Establish Locals
    Dim loStart As New System.Diagnostics.ProcessStartInfo("C:\MyPath\MyExe.EXE")
    Dim loProcess As System.Diagnostics.Process

    loStart.WindowStyle = Diagnostics.ProcessWindowStyle.Normal

    '-- Start the process
    loProcess = System.Diagnostics.Process.Start(loStart)

    '-- Wait until the window handle can be obtained
    Do While _ProgramHandle.ToInt32() = 0
        _ProgramHandle = System.Diagnostics.Process.GetProcessById(loProcess.Id).MainWindowHandle
    Loop
End Sub

Now that you have the handle stored off, you can restore the window using WinAPI when the user clicks the menu item again. 

Here is a list of the WinAPIs you will have to declare:

   

Public Const SW_SHOWMAXIMIZED As Integer = 3
Public Const SW_RESTORE As Integer = 9

    <DllImport("user32.dll")> _
    Public Function ShowWindow(ByVal WindowHandle As Integer, ByVal Command As Integer) As Boolean
    End Function
    <DllImport("user32.dll")> _
    Public Function SetForegroundWindow(ByVal WindowHandle As Integer) As Boolean
    End Function
    <DllImport("user32.dll")> _
    Public Function SetActiveWindow(ByVal WindowHandle As Integer) As Boolean
    End Function
    <DllImport("user32.dll")> _
    Public Function SetFocus(ByVal hwnd As Integer) As Integer
    End Function

I added the SW_MAXIMIZED value above in case you needed to test on a maximized window.  Then you can use those declared WinAPI methods like this:

SetForegroundWindow(_ProgramHandle.ToInt32())
SetActiveWindow(_ProgramHandle.ToInt32())
ShowWindow(_ProgramHandle.ToInt32(), SW_RESTORE)
By Tim Dol - 3/13/2007

Thanks Trent, this is exactly what I was looking for.

How do you handle something like the security dialog.  Right now I  launch it in a separate window using loDialog.Show() because I have problems with scroll bars when I launch inside my MDI. (I just haven't had time to investigate why you can't scroll properly).

If I minimize the security dialog and then try to activate again through the menu system, I want to restore the existing instance to prevent multiple instances. How do I accomplish something like this.

Thanks

By Trent L. Taylor - 3/13/2007

Well, since you are using n MDI form you can cycle through all of the instantiated forms through the forms collection:

Public Function RestoreForm(ByVal FormType As System.Type) As Boolean
Dim loForm As System.Windows.Forms.Form
Dim llReturn As Boolean = False

For Each loForm In MyMDI.MdiChildren
   If loForm.GetType() Is FormType
      llReturn = True
     
      If loForm.WindowState = FormWindowState.Minimized Then
         loForm.WindowState = FormWindowState.Normal
      End If
   End If   
Next

Return llReturn
End Function

You would call it like this:

If Not RestoreForm(GetType(MyForm)) Then
    '-- Launch your form
End If