// 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);
 
 
 
      return (0); // as MSDN says
 
   }
 
 
 
   // else did we click the close button on the title bar ?
 
   else if (message == WM_CLOSE)
 
   {
 
      DestroyWindow (hWnd); // close the window
 
      return (0); // as MSDN says
 
   }
 
 
 
   // 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
 
      the_board.reevaluate = true; // refresh the GUI buttons if needed
 
      return (0); // as MSDN says
 
   }
 
 
 
   // 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);
 
 
 
      return (0); // as MSDN says
 
   }
 
 
 
   // 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;
 
 
 
      return (0); // as MSDN says
 
   }
 
 
 
   // 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
 
 
 
      return (0); // as MSDN says
 
   }
 
 
 
   // call the default window message processing function to keep things going
 
   return (DefWindowProc (hWnd, message, wParam, lParam));
 
}