- fixed Windows startup.

* the window class name was still ASCII, thanks to some totally pointless and ultimately dangerous type cast to LPCTSTR which rendered all type checks ineffective.
* use wWinMain instead of WinMain so that a Unicode argv gets created. For whatever reason, the ANSI startup leaves this variable empty.
* added a 'disablecrashlog' CCMD for Windows. It is a lot more useful with a debugger present to get the standard crash notification from the system which allows opening a debugger than the crash log and no option to open a debugger.
This commit is contained in:
Christoph Oelckers 2019-02-17 10:10:41 +01:00
parent f512f29270
commit 78d0fa9269
2 changed files with 26 additions and 21 deletions

View file

@ -151,7 +151,7 @@ DYN_WIN32_SYM(SHGetKnownFolderPath);
// PRIVATE DATA DEFINITIONS ------------------------------------------------ // PRIVATE DATA DEFINITIONS ------------------------------------------------
static const char WinClassName[] = GAMENAME "MainWindow"; static const WCHAR WinClassName[] = WGAMENAME "MainWindow";
static HMODULE hwtsapi32; // handle to wtsapi32.dll static HMODULE hwtsapi32; // handle to wtsapi32.dll
static void (*TermFuncs[MAX_TERMS])(void); static void (*TermFuncs[MAX_TERMS])(void);
static int NumTerms; static int NumTerms;
@ -766,7 +766,7 @@ void ShowErrorPane(const char *text)
paraformat.dwMask = PFM_STARTINDENT | PFM_OFFSETINDENT | PFM_RIGHTINDENT; paraformat.dwMask = PFM_STARTINDENT | PFM_OFFSETINDENT | PFM_RIGHTINDENT;
paraformat.dxStartIndent = paraformat.dxOffset = paraformat.dxRightIndent = 120; paraformat.dxStartIndent = paraformat.dxOffset = paraformat.dxRightIndent = 120;
SendMessage (ConWindow, EM_SETPARAFORMAT, 0, (LPARAM)&paraformat); SendMessage (ConWindow, EM_SETPARAFORMAT, 0, (LPARAM)&paraformat);
SendMessageW (ConWindow, EM_REPLACESEL, FALSE, (LPARAM)"\n"); SendMessageW (ConWindow, EM_REPLACESEL, FALSE, (LPARAM)L"\n");
// Find out where the error lines start for the error icon display control. // Find out where the error lines start for the error icon display control.
SendMessage (ConWindow, EM_EXGETSEL, 0, (LPARAM)&end); SendMessage (ConWindow, EM_EXGETSEL, 0, (LPARAM)&end);
@ -834,7 +834,15 @@ void DoMain (HINSTANCE hInstance)
_set_new_handler (NewFailure); _set_new_handler (NewFailure);
#endif #endif
Args = new FArgs(__argc, __argv); // Do not use the multibyte __argv here because we want UTF-8 arguments
// and those can only be done by converting the Unicode variants.
Args = new FArgs();
auto argc = __argc;
auto wargv = __wargv;
for (int i = 0; i < argc; i++)
{
Args->AppendArg(FString(wargv[i]));
}
// Load Win32 modules // Load Win32 modules
Kernel32Module.Load({"kernel32.dll"}); Kernel32Module.Load({"kernel32.dll"});
@ -957,7 +965,7 @@ void DoMain (HINSTANCE hInstance)
WndClass.hCursor = LoadCursor (NULL, IDC_ARROW); WndClass.hCursor = LoadCursor (NULL, IDC_ARROW);
WndClass.hbrBackground = NULL; WndClass.hbrBackground = NULL;
WndClass.lpszMenuName = NULL; WndClass.lpszMenuName = NULL;
WndClass.lpszClassName = (LPCTSTR)WinClassName; WndClass.lpszClassName = WinClassName;
/* register this new class with Windows */ /* register this new class with Windows */
if (!RegisterClass((LPWNDCLASS)&WndClass)) if (!RegisterClass((LPWNDCLASS)&WndClass))
@ -966,9 +974,9 @@ void DoMain (HINSTANCE hInstance)
/* create window */ /* create window */
FStringf caption("" GAMESIG " %s " X64 " (%s)", GetVersionString(), GetGitTime()); FStringf caption("" GAMESIG " %s " X64 " (%s)", GetVersionString(), GetGitTime());
std::wstring wcaption = caption.WideString(); std::wstring wcaption = caption.WideString();
Window = CreateWindowEx( Window = CreateWindowExW(
WS_EX_APPWINDOW, WS_EX_APPWINDOW,
(LPCTSTR)WinClassName, WinClassName,
wcaption.c_str(), wcaption.c_str(),
WS_OVERLAPPEDWINDOW | WS_VISIBLE | WS_CLIPCHILDREN, WS_OVERLAPPEDWINDOW | WS_VISIBLE | WS_CLIPCHILDREN,
x, y, width, height, x, y, width, height,
@ -1253,13 +1261,20 @@ static void infiniterecursion(int foo)
} }
#endif #endif
// Setting this to 'true' allows getting the standard notification for a crash
// which offers the very important feature to open a debugger and see the crash in context right away.
CUSTOM_CVAR(Bool, disablecrashlog, false, CVAR_ARCHIVE | CVAR_GLOBALCONFIG)
{
SetUnhandledExceptionFilter(!*self ? CatchAllExceptions : nullptr);
}
//========================================================================== //==========================================================================
// //
// WinMain // WinMain
// //
//========================================================================== //==========================================================================
int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE nothing, LPSTR cmdline, int nCmdShow) int WINAPI wWinMain (HINSTANCE hInstance, HINSTANCE nothing, LPWSTR cmdline, int nCmdShow)
{ {
g_hInst = hInstance; g_hInst = hInstance;
@ -1276,27 +1291,27 @@ int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE nothing, LPSTR cmdline, int n
} }
#if !defined(__GNUC__) && defined(_DEBUG) #if !defined(__GNUC__) && defined(_DEBUG)
if (__argc == 2 && strcmp (__argv[1], "TestCrash") == 0) if (__argc == 2 && __wargv != nullptr && wcscmp (__wargv[1], L"TestCrash") == 0)
{ {
__try __try
{ {
*(int *)0 = 0; *(int *)0 = 0;
} }
__except(CrashPointers = *GetExceptionInformation(), __except(CrashPointers = *GetExceptionInformation(),
CreateCrashLog (__argv[1], 9, NULL), EXCEPTION_EXECUTE_HANDLER) CreateCrashLog ("TestCrash", 9, NULL), EXCEPTION_EXECUTE_HANDLER)
{ {
} }
DisplayCrashLog (); DisplayCrashLog ();
exit (0); exit (0);
} }
if (__argc == 2 && strcmp (__argv[1], "TestStackCrash") == 0) if (__argc == 2 && __wargv != nullptr && wcscmp (__wargv[1], L"TestStackCrash") == 0)
{ {
__try __try
{ {
infiniterecursion(1); infiniterecursion(1);
} }
__except(CrashPointers = *GetExceptionInformation(), __except(CrashPointers = *GetExceptionInformation(),
CreateCrashLog (__argv[1], 14, NULL), EXCEPTION_EXECUTE_HANDLER) CreateCrashLog ("TestStackCrash", 14, NULL), EXCEPTION_EXECUTE_HANDLER)
{ {
} }
DisplayCrashLog (); DisplayCrashLog ();

View file

@ -20,15 +20,6 @@
#define IDB_BITMAP1 131 #define IDB_BITMAP1 131
#define IDB_DEADGUY 131 #define IDB_DEADGUY 131
#define IDD_CRASHDETAILS 133 #define IDD_CRASHDETAILS 133
#define IDI_BOING1 137
#define IDI_BOING2 138
#define IDI_BOING3 139
#define IDI_BOING4 140
#define IDI_BOING5 141
#define IDI_BOING6 142
#define IDI_BOING7 143
#define IDI_BOING8 144
#define IDD_BOING 145
#define IDD_CRASHOVERVIEW 147 #define IDD_CRASHOVERVIEW 147
#define IDD_ERRORPANE 148 #define IDD_ERRORPANE 148
#define IDD_NETSTARTPANE 149 #define IDD_NETSTARTPANE 149
@ -83,7 +74,6 @@
#define IDC_BUTTON2 1062 #define IDC_BUTTON2 1062
#define IDC_CRASHDETAILS 1062 #define IDC_CRASHDETAILS 1062
#define IDC_DEADGUYVIEWER 1063 #define IDC_DEADGUYVIEWER 1063
#define IDC_BOING 1065
#define IDC_CRASHFILESIZE 1066 #define IDC_CRASHFILESIZE 1066
#define IDC_BUTTON1 1071 #define IDC_BUTTON1 1071
#define IDC_BOINGSTATUS 1072 #define IDC_BOINGSTATUS 1072