2

I am using a form to start new flash processes using Process.start() and MoveWindow() to resize and change the process window location. The problem is before MoveWindow() is call you can see the window in its default size and location for a split second. I wanna know if there is a way to set the location and size of the window before the actual process is started.

Process flash = new Process();
flash.StartInfo.WindowStyle = ProcessWindowStyle.Normal;
flash.StartInfo.FileName = "C:\\RED\\bin\\android.swf";
flash.Start();
Thread.Sleep(300);
mainForm.MoveWindow(flash.MainWindowHandle, posX, 0, 1920, 1080, true);
edi9999
  • 19,701
  • 13
  • 88
  • 127
Miguel Sato
  • 21
  • 1
  • 2
  • Initial window size could be taken from somewhere. Otherwise the only option is to do it as you do. Tip: try to show minimized window and restore/move after together. – Sinatr May 27 '15 at 15:28
  • Your tip worked partially, I'm using 2 screen and want to play a flash in each screen. Using minimized window and them restore it cause the window to allways apear in the primary screen. – Miguel Sato May 27 '15 at 16:09

2 Answers2

3

Use CreateProcess. I had a same need for creating another process with the position.

I have defined the PInvoke like below.

public class Kernel32
{
    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
    public struct STARTUPINFO
    {
        public uint cb;
        public string lpReserved;
        public string lpDesktop;
        public string lpTitle;
        public uint dwX;
        public uint dwY;
        public uint dwXSize;
        public uint dwYSize;
        public uint dwXCountChars;
        public uint dwYCountChars;
        public uint dwFillAttribute;
        public uint dwFlags;
        public short wShowWindow;
        public short cbReserved2;
        public IntPtr lpReserved2;
        public IntPtr hStdInput;
        public IntPtr hStdOutput;
        public IntPtr hStdError;
    }

    [StructLayout(LayoutKind.Sequential)]
    public struct PROCESS_INFORMATION
    {
        public IntPtr hProcess;
        public IntPtr hThread;
        public int dwProcessId;
        public int dwThreadId;
    }

    [StructLayout(LayoutKind.Sequential)]
    public struct SECURITY_ATTRIBUTES
    {
        public int nLength;
        public IntPtr lpSecurityDescriptor;
        public int bInheritHandle;
    }

    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
    public struct STARTUPINFOEX
    {
        public STARTUPINFO StartupInfo;
        public IntPtr lpAttributeList;
    }

    [DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Auto)]
    public static extern bool CreateProcess(
       string lpApplicationName,
       string lpCommandLine,
       ref SECURITY_ATTRIBUTES lpProcessAttributes,
       ref SECURITY_ATTRIBUTES lpThreadAttributes,
       bool bInheritHandles,
       uint dwCreationFlags,
       IntPtr lpEnvironment,
       string lpCurrentDirectory,
       [In] ref STARTUPINFO lpStartupInfo,
       out PROCESS_INFORMATION lpProcessInformation);
}

And use it like below.

const uint NORMAL_PRIORITY_CLASS = 0x0020;
const uint CREATE_UNICODE_ENVIRONMENT = 0x0400;
const uint STARTF_USESHOWWINDOW = 0x0001;
var pInfo = new Kernel32.PROCESS_INFORMATION();
var sInfo = new Kernel32.STARTUPINFO();
sInfo.dwX = (uint)hostingApp.X; // X Position 
sInfo.dwY = (uint)hostingApp.Y; // Y Position 
sInfo.dwXSize = (uint)hostingApp.Width; // Width
sInfo.dwYSize = (uint)hostingApp.Height; // Height
sInfo.dwFlags = STARTF_USESHOWWINDOW;
var pSec = new Kernel32.SECURITY_ATTRIBUTES();
var tSec = new Kernel32.SECURITY_ATTRIBUTES();
pSec.nLength = System.Runtime.InteropServices.Marshal.SizeOf(pSec);
tSec.nLength = System.Runtime.InteropServices.Marshal.SizeOf(tSec);

    var create_result = Kernel32.CreateProcess(
        fileName,                   // lpApplicationName
        " " + arguments,            // lpCommandLine
        ref pSec,                   // lpProcessAttributes
        ref tSec,                   // lpThreadAttributes
        false,                      // bInheritHandles
        NORMAL_PRIORITY_CLASS | CREATE_UNICODE_ENVIRONMENT,      // dwCreationFlags
        IntPtr.Zero,                // lpEnvironment
        null,                       // lpCurrentDirectory
        ref sInfo,                  // lpStartupInfo
        out pInfo);                 // lpProcessInformation


    var process = Process.GetProcessById(pInfo.dwProcessId);

Hope this helps.

  • I tried using a variation of this example, but the launched app (Notepad) did not listen to the XY dimensions set in the STARTUPINFO structure. If I did NOT set the dwFlags value, Notepad appeared normally. If I did set the dwFlags value to STARTF_USESHOWWINDOW, Notepad would not appear at all and was not in the taskbar (although I was able to print its process id). The MSDN doc says that the dimensions will be used the first time the app calls CreateWindow, but Notepad ignores my size settings. – Kevin Apr 19 '21 at 22:06
1

Look at the ProcessStartInfo.WindowStyle. You should be able to set it to start as Hidden until you've moved and resized it and then set it back to normal.

See here:

The hidden window style. A window can be either visible or hidden. The system displays a hidden window by not drawing it. If a window is hidden, it is effectively disabled. A hidden window can process messages from the system or from other windows, but it cannot process input from the user or display output. Frequently, an application may keep a new window hidden while it customizes the window's appearance, and then make the window style Normal. To use ProcessWindowStyle.Hidden, the ProcessStartInfo.UseShellExecute property must be false.

For how to change the style after the process has started, see this question:

Toggle Process.StartInfo.WindowStyle = ProcessWindowStyle.Hidden at runtime

Community
  • 1
  • 1
Matt Burland
  • 44,552
  • 18
  • 99
  • 171
  • 2
    I try using ProcessWindowStyle.Hidden, but the problem is that hidden windows doesnt have a handle (nor a actual window) so i cant resize it. – Miguel Sato May 27 '15 at 15:38