views:

145

answers:

2

Question: In VB.net, you can set focus to an external application using

AppActivate("Windows Name") or AppActivate(processID as integer)

Now this works fine if you do for example:

Dim intNotePad As Integer = Shell("C:\WINNT\Notepad.exe",

AppWinStyle.MinimizedNoFocus) AppActivate(intNotePad)

But when I do

       For Each theprocess As Process In processlist
        If InStr(theprocess.ProcessName, "DWG") Then

            strProcessList += String.Format("Process: {0} ID: {1}", theprocess.ProcessName, theprocess.Id) + vbCrLf


            AppActivate(theprocess.ID)
        End If

next theprocess

then it doesn't find the window, even if it's open and even if it finds the window using the window title.

But I need it by process id.

How can i do that ?

I need it to set focus on a 3rd party installer in a windows installer setup project.

+1  A: 

I don't know exactly why your not achieveing the correct result. Generally, when setting focus to other applications, I've never had too much luck with AppActivate (varying degrees of success, at least). Try this instead:

Add this class to the same module / object / whereever your code is:

Public NotInheritable Class Win32Helper
    <System.Runtime.InteropServices.DllImport("user32.dll", _
    EntryPoint:="SetForegroundWindow", _
    CallingConvention:=Runtime.InteropServices.CallingConvention.StdCall, _
    CharSet:=Runtime.InteropServices.CharSet.Unicode, SetLastError:=True)> _
    Public Shared Function _
    SetForegroundWindow(ByVal handle As IntPtr) As Boolean
        ' Leave function empty
    End Function

    <System.Runtime.InteropServices.DllImport("user32.dll", _
    EntryPoint:="ShowWindow", _
    CallingConvention:=Runtime.InteropServices.CallingConvention.StdCall, _
    CharSet:=Runtime.InteropServices.CharSet.Unicode, SetLastError:=True)> _
    Public Shared Function ShowWindow(ByVal handle As IntPtr, _
    ByVal nCmd As Int32) As Boolean
        ' Leave function empty
    End Function
End Class

Then in your code, instead of AppActivate do the following:

Dim appHandle as intPtr
appHandle=theprocess.MainWindowHandle 'theprocess is naturally your process object

Dim Win32Help As New Win32Helper
Win32Helper.SetForegroundWindow(appHandle)
Morten K
+1  A: 

Try these Win32 functions

Declare Sub SwitchToThisWindow Lib "user32.dll" (ByVal hWnd As IntPtr, ByVal fAltTab As Boolean)
Declare Function SetActiveWindow Lib "user32.dll" (ByVal hwnd As IntPtr) As IntPtr
Private Enum ShowWindowEnum
    Hide = 0
    ShowNormal = 1
    ShowMinimized = 2
    ShowMaximized = 3
    Maximize = 3
    ShowNormalNoActivate = 4
    Show = 5
    Minimize = 6
    ShowMinNoActivate = 7
    ShowNoActivate = 8
    Restore = 9
    ShowDefault = 10
    ForceMinimized = 11
End Enum

Use Process.MainWindowHandle to get the handle. This works on most, but not all, applications.

Jonathan Allen