867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895fn call_wWinMain() std.os.windows.INT {
const peb = std.os.windows.peb();
const MAIN_HINSTANCE = @typeInfo(@TypeOf(root.wWinMain)).@"fn".param_types[0].?;
const hInstance: MAIN_HINSTANCE = @ptrCast(peb.ImageBaseAddress);
const lpCmdLine: [*:0]u16 = @ptrCast(peb.ProcessParameters.CommandLine.Buffer);
// There are various types used for the 'show window' variable through the Win32 APIs:
// - u16 in STARTUPINFOA.wShowWindow / STARTUPINFOW.wShowWindow
// - c_int in ShowWindow
// - u32 in PEB.ProcessParameters.dwShowWindow
// Since STARTUPINFO is the bottleneck for the allowed values, we use `u16` as the
// type which can coerce into i32/c_int/u32 depending on how the user defines their wWinMain
// (the Win32 docs show wWinMain with `int` as the type for nShowCmd).
const nShowCmd: u16 = nShowCmd: {
// This makes Zig match the nShowCmd behavior of a C program with a WinMain symbol:
// - With STARTF_USESHOWWINDOW set in STARTUPINFO.dwFlags of the CreateProcess call:
// - nShowCmd is STARTUPINFO.wShowWindow from the parent CreateProcess call
// - With STARTF_USESHOWWINDOW unset:
// - nShowCmd is always SW_SHOWDEFAULT
const SW_SHOWDEFAULT = 10;
if (peb.ProcessParameters.dwFlags & std.os.windows.STARTF_USESHOWWINDOW != 0) {
break :nShowCmd @truncate(peb.ProcessParameters.dwShowWindow);
}
break :nShowCmd SW_SHOWDEFAULT;
};
// second parameter hPrevInstance, MSDN: "This parameter is always NULL"
return root.wWinMain(hInstance, null, lpCmdLine, nShowCmd);
}