Click here to Skip to main content
15,886,199 members
Please Sign up or sign in to vote.
2.50/5 (2 votes)
See more:
C#
I am saving position with the values top,left,height,width.I have two forms which are of 2 different exes.So,the second form is opened from first form so it is taking the top,left with reference to first form and not the screen.

Issue cause due to this is as below,

1.Second form position is saved to be opened at the middle of first form.
2.Now I open the first form ,resize it to the minimum size and move it to bottom right 
3.Now I open the second form.

Second form is not visible because it is below the first form and there is no space. When I maximize the first form,second form also repositions itself and is visible.


What I have tried:

Individually it works fine.when 2 forms are from 2 different exe's this issue occurs.2 forms from same single exe doesnt cause this issue.
Posted
Updated 15-Jul-16 1:38am
Comments
BillWoodruff 15-Jul-16 3:54am    
Please show the code that runs an instance of the second exe.

"Individually it works fine.when 2 forms are from 2 different exe's this issue occurs.2 forms from same single exe doesnt cause this issue." Are you saying you do not have a problem if both Forms are part of the same WinForm App ?

Please describe exactly how you wish the first and second App's Forms to be positioned.

1 solution

Here's a working example that shows how to launch one C# exe from another, and position the two Forms (the first app's Main Form, the second app's Main Form) so they each occupy half the working-screen-area of the primary monitor.
C#
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);
        }
    }
}
Notes:

1. in this example I chose to close the second app when the first app closes ... that doesn't mean you have to do that, but ... think about the issue.

2. in this example, when the firs app main window moves the second app main window moves along with it ... just an example to illustrate the use of the 'MoveWindow API call. You just as easily deal with any change in the first app's window to set the size, or whatever, for the second app's window.
 
Share this answer
 

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900