// window_motd.cpp
#include "../common.h"
// window parameters
#define WINDOW_CLASSNAME PROGRAM_NAME L" MOTD WndClass"
#define WINDOW_DEFAULT_WIDTH 720
#define WINDOW_DEFAULT_HEIGHT 600
#define WINDOW_MIN_WIDTH 320
#define WINDOW_MIN_HEIGHT 240
// local definitions
#define WINDOW_EDITBOX_MOTD 1
#define WINDOW_CHECKBOX_SHOWMOTD 2
#define WINDOW_TEXT_STATUSBAR 3
// global variables
static bool is_classregistered = false;
//static HWND hThisWnd = NULL;
#define hThisWnd hMOTDWnd // shared variable
// prototypes of local functions
static LRESULT CALLBACK WindowProc_ThisWindow (HWND hWnd, unsigned int message, WPARAM wParam, LPARAM lParam);
void Window_MOTD (void)
{
// helper function to fire up the child window
WNDCLASSEX wc;
// is the window we want to display already displayed ?
if (IsWindow (hThisWnd))
SetForegroundWindow (hThisWnd); // if so, just bring it to front
// else the way is clear
else
{
// is the window class NOT registered yet ?
if (!is_classregistered)
{
// if so, register the window class once and for all
memset (&wc, 0, sizeof (wc));
wc.cbSize = sizeof (wc);
wc.style = CS_HREDRAW | CS_VREDRAW;
wc.lpfnWndProc = WindowProc_ThisWindow;
wc.hInstance = hAppInstance;
wc.hIcon = LoadIcon (hAppInstance, (wchar_t *) ICON_MAIN);
wc.hCursor = LoadCursor (NULL, IDC_ARROW);
wc.hbrBackground = GetSysColorBrush (COLOR_3DFACE);
wc.lpszClassName = WINDOW_CLASSNAME;
RegisterClassEx (&wc);
is_classregistered = true; // remember this window class is registered
}
// create the child window
hThisWnd = CreateWindowEx (WS_EX_CLIENTEDGE, WINDOW_CLASSNAME, LOCALIZE (L"MOTD_Title"), WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, CW_USEDEFAULT, WINDOW_DEFAULT_WIDTH, WINDOW_DEFAULT_HEIGHT,
NULL, NULL, hAppInstance, NULL);
}
return; // return as soon as the thread is fired up
}
void Window_MOTD_Validated (void)
{
// callback function called by the main game thread when the window is validated
// remember this callback is no longer to be called
is_window_motd_validated = false;
return; // finished
}
static LRESULT CALLBACK WindowProc_ThisWindow (HWND hWnd, unsigned int message, WPARAM wParam, LPARAM lParam)
{
// message handler for the child window
static const wchar_t rtf_template_begin[] = L"{\\rtf1\\ansi{\\fonttbl\\f0\\f{Lucida Console};}\\f0\\fs20\\pard\n";
static const wchar_t rtf_template_end[] = L"\\par\n}\n";
static wchar_t line_buffer[256];
unsigned short wParam_hiword;
unsigned short wParam_loword;
MINMAXINFO *minmax;
RECT client_rect;
wchar_t *rtf_string; // mallocated
wchar_t *string_pointer;
int rtf_stringsize;
// filter out the commonly used message values
wParam_hiword = HIWORD (wParam);
wParam_loword = LOWORD (wParam);
// have we just fired up this window ?
if (message == WM_CREATE)
{
// center the window
CenterWindow (hWnd, hMainWnd);
// populate the window
LoadLibrary (L"riched32.dll"); // ensure the RichEdit controls DLL is loaded
CreateWindowEx (0, L"RichEdit20A", L"", // for some reason, only the ANSI version of this control accepts RTF data :(
WS_CHILD | WS_VISIBLE | WS_VSCROLL | WS_HSCROLL | ES_MULTILINE | ES_AUTOVSCROLL | ES_AUTOHSCROLL | ES_READONLY | ES_SELECTIONBAR | ES_SUNKEN,
0, 0, 0, 0, hWnd, (HMENU) WINDOW_EDITBOX_MOTD, hAppInstance, NULL);
CreateWindowEx (0, L"button", L"",
BS_AUTOCHECKBOX | WS_CHILD | WS_VISIBLE,
0, 0, 0, 0, hWnd, (HMENU) WINDOW_CHECKBOX_SHOWMOTD, hAppInstance, NULL);
CreateWindowEx (WS_EX_RIGHT, L"static", L"",
WS_CHILD | WS_VISIBLE,
0, 0, 0, 0, hWnd, (HMENU) WINDOW_TEXT_STATUSBAR, hAppInstance, NULL);
// set the MOTD text
rtf_stringsize = wcslen (rtf_template_begin) + 2 * wcslen (server_motd) + wcslen (rtf_template_end) + 1;
rtf_string = (wchar_t *) SAFE_malloc (rtf_stringsize, sizeof (wchar_t), false);
wcscpy_s (rtf_string, rtf_stringsize, rtf_template_begin);
string_pointer = server_motd; // start reading MOTD line per line
while ((string_pointer = wcsgets (line_buffer, WCHAR_SIZEOF (line_buffer), string_pointer)) != NULL)
{
wcscat_s (line_buffer, WCHAR_SIZEOF (line_buffer), L"\\line\n"); // append a RTF linebreak to each line
wcscat_s (rtf_string, rtf_stringsize, line_buffer); // and append each line to the translated MOTD buffer
}
wcscat_s (rtf_string, rtf_stringsize, rtf_template_end);
SendMessage (GetDlgItem (hWnd, WINDOW_EDITBOX_MOTD), EM_SETBKGNDCOLOR, 0, RGB (224, 224, 224));
SetWindowText (GetDlgItem (hWnd, WINDOW_EDITBOX_MOTD), rtf_string);
SAFE_free ((void **) &rtf_string);
// associate the default GUI font with the check box, set its text and check/uncheck it if needed
SendMessage (GetDlgItem (hWnd, WINDOW_CHECKBOX_SHOWMOTD), WM_SETFONT, (WPARAM) GetStockObject (DEFAULT_GUI_FONT), false);
SetWindowText (GetDlgItem (hWnd, WINDOW_CHECKBOX_SHOWMOTD), LOCALIZE (L"MOTD_ShowMOTD"));
Button_SetCheck (GetDlgItem (hWnd, WINDOW_CHECKBOX_SHOWMOTD), (options.network.want_motdonconnect ? BST_CHECKED : BST_UNCHECKED));
// associate the default GUI font with the status bar and set its text
SendMessage (GetDlgItem (hWnd, WINDOW_TEXT_STATUSBAR), WM_SETFONT, (WPARAM) GetStockObject (DEFAULT_GUI_FONT), false);
SetWindowText (GetDlgItem (hWnd, WINDOW_TEXT_STATUSBAR), LOCALIZE (L"MOTD_StatusBar"));
// convert the status bar message to a hyperlink
ConvertStaticToHyperlink (GetDlgItem (hWnd, WINDOW_TEXT_STATUSBAR));
// now show the window
ShowWindow (hWnd, SW_SHOW);
}
// else did we click the close button on the title bar ?
else if (message == WM_CLOSE)
DestroyWindow (hWnd); // destroy this window
// else are we destroying this window ?
else if (message == WM_DESTROY)
{
hThisWnd = NULL; // window is closed
SetForegroundWindow (hMainWnd); // restore focus on the main window
is_window_motd_validated = true; // remember we closed this window
}
// else are we resizing the window ?
else if (message == WM_SIZE)
{
// get the new window size
GetClientRect (hWnd, &client_rect);
// position the window elements
SetWindowPos (GetDlgItem (hWnd, WINDOW_EDITBOX_MOTD), NULL, 16, 16, client_rect.right - 32, client_rect.bottom - 64, SWP_NOZORDER);
SetWindowPos (GetDlgItem (hWnd, WINDOW_CHECKBOX_SHOWMOTD), NULL, 16, client_rect.bottom - 32, client_rect.right - 32, 16, SWP_NOZORDER);
SetWindowPos (GetDlgItem (hWnd, WINDOW_TEXT_STATUSBAR), NULL, 0, client_rect.bottom - 16, client_rect.right, 16, SWP_NOZORDER);
}
// else are we asking how big/small we can resize ?
else if (message == WM_GETMINMAXINFO)
{
minmax = (MINMAXINFO *) lParam; // get a pointer to the min/max info structure
minmax->ptMinTrackSize.x = WINDOW_MIN_WIDTH;
minmax->ptMinTrackSize.y = WINDOW_MIN_HEIGHT;
}
// else did we take action on one of the controls ?
else if (message == WM_COMMAND)
{
// was it the show MOTD checkbox ?
if (wParam_loword == WINDOW_CHECKBOX_SHOWMOTD)
options.network.want_motdonconnect = (Button_GetCheck (GetDlgItem (hWnd, WINDOW_CHECKBOX_SHOWMOTD)) != 0); // if so, update settings
// else was it the status bar hyperlink ?
else if (wParam_loword == WINDOW_TEXT_STATUSBAR)
ShellExecute (NULL, L"open", PROGRAM_URL, NULL, NULL, SW_MAXIMIZE); // open the donation page in the default browser, maximized
}
// call the default window message processing function to keep things going
return (DefWindowProc (hWnd, message, wParam, lParam));
}