Проблема
Я думаю, что это трудно сделать в подпрограмме вызывающей стороны btnOpenExplorer_Click
, поскольку будет слишком рано получать объект процесса со всеми назначенными ему свойствами. В основном это свойства ProcessMainWindowTitle и Process.MainWindowHandle , которые необходимы для решения этой проблемы. Чтобы обойти это, нужно, чтобы вызывающая сторона запускала процессы, а таймер - для позиционирования и изменения размера с помощью функции SetWindowPos .
Вот как я это сделаю:
Функции API
<DllImport("user32.dll", EntryPoint:="SetWindowPos")>
Private Shared Function SetWindowPos(ByVal hWnd As IntPtr, ByVal hWndInsertAfter As IntPtr, ByVal X As Integer, ByVal Y As Integer, ByVal cx As Integer, ByVal cy As Integer, ByVal uFlags As UInteger) As <MarshalAs(UnmanagedType.Bool)> Boolean
End Function
<DllImport("user32.dll")>
Private Shared Function IsIconic(hWnd As IntPtr) As <MarshalAs(UnmanagedType.Bool)> Boolean
End Function
Константы и переменные уровня класса
Private Const HWND_TOP As Integer = &H0
Private Const SW_SHOWNORMAL As Integer = &H1
Private dir1, dir2 As String
Private WithEvents Timer1 As New Timer With {.Interval = 250}
Process Finder
Private Function GetExplorerProcess(title As String) As Process
Dim dirName As String = If(IO.Directory.Exists(title), New IO.DirectoryInfo(title).Name, title).ToLower
Return Process.GetProcesses.Where(
Function(a) a.ProcessName.ToLower.Equals("explorer") AndAlso
a.MainWindowTitle.ToLower.Equals(dirName)
).FirstOrDefault
End Function
Звонящий
Private Sub btnOpenExplorer_Click(sender As Object, e As EventArgs) Handles btnOpenExplorer.Click
Dim proc1 As Process = GetExplorerProcess(dir1)
If proc1 Is Nothing Then
Dim procInfo1 As New ProcessStartInfo With {
.FileName = "explorer.exe",
.Arguments = dir1,
.WindowStyle = ProcessWindowStyle.Normal
}
Process.Start(procInfo1)
End If
Dim proc2 As Process = GetExplorerProcess(dir2)
If proc2 Is Nothing Then
Dim procInfo2 As New ProcessStartInfo With {
.FileName = "explorer.exe",
.Arguments = dir2,
.WindowStyle = ProcessWindowStyle.Normal
}
Process.Start(procInfo2)
End If
Timer1.Start()
End Sub
Таймер - Активация Windows, установка размера и местоположения
Private Sub Timer1_Tick(sender As Object, e As EventArgs) Handles Timer1.Tick
Dim proc1 As Process = GetExplorerProcess(dir1)
Dim proc2 As Process = GetExplorerProcess(dir2)
If proc1 IsNot Nothing AndAlso proc2 IsNot Nothing Then
Timer1.Stop()
Dim R As Rectangle = Screen.PrimaryScreen.WorkingArea
Dim R1 As New Rectangle(R.X, R.Height - (R.Height / 3), R.Width / 2, R.Height / 4)
Dim R2 As New Rectangle(R1.Right, R1.Y, R1.Width, R1.Height)
Dim hWnd1 As IntPtr = proc1.MainWindowHandle
Dim hWnd2 As IntPtr = proc2.MainWindowHandle
'Restore the first window if its minimized.
If IsIconic(hWnd1) Then
ShowWindow(hWnd1, SW_SHOWNORMAL)
End If
'Set the size and location of the first window.
SetWindowPos(hWnd1, IntPtr.op_Explicit(HWND_TOP), R1.X, R1.Y, R1.Width, R1.Height, 0)
'Restore the second window if its minimized.
If IsIconic(hWnd2) Then
ShowWindow(hWnd2, SW_SHOWNORMAL)
End If
'Set the size and location of the second window.
SetWindowPos(hWnd2, IntPtr.op_Explicit(HWND_TOP), R2.X, R2.Y, R2.Width, R2.Height, 0)
End If
End Sub
Все готово к работе. Удачи.
Ссылки
Установить местоположение экрана дочернего окна внешнего приложения?
Функция SetWindowPos
Управление процессами в .NET
Как сделать окно активным в vb.net