8

In an MFC program, you can determine whether the application shortcut had the Run value set to "Minimized" by checking the value of m_nCmdShow. Is there an equivalent way to do this in c#?

To clarify, I don't want to set the state of a particular form. If you look at the properties for a shortcut, there is a "Run" option. You can set this value to Normal Window, Minimized, or Maximized.

In C++ you can read what that startup value was set to by looking at m_nCmdShow. I need to do the same thing in C#.

Update

This attempt:

[STAThread]
static void Main(string[] args)
{
    ProcessStartInfo processInfo = Process.GetCurrentProcess().StartInfo;
    MessageBox.Show(processInfo.WindowStyle.ToString());
    ...
}

always reports Normal, no matter what the shortcut is set to.

lfalin
  • 4,219
  • 5
  • 31
  • 57

2 Answers2

3

In WindowsForms its the WindowState property of Form class. check it up in properties at design time or set it from code.

Edit: When running the program from a shortcut Windows is likely to use the CreateProcess API passing a STARTUPINFO structure to it.

from your Windows Forms application you get such structure in this way:

System.Diagnostics.Process.GetCurrentProcess().StartInfo

which contains the property: WindowStyle and the available values for it are those of the enum:

System.Diagnostics.ProcessWindowStyle

so:

Hidden;
Minimized;
Maximized;
Normal;

and that's the mapping to m_nCmdShow the OP is looking for.

Davide Piras
  • 43,984
  • 10
  • 98
  • 147
  • Interesting! how is that member set in MFC? its value must get assigned somewhere... – Davide Piras Sep 14 '11 at 16:53
  • @Ifalin: see my last edit :) hope this answers completely your question. – Davide Piras Sep 14 '11 at 18:57
  • strange... there was actually also another question about this: http://stackoverflow.com/questions/7026395/how-to-pass-windowstate-from-desktop-shortcut-into-wpf-app – Davide Piras Sep 15 '11 at 14:07
  • Maybe it makes a difference if your startup object is set to a form or a not. Mine is set to a class rather than a form, because there are some other things that need to happen on startup. – lfalin Sep 15 '11 at 14:19
0

This lets you retrieve the initial window state by accessing NativeMethods.StartupInfo.GetInitialWindowStyle() in your code. You can use more information by accessing NativeMethods.StartupInfo.FromCurrentProcess. If you start your program from cmd.exe with START "My Program Title" /MIN MyProgram.exe, you'll find "My Program Title" in NativeMethods.StartupInfo.FromCurrentProcess.lpTitle and NativeMethods.StartupInfo.GetInitialWindowStyle() returns ProcessWindowStyle.Minimized.

static partial class NativeMethods
{
    public static class StartupInfo
    {
        [StructLayout(LayoutKind.Sequential)]
        public class STARTUPINFO
        {
            public readonly UInt32 cb;  
            private IntPtr lpReserved;
            [MarshalAs(UnmanagedType.LPWStr)] public readonly string lpDesktop;
            [MarshalAs(UnmanagedType.LPWStr)] public readonly string lpTitle;
            public readonly UInt32 dwX;
            public readonly UInt32 dwY;
            public readonly UInt32 dwXSize;
            public readonly UInt32 dwYSize;
            public readonly UInt32 dwXCountChars;
            public readonly UInt32 dwYCountChars;
            public readonly UInt32 dwFillAttribute;
            public readonly UInt32 dwFlags;
            [MarshalAs(UnmanagedType.U2)] public readonly UInt16 wShowWindow;
            [MarshalAs(UnmanagedType.U2)] private UInt16 cbReserved2;
            private IntPtr lpReserved2;
            public readonly IntPtr hStdInput;
            public readonly IntPtr hStdOutput;
            public readonly IntPtr hStdError;
        }

        public readonly static STARTUPINFO FromCurrentProcess = null;

        const uint STARTF_USESHOWWINDOW = 0x00000001;
        const ushort SW_HIDE = 0;
        const ushort SW_SHOWNORMAL = 1;
        const ushort SW_SHOWMINIMIZED = 2;
        const ushort SW_SHOWMAXIMIZED = 3;
        const ushort SW_MINIMIZE = 6;
        const ushort SW_SHOWMINNOACTIVE = 7;
        const ushort SW_FORCEMINIMIZE = 11;

        [DllImport("kernel32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
        static extern void GetStartupInfoW(IntPtr startupInfoPtr);

        static StartupInfo() //Static constructor
        {
            FromCurrentProcess = new STARTUPINFO();
            int length = Marshal.SizeOf(typeof(STARTUPINFO));
            IntPtr ptr = Marshal.AllocHGlobal(length);

            Marshal.StructureToPtr(FromCurrentProcess, ptr, false);

            GetStartupInfoW(ptr);

            Marshal.PtrToStructure(ptr, FromCurrentProcess);
            Marshal.FreeHGlobal(ptr);
        }

        public static ProcessWindowStyle GetInitialWindowStyle()
        {
            if ((FromCurrentProcess.dwFlags & STARTF_USESHOWWINDOW) == 0) return ProcessWindowStyle.Normal;

            switch (FromCurrentProcess.wShowWindow)
            {
                case SW_HIDE: return ProcessWindowStyle.Hidden;
                case SW_SHOWNORMAL: return ProcessWindowStyle.Normal;
                case SW_MINIMIZE:
                case SW_FORCEMINIMIZE:
                case SW_SHOWMINNOACTIVE:
                case SW_SHOWMINIMIZED: return ProcessWindowStyle.Minimized;
                case SW_SHOWMAXIMIZED: return ProcessWindowStyle.Maximized;
                default: return ProcessWindowStyle.Normal;
            }
        }
    } 
}