- // window_chat.cpp 
-   
- #include "../common.h" 
-   
- // WARNING: OLE-enabled RichEdit control needs a C++ compiler! 
- #include <richole.h> 
-   
-   
- // window parameters 
- #define WINDOW_CLASSNAME PROGRAM_NAME L" Chat WndClass" 
- #define WINDOW_DEFAULT_WIDTH 520 
- #define WINDOW_DEFAULT_HEIGHT 400 
- #define WINDOW_MIN_WIDTH 480 
- #define WINDOW_MIN_HEIGHT 330 
-   
-   
- // local definitions 
- #define WINDOW_TEXT_QUESTION 1 
- #define WINDOW_EDITBOX_DISCUSSION 2 
- #define WINDOW_EDITBOX_MESSAGETOSEND 3 
- #define WINDOW_BITMAP_OPPONENTSTATUS 4 
- #define WINDOW_BUTTON_INVITE 5 
- #define WINDOW_BUTTON_PLAYERINFO 6 
- #define WINDOW_BUTTON_SEND 7 
- #define WINDOW_TEXT_STATUSBAR 8 
- #define WINDOW_TIMER_REFRESH 1 
-   
-   
- // RichEdit OLE callback interface structure definition 
- struct RichEditOLECallback : IRichEditOleCallback 
- { 
-    // this structure derives from the IRichEditOleCallback structure, which itself derives 
-    // from the IUnknown structure. So we define IN THIS VERY ORDER the members of the 
-    // IUnknown structure first, THEN the members of the IRichEditOleCallback structure, 
-    // THEN our own members. 
-   
-    // constructor/destructor 
-    RichEditOLECallback () { reference_count = 0; } 
-    ~RichEditOLECallback () { } 
-   
-    // members of the IUnknown structure 
-    ULONG CALLBACK AddRef (void) { reference_count++; return (reference_count); } 
-    ULONG CALLBACK Release (void) { reference_count--; return (reference_count); } 
-    HRESULT CALLBACK QueryInterface (REFIID iid, void **ppvObject) 
-    { 
-       if ((iid != IID_IUnknown) && (iid != IID_IRichEditOleCallback)) 
-          return (E_NOINTERFACE); 
-   
-       *ppvObject = this; 
-       reference_count++; 
-       return (S_OK); 
-    } 
-   
-    // members of the IRichEditOleCallback structure 
-    HRESULT CALLBACK ContextSensitiveHelp (BOOL fEnterMode) { return (E_NOTIMPL); } 
-    HRESULT CALLBACK DeleteObject (IOleObject *lpoleobj) { return (E_NOTIMPL); } 
-    HRESULT CALLBACK GetClipboardData (CHARRANGE *lpchrg, DWORD reco, IDataObject **lplpdataobj) { return (E_NOTIMPL); } 
-    HRESULT CALLBACK GetContextMenu (WORD seltype, IOleObject *lpoleobj, CHARRANGE *lpchrg, HMENU *lphmenu) { return (E_NOTIMPL); } 
-    HRESULT CALLBACK GetDragDropEffect (BOOL fDrag, DWORD grfKeyState, DWORD *pdwEffect) { return (E_NOTIMPL); } 
-    HRESULT CALLBACK GetInPlaceContext (IOleInPlaceFrame **lplpFrame, IOleInPlaceUIWindow **lplpDoc, tagOIFI *lpFrameInfo) { return (E_NOTIMPL); } 
-    HRESULT CALLBACK GetNewStorage (IStorage **storage) 
-    { 
-       // initialize a storage object in memory 
-   
-       ILockBytes *lock_bytes; 
-       HRESULT ret; 
-   
-       if ((ret = CreateILockBytesOnHGlobal (NULL, TRUE, &lock_bytes)) != S_OK) 
-          return (ret); 
-       if ((ret = StgCreateDocfileOnILockBytes (lock_bytes, STGM_CREATE | STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, storage)) != S_OK) 
-          lock_bytes->Release (); 
-       return (ret); 
-    } 
-    HRESULT CALLBACK QueryAcceptData (IDataObject *lpdataobj, CLIPFORMAT *lpcfFormat, DWORD reco, BOOL fReally, HANDLE hMetaPict) { return (E_NOTIMPL); } 
-    HRESULT CALLBACK QueryInsertObject (LPCLSID lpclsid, IStorage *storage, LONG cp) { return (S_OK); } 
-    HRESULT CALLBACK ShowContainerUI (BOOL fShow) { return (E_NOTIMPL); } 
-   
-    // our own data 
-    ULONG reference_count; 
- }; 
-   
-   
- // global variables used in this module only 
- static bool is_classregistered = false; 
- static PROC WindowProc_MessageToSend_DefaultProc; 
- static RichEditOLECallback *richedit_oleinterface = NULL; 
-   
-   
- // prototypes of local functions 
- static LRESULT CALLBACK WindowProc_ThisWindow (HWND hWnd, unsigned int message, WPARAM wParam, LPARAM lParam); 
- static LRESULT CALLBACK WindowProc_MessageToSend (HWND hDlg, unsigned int message, WPARAM wParam, LPARAM lParam); 
-   
-   
- void Window_Chat (int interlocutor_index) 
- { 
-    // helper function to fire up the child window 
-   
-    WNDCLASSEX wc; 
-    player_t *network_player; 
-   
-    // if the REOLECallback class instance hasn't been instantiated yet, do it 
-    if (richedit_oleinterface == NULL) 
-       richedit_oleinterface = new RichEditOLECallback; 
-   
-    network_player = Player_FindByType (PLAYER_INTERNET); // quick access to network player 
-    if (network_player == NULL) 
-       return; // consistency check 
-   
-    if (lastonlineplayers_time + 5.0f < current_time) 
-       Player_SendBuffer_Add (network_player, 1000, L"who\n"); // request a players list update 
-   
-    if (!interlocutors[interlocutor_index].is_active) 
-       return; // consistency check 
-   
-    // 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 window as an application-level window (not child) 
-    interlocutors[interlocutor_index].hWnd = CreateWindowEx (WS_EX_CLIENTEDGE, WINDOW_CLASSNAME, L"", WS_OVERLAPPEDWINDOW, 
-                                                             CW_USEDEFAULT, CW_USEDEFAULT, WINDOW_DEFAULT_WIDTH, WINDOW_DEFAULT_HEIGHT, 
-                                                             NULL, NULL, hAppInstance, NULL); 
-    interlocutors[interlocutor_index].update_dialog = true; // and update this interlocutor's dialog 
-   
-    return; // finished, the window is fired up 
- } 
-   
-   
- void Window_Chat_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_chat_validated = false; 
-   
-    return; // finished 
- } 
-   
-   
- static LRESULT CALLBACK WindowProc_ThisWindow (HWND hWnd, unsigned int message, WPARAM wParam, LPARAM lParam) 
- { 
-    // message handler for the child window 
-   
-    unsigned short wParam_hiword; 
-    unsigned short wParam_loword; 
-    wchar_t temp_string[256]; 
-    wchar_t *text_buffer; 
-    char *cstring_buffer; 
-    interlocutor_t *interlocutor; 
-    onlineplayer_t *onlineplayer; 
-    challenge_t *challenge; 
-    player_t *remote_player; 
-    player_t *local_player; 
-    MINMAXINFO *minmax; 
-    FLASHWINFO flashinfo; 
-    RECT client_rect; 
-    HWND hEditWnd; 
-    int display_picture; 
-    int player_index; 
-    int char_index; 
-    int length; 
-    bool is_invitable; 
-   
-    // 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 
-       CreateWindowEx (0, L"static", L"", 
-                       WS_CHILD | WS_VISIBLE, 
-                       0, 0, 0, 0, hWnd, (HMENU) WINDOW_TEXT_QUESTION, hAppInstance, NULL); 
-   
-       LoadLibrary (L"riched20.dll"); // ensure the RichEdit controls DLL is loaded 
-       hEditWnd = CreateWindowEx (0, L"RichEdit20A", L"", // for some reason, only the ANSI version of this control accepts RTF data :( 
-                                  WS_CHILD | WS_VISIBLE | WS_VSCROLL | ES_MULTILINE | ES_AUTOVSCROLL | ES_READONLY | ES_SELECTIONBAR | ES_SUNKEN,  
-                                  0, 0, 0, 0, hWnd, (HMENU) WINDOW_EDITBOX_DISCUSSION, hAppInstance, NULL); 
-       SendMessage (hEditWnd, EM_SETOLECALLBACK, 0, (LPARAM) richedit_oleinterface); 
-   
-       hEditWnd = CreateWindowEx (WS_EX_CLIENTEDGE, L"edit", L"",  
-                                  WS_CHILD | WS_VISIBLE | WS_VSCROLL | ES_MULTILINE | ES_AUTOVSCROLL,  
-                                  0, 0, 0, 0, hWnd, (HMENU) WINDOW_EDITBOX_MESSAGETOSEND, hAppInstance, NULL); 
-       WindowProc_MessageToSend_DefaultProc = (PROC) GetWindowLong (hEditWnd, GWL_WNDPROC); // save this edit box's window proc 
-       SetWindowLong (hEditWnd, GWL_WNDPROC, (long) WindowProc_MessageToSend); // replace this edit box's window proc by ours 
-   
-       CreateWindowEx (0, L"static", L"", 
-                       WS_CHILD | WS_VISIBLE | SS_BITMAP | SS_SUNKEN, 
-                       0, 0, 0, 0, hWnd, (HMENU) WINDOW_BITMAP_OPPONENTSTATUS, hAppInstance, NULL); 
-       CreateWindowEx (0, L"button", L"", 
-                       WS_CHILD | WS_VISIBLE | WS_DISABLED, // initially disabled 
-                       0, 0, 0, 0, hWnd, (HMENU) WINDOW_BUTTON_INVITE, hAppInstance, NULL); 
-       CreateWindowEx (0, L"button", L"", 
-                       WS_CHILD | WS_VISIBLE | WS_DISABLED, // initially disabled 
-                       0, 0, 0, 0, hWnd, (HMENU) WINDOW_BUTTON_PLAYERINFO, hAppInstance, NULL); 
-       CreateWindowEx (0, L"button", L"", 
-                       WS_CHILD | WS_VISIBLE | BS_DEFPUSHBUTTON, 
-                       0, 0, 0, 0, hWnd, (HMENU) WINDOW_BUTTON_SEND, 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 chat text font 
-       SendMessage (GetDlgItem (hWnd, WINDOW_EDITBOX_MESSAGETOSEND), WM_SETFONT, (WPARAM) hFontChat, false); 
-   
-       // associate the default GUI font with the leading caption 
-       SendMessage (GetDlgItem (hWnd, WINDOW_TEXT_QUESTION), WM_SETFONT, (WPARAM) GetStockObject (DEFAULT_GUI_FONT), false); 
-   
-       // associate the default GUI font with the invite button and set its text 
-       SendMessage (GetDlgItem (hWnd, WINDOW_BUTTON_INVITE), WM_SETFONT, (WPARAM) GetStockObject (DEFAULT_GUI_FONT), false); 
-       SetDlgItemText (hWnd, WINDOW_BUTTON_INVITE, LOCALIZE (L"Chat_Invite")); 
-   
-       // associate the default GUI font with the player info button and set its text 
-       SendMessage (GetDlgItem (hWnd, WINDOW_BUTTON_PLAYERINFO), WM_SETFONT, (WPARAM) GetStockObject (DEFAULT_GUI_FONT), false); 
-       SetDlgItemText (hWnd, WINDOW_BUTTON_PLAYERINFO, LOCALIZE (L"Chat_GetInfo")); 
-   
-       // associate the default GUI font with the send button and set its text 
-       SendMessage (GetDlgItem (hWnd, WINDOW_BUTTON_SEND), WM_SETFONT, (WPARAM) GetStockObject (DEFAULT_GUI_FONT), false); 
-       SetDlgItemText (hWnd, WINDOW_BUTTON_SEND, LOCALIZE (L"Button_Send")); 
-   
-       // 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); 
-       SetDlgItemText (hWnd, WINDOW_TEXT_STATUSBAR, LOCALIZE (L"Chat_StatusBar")); 
-   
-       // refresh the server message area every second 
-       SetTimer (hWnd, WINDOW_TIMER_REFRESH, 1000, NULL); 
-       SendMessage (hWnd, WM_TIMER, WINDOW_TIMER_REFRESH, 0); // but call it now 
-   
-       // 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); // close the window 
-   
-    // else are we destroying this window ? 
-    else if (message == WM_DESTROY) 
-    { 
-       KillTimer (hWnd, WINDOW_TIMER_REFRESH); // destroy the timer we used to refresh the dialog text 
-   
-       interlocutor = Interlocutor_FindByWindowHandle (hWnd); // find the interlocutor it is 
-       if (interlocutor != NULL) 
-          interlocutor->is_active = false; // remember interlocutor has gone away 
-   
-       is_window_chat_validated = true; 
-    } 
-   
-    // 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_TEXT_QUESTION), NULL, 16, 16, client_rect.right - 148, 16, SWP_NOZORDER); 
-       SetWindowPos (GetDlgItem (hWnd, WINDOW_EDITBOX_DISCUSSION), NULL, 16, 40, client_rect.right - 148, client_rect.bottom - 136, SWP_NOZORDER); 
-       SetWindowPos (GetDlgItem (hWnd, WINDOW_EDITBOX_MESSAGETOSEND), NULL, 16, client_rect.bottom - 80, client_rect.right - 148, 64, SWP_NOZORDER); 
-       SetWindowPos (GetDlgItem (hWnd, WINDOW_BITMAP_OPPONENTSTATUS), NULL, client_rect.right - 116, 16, 100, 100, SWP_NOZORDER); 
-       SetWindowPos (GetDlgItem (hWnd, WINDOW_BUTTON_INVITE), NULL, client_rect.right - 116, 124, 100, 32, SWP_NOZORDER); 
-       SetWindowPos (GetDlgItem (hWnd, WINDOW_BUTTON_PLAYERINFO), NULL, client_rect.right - 116, 162, 100, 32, SWP_NOZORDER); 
-       SetWindowPos (GetDlgItem (hWnd, WINDOW_BUTTON_SEND), NULL, client_rect.right - 116, client_rect.bottom - 80, 100, 64, 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 "invite" button ? 
-       if (wParam_loword == WINDOW_BUTTON_INVITE) 
-       { 
-          interlocutor = Interlocutor_FindByWindowHandle (hWnd); // find the interlocutor it is 
-          if (interlocutor != NULL) 
-          { 
-             // player is available for an invitation. Is he already inviting us ? 
-             challenge = Challenge_Find (interlocutor->nickname); 
-             if ((challenge != NULL) && challenge->is_active && IsWindow (challenge->hWnd)) 
-                EndDialog (challenge->hWnd, 0); // if so, close the challenge dialog box (this will also make us decline it properly) 
-   
-             DialogBox_SendChallenge (interlocutor->nickname); // fire up the dialog box 
-          } 
-       } 
-   
-       // else did we click the "get player info" button ? 
-       else if (wParam_loword == WINDOW_BUTTON_PLAYERINFO) 
-       { 
-          interlocutor = Interlocutor_FindByWindowHandle (hWnd); // find the interlocutor it is 
-          if (interlocutor != NULL) 
-             PlayerCard_FindOrCreate (interlocutor->nickname); // fire up the dialog box 
-       } 
-   
-       // else was it the "send" button ? 
-       else if (wParam_loword == WINDOW_BUTTON_SEND) 
-       { 
-          // grab the text to send from the edit box and empty the box 
-          length = SendMessage (GetDlgItem (hWnd, WINDOW_EDITBOX_MESSAGETOSEND), WM_GETTEXTLENGTH, 0, 0); // get text length 
-          text_buffer = (wchar_t *) SAFE_malloc (length + 1, sizeof (wchar_t), false); // allocate space 
-          GetDlgItemText (hWnd, WINDOW_EDITBOX_MESSAGETOSEND, text_buffer, length + 1); // copy text 
-   
-          // is there actually something to send ? 
-          if (text_buffer[0] != 0) 
-          { 
-             // drop all accents by converting to 7-bit US-ASCII and then back to wide char 
-             cstring_buffer = (char *) SAFE_malloc (2 * (length + 1), sizeof (char), false); 
-             ConvertTo7BitASCII (cstring_buffer, 2 * (length + 1), text_buffer); 
-             ConvertToWideChar (text_buffer, length + 1, cstring_buffer); 
-             SAFE_free ((void **) &cstring_buffer); 
-   
-             // convert some dangerous characters 
-             length = wcslen (text_buffer); 
-             for (char_index = 0; char_index < length; char_index++) 
-                if ((text_buffer[char_index] == L'\r') || (text_buffer[char_index] == L'\n')) 
-                   text_buffer[char_index] = L' '; 
-                else if (text_buffer[char_index] == L'%') 
-                   text_buffer[char_index] = L'ยค'; // percent signs are nasty for the varargs, so remove them 
-   
-             // find the local and the network players 
-             if (((remote_player = Player_FindByType (PLAYER_INTERNET)) != NULL) 
-                 && ((local_player = Player_FindByType (PLAYER_HUMAN)) != NULL)) 
-             { 
-                interlocutor = Interlocutor_FindByWindowHandle (hWnd); // find the interlocutor it is 
-                if (interlocutor != NULL) 
-                { 
-                   // fill the send buffer and append chat text to interlocutor's chat window 
-                   Player_SendBuffer_Add (remote_player, 1000, L"tell %s %s\n", interlocutor->nickname, text_buffer); 
-                   Interlocutor_Chat (interlocutor, local_player->name, true, text_buffer); 
-                } 
-             } 
-          } 
-   
-          SetDlgItemText (hWnd, WINDOW_EDITBOX_MESSAGETOSEND, L""); // reset text in the window 
-          SAFE_free ((void **) &text_buffer); // free the memory space we used 
-       } 
-   
-       // 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 
-    } 
-   
-    // else is it a timer event AND is it our refresh timer ? 
-    else if ((message == WM_TIMER) && (wParam == WINDOW_TIMER_REFRESH)) 
-    { 
-       interlocutor = Interlocutor_FindByWindowHandle (hWnd); // find the interlocutor it is 
-       if (interlocutor != NULL) 
-       { 
-          // find interlocutor in online players list 
-          for (player_index = 0; player_index < onlineplayer_count; player_index++) 
-             if (wcscmp (interlocutor->nickname, onlineplayers[player_index].nickname) == 0) 
-                break; // break as soon as we find it 
-   
-          // have we found it ? 
-          if (player_index < onlineplayer_count) 
-          { 
-             onlineplayer = &onlineplayers[player_index]; // quick access to online player 
-             remote_player = Player_FindByType (PLAYER_INTERNET); // find the remote player 
-   
-             // is this talkee our opponent AND are we playing a game AND does its status not reflect it yet ? 
-             if ((remote_player != NULL) && remote_player->is_in_game 
-                 && (wcscmp (onlineplayer->nickname, remote_player->name) == 0) 
-                 && ((onlineplayer->handlestatus == HANDLESTATUS_UNDEFINED) 
-                     || (onlineplayer->handlestatus == HANDLESTATUS_AVAILABLE) 
-                     || (onlineplayer->handlestatus == HANDLESTATUS_EXAMININGAGAME) 
-                     || (onlineplayer->handlestatus == HANDLESTATUS_NOTOPENFORAMATCH) 
-                     || (onlineplayer->handlestatus == HANDLESTATUS_INACTIVEORBUSY))) 
-                onlineplayer->handlestatus = HANDLESTATUS_INGAME; // if so, remember we're playing against it 
-   
-             display_picture = onlineplayer->handlestatus; // if so, use its current status 
-          } 
-          else 
-             display_picture = HANDLESTATUS_OFFLINE; // else flag it as offline 
-   
-          // do we need to change its status ? 
-          if (display_picture != interlocutor->current_displaypicture) 
-          { 
-             // set window icons (small one for title bar & big one for task manager) and avatar 
-             SendMessage (hWnd, WM_SETICON, ICON_SMALL, (LPARAM) handlestatus[display_picture].icon); 
-             SendMessage (hWnd, WM_SETICON, ICON_BIG, (LPARAM) handlestatus[display_picture].icon); 
-             SendMessage (GetDlgItem (hWnd, WINDOW_BITMAP_OPPONENTSTATUS), STM_SETIMAGE, IMAGE_BITMAP, (LPARAM) handlestatus[display_picture].bitmap); 
-   
-             // set window text 
-             swprintf_s (temp_string, WCHAR_SIZEOF (temp_string), L"%s (%s)", interlocutor->nickname, handlestatus[display_picture].text); 
-             SetWindowText (hWnd, temp_string); // set window title 
-   
-             // set window title and parameters 
-             if (display_picture == HANDLESTATUS_OFFLINE) 
-             { 
-                EnableWindow (GetDlgItem (hWnd, WINDOW_BUTTON_PLAYERINFO), false); // if so, disable buttons 
-                EnableWindow (GetDlgItem (hWnd, WINDOW_BUTTON_INVITE), false); 
-                EnableWindow (GetDlgItem (hWnd, WINDOW_EDITBOX_MESSAGETOSEND), false); 
-                EnableWindow (GetDlgItem (hWnd, WINDOW_BUTTON_SEND), false); 
-             } 
-             else 
-             { 
-                if ((display_picture == HANDLESTATUS_OFFLINE) || (display_picture == HANDLESTATUS_INGAME) || (display_picture == HANDLESTATUS_NOTOPENFORAMATCH)) 
-                   is_invitable = false; // this player is NOT invitable 
-                else 
-                   is_invitable = true; // all other players are invitable 
-   
-                EnableWindow (GetDlgItem (hWnd, WINDOW_BUTTON_PLAYERINFO), true); // else enable them 
-                EnableWindow (GetDlgItem (hWnd, WINDOW_BUTTON_INVITE), is_invitable); 
-                EnableWindow (GetDlgItem (hWnd, WINDOW_EDITBOX_MESSAGETOSEND), true); 
-                EnableWindow (GetDlgItem (hWnd, WINDOW_BUTTON_SEND), true); 
-   
-                if (GetForegroundWindow () == hWnd) 
-                   SetFocus (GetDlgItem (hWnd, WINDOW_EDITBOX_MESSAGETOSEND)); // set keyboard focus to the message editbox 
-             } 
-   
-             interlocutor->current_displaypicture = display_picture; // remember we've done it 
-          } 
-   
-          // do we need to update dialog ? 
-          if (interlocutor->update_dialog) 
-          { 
-             // set the leading caption 
-             swprintf_s (temp_string, WCHAR_SIZEOF (temp_string), LOCALIZE (L"Chat_Question"), interlocutor->nickname); 
-             SetDlgItemText (hWnd, WINDOW_TEXT_QUESTION, temp_string); 
-   
-             // set discussion text and scroll the edit box down 
-             hEditWnd = GetDlgItem (hWnd, WINDOW_EDITBOX_DISCUSSION); 
-             SetWindowText (hEditWnd, interlocutor->dialogtext); 
-             length = GetWindowTextLength (hEditWnd); 
-             //SetFocus (hEditWnd); 
-             Edit_SetSel (hEditWnd, length, length); 
-             Edit_ScrollCaret (hEditWnd); 
-             SetFocus (GetDlgItem (hWnd, WINDOW_EDITBOX_MESSAGETOSEND)); 
-   
-             // if we are not the top level window, flash window 
-             if (GetForegroundWindow () != hWnd) 
-             { 
-                memset (&flashinfo, 0, sizeof (flashinfo)); 
-                flashinfo.cbSize = sizeof (flashinfo); 
-                flashinfo.hwnd = hWnd; 
-                flashinfo.dwFlags = FLASHW_ALL | FLASHW_TIMERNOFG; // flash until we bring window to foreground 
-                FlashWindowEx (&flashinfo); 
-             } 
-   
-             interlocutor->update_dialog = false; // remember we refreshed dialog text 
-          } 
-       } 
-    } 
-   
-    // call the default dialog message processing function to keep things going 
-    return (DefWindowProc (hWnd, message, wParam, lParam)); 
- } 
-   
-   
- static LRESULT CALLBACK WindowProc_MessageToSend (HWND hWnd, unsigned int message, WPARAM wParam, LPARAM lParam) 
- { 
-    // this is the callback function for the edit box control where the user types its message 
-   
-    // was the enter key pressed ? 
-    if ((message == WM_CHAR) && (wParam == VK_RETURN)) 
-    { 
-       SendMessage (GetParent (hWnd), WM_COMMAND, WINDOW_BUTTON_SEND, 0); // if so, forward it to our parent 
-       return (true); // and prevent this keystroke from being treated 
-    } 
-   
-    // for all other messages, call the default window message processing function 
-    return ((LRESULT) CallWindowProc ((WNDPROC) WindowProc_MessageToSend_DefaultProc, hWnd, message, wParam, lParam)); 
- } 
-