authorgravatar for squeek502@hotmail.comRyan Liptak <squeek502@hotmail.com> 2023-10-31 01:26:50-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2023-11-02 00:19:40-04:00
log42d4d07efa0a6affd87fcf7b833bdffd40a78c25
tree6cd33e7f3a1b9f4f2c008d5cb845198a9c82ea1d
parentd892665694bc437898c58631cc632bc93a528e97

start: Make wWinMain nCmdShow setting match Windows better

It won't match perfectly; see https://github.com/ziglang/zig/issues/17808

1 files changed, 24 insertions(+), 3 deletions(-)

lib/std/start.zig+24-3
...@@ -603,13 +603,34 @@ pub fn callMain() u8 {...@@ -603,13 +603,34 @@ pub fn callMain() u8 {
603}603}
604604
605pub fn call_wWinMain() std.os.windows.INT {605pub fn call_wWinMain() std.os.windows.INT {
606 const peb = std.os.windows.peb();
606 const MAIN_HINSTANCE = @typeInfo(@TypeOf(root.wWinMain)).Fn.params[0].type.?;607 const MAIN_HINSTANCE = @typeInfo(@TypeOf(root.wWinMain)).Fn.params[0].type.?;
607 const hInstance = @as(MAIN_HINSTANCE, @ptrCast(std.os.windows.kernel32.GetModuleHandleW(null).?));608 const hInstance = @as(MAIN_HINSTANCE, @ptrCast(std.os.windows.kernel32.GetModuleHandleW(null).?));
608 const lpCmdLine = std.os.windows.kernel32.GetCommandLineW();609 const lpCmdLine = std.os.windows.kernel32.GetCommandLineW();
609610
610 // There's no (documented) way to get the nCmdShow parameter, so we're611 // There are various types used for the 'show window' variable through the Win32 APIs:
611 // using this fairly standard default.612 // - u16 in STARTUPINFOA.wShowWindow / STARTUPINFOW.wShowWindow
612 const nCmdShow = 5;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 };
613634
614 // second parameter hPrevInstance, MSDN: "This parameter is always NULL"635 // second parameter hPrevInstance, MSDN: "This parameter is always NULL"
615 return root.wWinMain(hInstance, null, lpCmdLine, nCmdShow);636 return root.wWinMain(hInstance, null, lpCmdLine, nCmdShow);