forked from Mirrors/openclonk
172 lines
5.4 KiB
C++
172 lines
5.4 KiB
C++
/*
|
|
* OpenClonk, http://www.openclonk.org
|
|
*
|
|
* Copyright (c) 2012-2016, The OpenClonk Team and contributors
|
|
*
|
|
* Distributed under the terms of the ISC license; see accompanying file
|
|
* "COPYING" for details.
|
|
*
|
|
* "Clonk" is a registered trademark of Matthes Bender, used with permission.
|
|
* See accompanying file "TRADEMARK" for details.
|
|
*
|
|
* To redistribute this file separately, substitute the full license texts
|
|
* for the above references.
|
|
*/
|
|
|
|
/* Functions for displaying a settings dialogue to users when the graphics system failed */
|
|
|
|
#include "C4Include.h"
|
|
|
|
#ifdef _WIN32
|
|
|
|
#include "res/resource.h"
|
|
#include "C4Version.h"
|
|
#include "game/C4Application.h"
|
|
#include "platform/C4windowswrapper.h"
|
|
#include "gui/C4GfxErrorDlg.h"
|
|
|
|
#include "graphics/C4Draw.h"
|
|
|
|
static int edittext_toi(HWND hWnd, int field)
|
|
{
|
|
WCHAR buf[512]; buf[511] = 0;
|
|
GetDlgItemTextW(hWnd,field,buf,509);
|
|
StdStrBuf data(buf);
|
|
const char* bufp = data.getData();
|
|
while(*bufp == ' ') ++bufp;
|
|
int res = strtol(bufp, nullptr, 0);
|
|
if(errno != ERANGE)
|
|
return res;
|
|
return -1;
|
|
}
|
|
|
|
static INT_PTR CALLBACK GfxErrProcedure(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)
|
|
{
|
|
switch(Msg)
|
|
{
|
|
case WM_INITDIALOG:
|
|
// Set Icon, Caption and static Texts
|
|
SendMessage(hWnd,WM_SETICON,ICON_BIG,(LPARAM)LoadIcon(Application.GetInstance(),MAKEINTRESOURCE(IDI_00_C4X)));
|
|
SendMessage(hWnd,WM_SETICON,ICON_SMALL,(LPARAM)LoadIcon(Application.GetInstance(),MAKEINTRESOURCE(IDI_00_C4X)));
|
|
SetWindowTextW(hWnd, GetWideChar(C4ENGINECAPTION));
|
|
SetDlgItemTextW(hWnd,IDC_GFXERR_MSG ,GetWideChar(LoadResStr("IDS_MSG_GFXERR_TXT")));
|
|
SetDlgItemTextW(hWnd,IDC_GFXERR_RES ,GetWideChar(LoadResStr("IDS_CTL_RESOLUTION")));
|
|
SetDlgItemTextW(hWnd,IDC_GFXERR_FSCRN,GetWideChar(LoadResStr("IDS_MSG_FULLSCREEN")));
|
|
SetDlgItemTextW(hWnd,IDCANCEL ,GetWideChar(LoadResStr("IDS_DLG_EXIT")));
|
|
SetDlgItemTextW(hWnd,IDOK ,GetWideChar(LoadResStr("IDS_BTN_RESTART")));
|
|
// Set Options
|
|
SendMessage(GetDlgItem(hWnd, IDC_GFXERR_FSCRN), BM_SETCHECK, Config.Graphics.Windowed?0:1, 0);
|
|
SetDlgItemTextW(hWnd,IDC_GFXERR_XINP ,FormatString("%d",Config.Graphics.ResX).GetWideChar());
|
|
SetDlgItemTextW(hWnd,IDC_GFXERR_YINP ,FormatString("%d",Config.Graphics.ResY).GetWideChar());
|
|
return TRUE;
|
|
|
|
case WM_DESTROY:
|
|
EndDialog(hWnd,1);
|
|
return TRUE;
|
|
|
|
case WM_COMMAND:
|
|
{
|
|
switch(LOWORD(wParam))
|
|
{
|
|
case IDCANCEL:
|
|
EndDialog(hWnd,1);
|
|
return TRUE;
|
|
case IDC_GFXERR_FSCRN:
|
|
case IDC_GFXERR_XINP:
|
|
case IDC_GFXERR_YINP:
|
|
{ // Handle Resolution values
|
|
if(SendMessage(GetDlgItem(hWnd, IDC_GFXERR_FSCRN),BM_GETCHECK,0,0) == BST_CHECKED)
|
|
{
|
|
int resx = edittext_toi(hWnd,IDC_GFXERR_XINP);
|
|
int resy = edittext_toi(hWnd,IDC_GFXERR_YINP);
|
|
if(resx < 1 || resy < 1) // res. will be 0 if the user supplies an invalid value
|
|
SetDlgItemTextW(hWnd,IDC_GFXERR_INVAL,GetWideChar(LoadResStr("IDS_MSG_GFXERR_RESINVAL")));
|
|
else
|
|
{
|
|
// Check if res is in list of supportet
|
|
bool found = false;
|
|
int32_t idx = 0, iXRes, iYRes, iBitDepth;
|
|
while (Application.GetIndexedDisplayMode(idx++, &iXRes, &iYRes, &iBitDepth, nullptr, Config.Graphics.Monitor))
|
|
if (iBitDepth == C4Draw::COLOR_DEPTH)
|
|
if(iXRes == resx && iYRes == resy)
|
|
{
|
|
found = true;
|
|
break;
|
|
}
|
|
SetDlgItemTextW(hWnd,IDC_GFXERR_INVAL,found?L"":GetWideChar(LoadResStr("IDS_MSG_GFXERR_RESNOTFOUND")));
|
|
}
|
|
}
|
|
else
|
|
SetDlgItemTextW(hWnd,IDC_GFXERR_INVAL,L"");
|
|
return TRUE;
|
|
}
|
|
case IDOK:
|
|
{
|
|
int resx = edittext_toi(hWnd,IDC_GFXERR_XINP);
|
|
int resy = edittext_toi(hWnd,IDC_GFXERR_YINP);
|
|
if(resx < 1 || resy < 1) break;
|
|
Config.Graphics.Windowed = !(SendMessage(GetDlgItem(hWnd, IDC_GFXERR_FSCRN),BM_GETCHECK,0,0) == BST_CHECKED);
|
|
Config.Graphics.ResX = resx;
|
|
Config.Graphics.ResY = resy;
|
|
Config.Save();
|
|
TCHAR selfpath[4096];
|
|
GetModuleFileName(nullptr, selfpath, 4096);
|
|
STARTUPINFOW siStartupInfo;
|
|
PROCESS_INFORMATION piProcessInfo;
|
|
memset(&siStartupInfo, 0, sizeof(siStartupInfo));
|
|
memset(&piProcessInfo, 0, sizeof(piProcessInfo));
|
|
siStartupInfo.cb = sizeof(siStartupInfo);
|
|
if (CreateProcessW(selfpath, nullptr,
|
|
nullptr, nullptr, FALSE, 0, nullptr, Config.General.ExePath.GetWideChar(), &siStartupInfo, &piProcessInfo))
|
|
{
|
|
CloseHandle(piProcessInfo.hProcess);
|
|
CloseHandle(piProcessInfo.hThread);
|
|
}
|
|
EndDialog(hWnd,2);
|
|
return TRUE;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return FALSE;
|
|
}
|
|
|
|
void ShowGfxErrorDialog()
|
|
{
|
|
// Application.Close will eventually post a quit message. We need to discard
|
|
// that, so DialogBox() doesn't immediately exit.
|
|
auto msg = MSG();
|
|
while (PeekMessage(&msg, nullptr, 0, 0, PM_REMOVE) != 0)
|
|
{
|
|
if (msg.message == WM_QUIT) break;
|
|
TranslateMessage(&msg);
|
|
DispatchMessage(&msg);
|
|
}
|
|
|
|
int ret = DialogBox(Application.GetInstance(), MAKEINTRESOURCE(IDD_GFXERROR), nullptr, GfxErrProcedure);
|
|
if (ret == 0 || ret == -1)
|
|
{
|
|
LPVOID lpMsgBuf;
|
|
DWORD err = GetLastError();
|
|
FormatMessage(
|
|
FORMAT_MESSAGE_ALLOCATE_BUFFER |
|
|
FORMAT_MESSAGE_FROM_SYSTEM |
|
|
FORMAT_MESSAGE_IGNORE_INSERTS,
|
|
nullptr,
|
|
err,
|
|
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
|
|
(LPTSTR) &lpMsgBuf,
|
|
0, nullptr );
|
|
LogF("Error in GfxErrorDlg: %d - %s", err, StdStrBuf((wchar_t*)lpMsgBuf).getData());
|
|
LocalFree(lpMsgBuf);
|
|
}
|
|
|
|
// If we discarded a quit message, re-post it now
|
|
if (msg.message == WM_QUIT)
|
|
PostQuitMessage(msg.wParam);
|
|
}
|
|
|
|
#else
|
|
void ShowGfxErrorDialog(){} // To be implemented? It's mainly a windows (users') problem.
|
|
#endif
|