mirror of
https://github.com/ZDoom/Raze.git
synced 2025-01-09 18:40:48 +00:00
190 lines
4.8 KiB
C++
190 lines
4.8 KiB
C++
|
|
#include "i_mainwindow.h"
|
|
#include "resource.h"
|
|
#include "startupinfo.h"
|
|
#include "gstrings.h"
|
|
#include "palentry.h"
|
|
#include "st_start.h"
|
|
#include "i_input.h"
|
|
#include "version.h"
|
|
#include "utf8.h"
|
|
#include "v_font.h"
|
|
#include "i_net.h"
|
|
#include "engineerrors.h"
|
|
#include "common/widgets/errorwindow.h"
|
|
#include "common/widgets/netstartwindow.h"
|
|
#include <richedit.h>
|
|
#include <shellapi.h>
|
|
#include <commctrl.h>
|
|
#include <dwmapi.h>
|
|
|
|
#pragma comment(lib, "dwmapi.lib")
|
|
|
|
MainWindow mainwindow;
|
|
|
|
void MainWindow::Create(const FString& caption, int x, int y, int width, int height)
|
|
{
|
|
static const WCHAR WinClassName[] = L"MainWindow";
|
|
|
|
HINSTANCE hInstance = GetModuleHandle(0);
|
|
|
|
WNDCLASS WndClass;
|
|
WndClass.style = 0;
|
|
WndClass.lpfnWndProc = LConProc;
|
|
WndClass.cbClsExtra = 0;
|
|
WndClass.cbWndExtra = 0;
|
|
WndClass.hInstance = hInstance;
|
|
WndClass.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_ICON1));
|
|
WndClass.hCursor = LoadCursor(NULL, IDC_ARROW);
|
|
WndClass.hbrBackground = CreateSolidBrush(RGB(0,0,0));
|
|
WndClass.lpszMenuName = NULL;
|
|
WndClass.lpszClassName = WinClassName;
|
|
|
|
/* register this new class with Windows */
|
|
if (!RegisterClass((LPWNDCLASS)&WndClass))
|
|
{
|
|
MessageBoxA(nullptr, "Could not register window class", "Fatal", MB_ICONEXCLAMATION | MB_OK);
|
|
exit(-1);
|
|
}
|
|
|
|
std::wstring wcaption = caption.WideString();
|
|
Window = CreateWindowExW(
|
|
WS_EX_APPWINDOW,
|
|
WinClassName,
|
|
wcaption.c_str(),
|
|
WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN,
|
|
x, y, width, height,
|
|
(HWND)NULL,
|
|
(HMENU)NULL,
|
|
hInstance,
|
|
NULL);
|
|
|
|
if (!Window)
|
|
{
|
|
MessageBoxA(nullptr, "Unable to create main window", "Fatal", MB_ICONEXCLAMATION | MB_OK);
|
|
exit(-1);
|
|
}
|
|
|
|
uint32_t bordercolor = RGB(51, 51, 51);
|
|
uint32_t captioncolor = RGB(33, 33, 33);
|
|
uint32_t textcolor = RGB(226, 223, 219);
|
|
|
|
// Don't error check these as they only exist on Windows 11, and if they fail then that is OK.
|
|
DwmSetWindowAttribute(Window, 34/*DWMWA_BORDER_COLOR*/, &bordercolor, sizeof(uint32_t));
|
|
DwmSetWindowAttribute(Window, 35/*DWMWA_CAPTION_COLOR*/, &captioncolor, sizeof(uint32_t));
|
|
DwmSetWindowAttribute(Window, 36/*DWMWA_TEXT_COLOR*/, &textcolor, sizeof(uint32_t));
|
|
}
|
|
|
|
// Sets the main WndProc, hides all the child windows, and starts up in-game input.
|
|
void MainWindow::ShowGameView()
|
|
{
|
|
if (GetWindowLongPtr(Window, GWLP_USERDATA) == 0)
|
|
{
|
|
SetWindowLongPtr(Window, GWLP_USERDATA, 1);
|
|
SetWindowLongPtr(Window, GWLP_WNDPROC, (LONG_PTR)WndProc);
|
|
I_InitInput(Window);
|
|
}
|
|
}
|
|
|
|
// Returns the main window to its startup state.
|
|
void MainWindow::RestoreConView()
|
|
{
|
|
I_ShutdownInput(); // Make sure the mouse pointer is available.
|
|
ShowWindow(Window, SW_HIDE);
|
|
|
|
// Make sure the progress bar isn't visible.
|
|
DeleteStartupScreen();
|
|
}
|
|
|
|
// Shows an error message, preferably in the main window, but it can use a normal message box too.
|
|
void MainWindow::ShowErrorPane(const char* text)
|
|
{
|
|
if (StartWindow) // Ensure that the network pane is hidden.
|
|
{
|
|
I_NetDone();
|
|
}
|
|
|
|
// PrintStr(text);
|
|
|
|
size_t totalsize = 0;
|
|
for (const FString& line : bufferedConsoleStuff)
|
|
totalsize += line.Len();
|
|
|
|
std::string alltext;
|
|
alltext.reserve(totalsize);
|
|
for (const FString& line : bufferedConsoleStuff)
|
|
alltext.append(line.GetChars(), line.Len());
|
|
|
|
restartrequest = ErrorWindow::ExecModal(text, alltext);
|
|
}
|
|
|
|
void MainWindow::ShowNetStartPane(const char* message, int maxpos)
|
|
{
|
|
NetStartWindow::ShowNetStartPane(message, maxpos);
|
|
}
|
|
|
|
void MainWindow::HideNetStartPane()
|
|
{
|
|
NetStartWindow::HideNetStartPane();
|
|
}
|
|
|
|
void MainWindow::SetNetStartProgress(int pos)
|
|
{
|
|
NetStartWindow::SetNetStartProgress(pos);
|
|
}
|
|
|
|
bool MainWindow::RunMessageLoop(bool (*timer_callback)(void*), void* userdata)
|
|
{
|
|
return NetStartWindow::RunMessageLoop(timer_callback, userdata);
|
|
}
|
|
|
|
bool MainWindow::CheckForRestart()
|
|
{
|
|
bool result = restartrequest;
|
|
restartrequest = false;
|
|
return result;
|
|
}
|
|
|
|
// The main window's WndProc during startup. During gameplay, the WndProc in i_input.cpp is used instead.
|
|
LRESULT MainWindow::LConProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
|
|
{
|
|
return DefWindowProc(hWnd, msg, wParam, lParam);
|
|
}
|
|
|
|
void MainWindow::PrintStr(const char* cp)
|
|
{
|
|
bufferedConsoleStuff.Push(cp);
|
|
}
|
|
|
|
void MainWindow::GetLog(std::function<bool(const void* data, uint32_t size, uint32_t& written)> writeData)
|
|
{
|
|
for (const FString& line : bufferedConsoleStuff)
|
|
{
|
|
size_t pos = 0;
|
|
size_t len = line.Len();
|
|
while (pos < len)
|
|
{
|
|
uint32_t size = (uint32_t)std::min(len - pos, 0x0fffffffULL);
|
|
uint32_t written = 0;
|
|
if (!writeData(&line[pos], size, written))
|
|
return;
|
|
pos += written;
|
|
}
|
|
}
|
|
}
|
|
|
|
// each platform has its own specific version of this function.
|
|
void MainWindow::SetWindowTitle(const char* caption)
|
|
{
|
|
std::wstring widecaption;
|
|
if (!caption)
|
|
{
|
|
FStringf default_caption("" GAMENAME " %s (%s)", GetVersionString(), GetGitTime());
|
|
widecaption = default_caption.WideString();
|
|
}
|
|
else
|
|
{
|
|
widecaption = WideString(caption);
|
|
}
|
|
SetWindowText(Window, widecaption.c_str());
|
|
}
|