mirror of
https://bitbucket.org/CPMADevs/cnq3
synced 2025-01-22 00:11:20 +00:00
restoring desktop settings and minimizing the window when crashing
making sure the crash message box is always visible
This commit is contained in:
parent
c1c9031f13
commit
1ef18feab5
1 changed files with 47 additions and 3 deletions
|
@ -2,6 +2,7 @@
|
|||
#include "../qcommon/qcommon.h"
|
||||
#include "../qcommon/crash.h"
|
||||
#include "win_local.h"
|
||||
#include "glw_win.h"
|
||||
#include <DbgHelp.h>
|
||||
#include <strsafe.h>
|
||||
|
||||
|
@ -249,6 +250,10 @@ static const char* WIN_GetAccessViolationCodeString( DWORD avCode )
|
|||
}
|
||||
}
|
||||
|
||||
// We save those separately because the handler might change related state before writing the report.
|
||||
static qbool wasDevModeValid = qfalse;
|
||||
static qbool wasMinimized = qfalse;
|
||||
|
||||
static void WIN_WriteTextData( const char* filePath, debug_help_t* debugHelp, EXCEPTION_RECORD* pExceptionRecord )
|
||||
{
|
||||
FILE* const file = fopen(filePath, "w");
|
||||
|
@ -273,6 +278,9 @@ static void WIN_WriteTextData( const char* filePath, debug_help_t* debugHelp, EX
|
|||
JSONW_StringValue("windows_version", "%d.%d.%d", osVersion[0], osVersion[1], osVersion[2]);
|
||||
}
|
||||
|
||||
JSONW_BooleanValue("device_mode_changed", wasDevModeValid);
|
||||
JSONW_BooleanValue("minimized", wasMinimized);
|
||||
|
||||
Crash_PrintToFile(__argv[0]);
|
||||
|
||||
JSONW_EndFile();
|
||||
|
@ -407,6 +415,23 @@ static qbool WIN_ShouldContinueSearch( DWORD exceptionCode )
|
|||
}
|
||||
}
|
||||
|
||||
// Debugging a full-screen app with a single screen is a horrendous experience.
|
||||
// With our custom handler, we can handle crashes by restoring the desktop settings
|
||||
// and hiding the main window before letting the debugger take over.
|
||||
// This will only help for crashes though, breakpoints will still be fucked up.
|
||||
// Work-around for breakpoints: use __debugbreak(); and don't launch the app through the debugger.
|
||||
static qbool WIN_WouldDebuggingBeOkay()
|
||||
{
|
||||
if (g_wv.monitorCount >= 2 || g_wv.hWnd == NULL)
|
||||
return qtrue;
|
||||
|
||||
const qbool fullScreen = (GetWindowLongA(g_wv.hWnd, GWL_STYLE) & WS_POPUP) != 0;
|
||||
if (!fullScreen)
|
||||
return qtrue;
|
||||
|
||||
return qfalse;
|
||||
}
|
||||
|
||||
//
|
||||
// The exception handler's job is to reset system settings that won't get reset
|
||||
// as part of the normal process clean-up by the OS.
|
||||
|
@ -440,15 +465,34 @@ LONG CALLBACK WIN_HandleException( EXCEPTION_POINTERS* ep )
|
|||
}
|
||||
|
||||
__try {
|
||||
WIN_EndTimePeriod();
|
||||
WIN_EndTimePeriod(); // system timer resolution
|
||||
} __except (EXCEPTION_EXECUTE_HANDLER) {}
|
||||
|
||||
if (IsDebuggerPresent() && WIN_WouldDebuggingBeOkay())
|
||||
return EXCEPTION_CONTINUE_SEARCH;
|
||||
|
||||
__try {
|
||||
wasDevModeValid = glw_state.cdsDevModeValid;
|
||||
if (glw_state.cdsDevModeValid)
|
||||
WIN_SetDesktopDisplaySettings();
|
||||
} __except (EXCEPTION_EXECUTE_HANDLER) {}
|
||||
|
||||
if (g_wv.hWnd != NULL) {
|
||||
__try {
|
||||
wasMinimized = (qbool)!!IsIconic(g_wv.hWnd);
|
||||
} __except(EXCEPTION_EXECUTE_HANDLER) {}
|
||||
|
||||
__try {
|
||||
ShowWindow(g_wv.hWnd, SW_MINIMIZE);
|
||||
} __except(EXCEPTION_EXECUTE_HANDLER) {}
|
||||
}
|
||||
|
||||
if (exc_exitCalled || IsDebuggerPresent())
|
||||
return EXCEPTION_CONTINUE_SEARCH;
|
||||
|
||||
static const char* mbTitle = "CNQ3 Crash";
|
||||
static const char* mbMsg = "CNQ3 crashed!\n\nYes to generate a crash report\nNo to continue after attaching a debugger\nCancel to quit";
|
||||
const int result = MessageBoxA(NULL, mbMsg, mbTitle, MB_YESNOCANCEL | MB_ICONERROR);
|
||||
const int result = MessageBoxA(NULL, mbMsg, mbTitle, MB_YESNOCANCEL | MB_ICONERROR | MB_TOPMOST);
|
||||
if (result == IDYES) {
|
||||
WIN_WriteExceptionFiles(ep);
|
||||
if (exc_reportWritten)
|
||||
|
|
Loading…
Reference in a new issue