Browse Source

Hack around hidden/dead MessageBoxes :(

So, it appears that once our dialog is created, the DialogBox windowproc
is nuked. So, to hack around this, any errors that occur while it is open
are cached and reported out after we close everything down. It sucks, but
it works. I blame Microsoft.
Adam Johnson 11 years ago
parent
commit
4ae685aff9
  1. 39
      Sources/Plasma/Apps/plUruLauncher/winmain.cpp

39
Sources/Plasma/Apps/plUruLauncher/winmain.cpp

@ -61,6 +61,7 @@ Mead, WA 99021
#define PLASMA_OK 0 #define PLASMA_OK 0
static HWND s_dialog; static HWND s_dialog;
static plString s_error; // This is highly unfortunate.
static plClientLauncher s_launcher; static plClientLauncher s_launcher;
static UINT s_taskbarCreated = RegisterWindowMessageW(L"TaskbarButtonCreated"); static UINT s_taskbarCreated = RegisterWindowMessageW(L"TaskbarButtonCreated");
static ITaskbarList3* s_taskbar = nullptr; static ITaskbarList3* s_taskbar = nullptr;
@ -87,6 +88,12 @@ static void WaitForOldPatcher()
// =================================================== // ===================================================
static inline void IShowErrorDialog(const wchar_t* msg)
{
// This bypasses all that hsClientMinimizeGuard crap we have in CoreLib.
MessageBoxW(nullptr, msg, L"Error", MB_ICONERROR | MB_OK);
}
static inline void IQuit(int exitCode=PLASMA_OK) static inline void IQuit(int exitCode=PLASMA_OK)
{ {
// hey, guess what? // hey, guess what?
@ -127,6 +134,7 @@ BOOL CALLBACK PatcherDialogProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM l
if (s_taskbar) if (s_taskbar)
s_taskbar->Release(); s_taskbar->Release();
PostQuitMessage(PLASMA_OK); PostQuitMessage(PLASMA_OK);
s_dialog = nullptr;
break; break;
case WM_NCHITTEST: case WM_NCHITTEST:
SetWindowLongW(hwndDlg, DWL_MSGRESULT, (LONG_PTR)HTCAPTION); SetWindowLongW(hwndDlg, DWL_MSGRESULT, (LONG_PTR)HTCAPTION);
@ -135,11 +143,9 @@ BOOL CALLBACK PatcherDialogProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM l
s_launcher.ShutdownNetCore(); s_launcher.ShutdownNetCore();
DestroyWindow(hwndDlg); DestroyWindow(hwndDlg);
break; break;
default:
return DefWindowProcW(hwndDlg, uMsg, wParam, lParam);
} }
return TRUE; return DefWindowProcW(hwndDlg, uMsg, wParam, lParam);
} }
static void ShowPatcherDialog(HINSTANCE hInstance) static void ShowPatcherDialog(HINSTANCE hInstance)
@ -265,17 +271,18 @@ static HANDLE ICreateProcess(const plFileName& exe, const plString& args)
return info.hProcess; return info.hProcess;
} else { } else {
wchar_t buf[2048]; wchar_t* msg = nullptr;
FormatMessageW( FormatMessageW(
FORMAT_MESSAGE_FROM_SYSTEM, FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
nullptr, nullptr,
GetLastError(), GetLastError(),
LANG_USER_DEFAULT, LANG_USER_DEFAULT,
buf, msg,
arrsize(buf), 0,
nullptr nullptr
); );
hsMessageBox(buf, L"Error", hsMessageBoxNormal, hsMessageBoxIconError); s_error = plString::FromWchar(msg);
LocalFree(msg);
} }
return nullptr; return nullptr;
@ -341,8 +348,7 @@ static void IOnNetError(ENetError result, const plString& msg)
if (s_taskbar) if (s_taskbar)
s_taskbar->SetProgressState(s_dialog, TBPF_ERROR); s_taskbar->SetProgressState(s_dialog, TBPF_ERROR);
plString text = plString::Format("Error: %S\r\n%s", NetErrorAsString(result), msg.c_str()); s_error = plString::Format("Error: %S\r\n%s", NetErrorAsString(result), msg.c_str());
hsMessageBox(text.c_str(), "Error", hsMessageBoxNormal);
IQuit(PLASMA_PHAILURE); IQuit(PLASMA_PHAILURE);
} }
@ -380,14 +386,14 @@ int __stdcall WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdL
// Load the doggone server.ini // Load the doggone server.ini
if (!s_launcher.LoadServerIni()) { if (!s_launcher.LoadServerIni()) {
hsMessageBox("No server.ini file found. Please check your URU installation.", "Error", hsMessageBoxNormal); IShowErrorDialog(L"No server.ini file found. Please check your URU installation.");
return PLASMA_PHAILURE; return PLASMA_PHAILURE;
} }
// Ensure there is only ever one patcher running... // Ensure there is only ever one patcher running...
if (IsPatcherRunning()) { if (IsPatcherRunning()) {
hsMessageBox(plString::Format("%s is already running", plProduct::LongName().c_str()).c_str(), "Error", plString text = plString::Format("%s is already running", plProduct::LongName().c_str());
hsMessageBoxNormal, hsMessageBoxIconError); IShowErrorDialog(text.ToWchar());
return PLASMA_OK; return PLASMA_OK;
} }
HANDLE _onePatcherMut = CreatePatcherMutex(); HANDLE _onePatcherMut = CreatePatcherMutex();
@ -400,6 +406,11 @@ int __stdcall WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdL
ShowPatcherDialog(hInstance); ShowPatcherDialog(hInstance);
PumpMessages(); PumpMessages();
// So there appears to be some sort of issue with calling MessageBox once we've set up our dialog...
// WTF?!?! So, to hack around that, we'll wait until everything shuts down to display any error.
if (!s_error.IsEmpty())
IShowErrorDialog(s_error.ToWchar());
// Alrighty now we just need to clean up behind ourselves! // Alrighty now we just need to clean up behind ourselves!
// NOTE: We shut down the netcore in the WM_QUIT handler so // NOTE: We shut down the netcore in the WM_QUIT handler so
// we don't have a windowless, zombie process if that takes // we don't have a windowless, zombie process if that takes
@ -408,7 +419,7 @@ int __stdcall WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdL
CloseHandle(_onePatcherMut); CloseHandle(_onePatcherMut);
// kthxbai // kthxbai
return PLASMA_OK; return s_error.IsEmpty() ? PLASMA_OK : PLASMA_PHAILURE;
} }
/* Enable themes in Windows XP and later */ /* Enable themes in Windows XP and later */

Loading…
Cancel
Save