BillWoodruff
Вот рабочий пример, который показывает, как запустить один c# exe из другого и расположить две формы (основную форму первого приложения, основную форму второго приложения) так, чтобы каждая из них занимала половину рабочей области экрана основного монитора.
using System;
using System.Diagnostics;
using System.Drawing;
using System.Runtime.InteropServices;
using System.Threading;
using System.Windows.Forms;
namespace YourApplication1
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
// http://www.pinvoke.net/default.aspx/user32.SetWindowPos
static readonly IntPtr HWND_TOPMOST = new IntPtr(-1);
static readonly IntPtr HWND_NOTOPMOST = new IntPtr(-2);
static readonly IntPtr HWND_TOP = new IntPtr(0);
static readonly IntPtr HWND_BOTTOM = new IntPtr(1);
// adapted from http://www.pinvoke.net/default.aspx/user32.SetWindowPos
[Flags]
public enum SetWindowPosFlags
{
NOSIZE = 0x0001,
NOMOVE = 0x0002,
NOZORDER = 0x0004,
NOREDRAW = 0x0008,
NOACTIVATE = 0x0010,
DRAWFRAME = 0x0020,
FRAMECHANGED = 0x0020,
SHOWWINDOW = 0x0040,
HIDEWINDOW = 0x0080,
NOCOPYBITS = 0x0100,
NOOWNERZORDER = 0x0200,
NOREPOSITION = 0x0200,
NOSENDCHANGING = 0x0400,
DEFERERASE = 0x2000,
ASYNCWINDOWPOS = 0x4000
}
[DllImport("user32.dll", SetLastError = true)]
static extern bool SetWindowPos(IntPtr hWnd, IntPtr hWndInsertAfter, int X, int Y, int cx, int cy, SetWindowPosFlags uFlags);
// used in the example in the Form1 LocationChanged EventHandler
// http://www.pinvoke.net/default.aspx/user32.movewindow
[DllImport("user32.dll", SetLastError = true)]
internal static extern bool MoveWindow(IntPtr hWnd, int X, int Y, int nWidth, int nHeight, bool bRepaint);
// second WinForm exe location
private string app2path = @"your complete second app exe filepath";
public Rectangle ScreenRect;
public ProcessStartInfo psi;
public Process secondAppProcess;
private void Form1_Load(object sender, EventArgs e)
{
ScreenRect = Screen.PrimaryScreen.WorkingArea;
this.Size = new Size(ScreenRect.Width/2, ScreenRect.Height);
this.Location = ScreenRect.Location;
psi = new ProcessStartInfo(app2path);
psi.WindowStyle = ProcessWindowStyle.Normal;
psi.UseShellExecute = false;
secondAppProcess = new Process();
secondAppProcess.StartInfo = psi;
secondAppProcess.Start();
// I've never been able to get this to work without this
Thread.Sleep(100);
// what WaitForInputIdle really does:
// https://blogs.msdn.microsoft.com/oldnewthing/20100325-00/?p=14493/
secondAppProcess.WaitForInputIdle();
SetWindowPos(
secondAppProcess.MainWindowHandle,
HWND_TOP,
this.Left + this.Width,
this.Top,
this.Width,
this.Height,
SetWindowPosFlags.SHOWWINDOW);
}
private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
secondAppProcess.CloseMainWindow();
}
private void Form1_LocationChanged(object sender, EventArgs e)
{
MoveWindow(secondAppProcess.MainWindowHandle, this.Right, this.Top, this.Width, this.Height, true);
}
}
}
Записи:
1 .в этом примере я решил закрыть второе приложение, когда закроется первое... это не значит, что вы должны это делать, но ... .. подумайте об этом.
2 .в этом примере, когда первое главное окно приложения перемещается, второе главное окно приложения перемещается вместе с ним... просто пример, иллюстрирующий использование вызова API MoveWindow. Вы так же легко справляетесь с любым изменением в окне первого приложения, чтобы установить размер или что-то еще для окна второго приложения.