@@ -603,13 +603,34 @@ pub fn callMain() u8 {
603
603
}
604
604
605
605
pub fn call_wWinMain () std.os.windows.INT {
606
+ const peb = std .os .windows .peb ();
606
607
const MAIN_HINSTANCE = @typeInfo (@TypeOf (root .wWinMain )).Fn .params [0 ].type .? ;
607
608
const hInstance = @as (MAIN_HINSTANCE , @ptrCast (std .os .windows .kernel32 .GetModuleHandleW (null ).? ));
608
609
const lpCmdLine = std .os .windows .kernel32 .GetCommandLineW ();
609
610
610
- // There's no (documented) way to get the nCmdShow parameter, so we're
611
- // using this fairly standard default.
612
- const nCmdShow = 5 ;
611
+ // There are various types used for the 'show window' variable through the Win32 APIs:
612
+ // - u16 in STARTUPINFOA.wShowWindow / STARTUPINFOW.wShowWindow
613
+ // - c_int in ShowWindow
614
+ // - u32 in PEB.ProcessParameters.dwShowWindow
615
+ // Since STARTUPINFO is the bottleneck for the allowed values, we use `u16` as the
616
+ // type which can coerce into i32/c_int/u32 depending on how the user defines their wWinMain
617
+ // (the Win32 docs show wWinMain with `int` as the type for nCmdShow).
618
+ const nCmdShow : u16 = nCmdShow : {
619
+ // This makes Zig match the nCmdShow behavior of a C program with a WinMain symbol:
620
+ // - With STARTF_USESHOWWINDOW set in STARTUPINFO.dwFlags of the CreateProcess call:
621
+ // - Compiled with subsystem:console -> nCmdShow is always SW_SHOWDEFAULT
622
+ // - Compiled with subsystem:windows -> nCmdShow is STARTUPINFO.wShowWindow from
623
+ // the parent CreateProcess call
624
+ // - With STARTF_USESHOWWINDOW unset:
625
+ // - nCmdShow is always SW_SHOWDEFAULT
626
+ const SW_SHOWDEFAULT = 10 ;
627
+ const STARTF_USESHOWWINDOW = 1 ;
628
+ // root having a wWinMain means that std.builtin.subsystem will always have a non-null value.
629
+ if (std .builtin .subsystem .? == .Windows and peb .ProcessParameters .dwFlags & STARTF_USESHOWWINDOW != 0 ) {
630
+ break :nCmdShow @truncate (peb .ProcessParameters .dwShowWindow );
631
+ }
632
+ break :nCmdShow SW_SHOWDEFAULT ;
633
+ };
613
634
614
635
// second parameter hPrevInstance, MSDN: "This parameter is always NULL"
615
636
return root .wWinMain (hInstance , null , lpCmdLine , nCmdShow );
0 commit comments