Subversion Repositories Games.Chess Giants

Rev

Rev 124 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

  1. // dialog_playercard.cpp
  2.  
  3. #include "../common.h"
  4.  
  5.  
  6. // dialog template
  7. #define THIS_DIALOG DIALOG_PLAYERCARD
  8.  
  9.  
  10. // local definitions
  11. #define TIMER_REFRESHDIALOG 1
  12.  
  13.  
  14. // list view column definition
  15. typedef struct listviewcolumn_s
  16. {
  17.    int width;
  18.    int alignment;
  19.    wchar_t *text;
  20. } listviewcolumn_t;
  21.  
  22.  
  23. // global variables used in this module only
  24. static int listviewicons[sizeof (handlestatus) / sizeof (handlestatus_t)]; // as big as the handlestatus global array
  25. static listviewcolumn_t listviewcolumns[] =
  26. {
  27.    { 80, LVCFMT_LEFT, NULL /*LOCALIZE (L"PlayerCard_GameStyle")*/}, // text address needs to be set at runtime, because it's mallocated
  28.    { 45, LVCFMT_CENTER, NULL /*LOCALIZE (L"PlayerCard_Rating")*/},
  29.    { 40, LVCFMT_CENTER, NULL /*LOCALIZE (L"PlayerCard_RD")*/},
  30.    { 45, LVCFMT_CENTER, NULL /*LOCALIZE (L"PlayerCard_Wins")*/},
  31.    { 45, LVCFMT_CENTER, NULL /*LOCALIZE (L"PlayerCard_Losses")*/},
  32.    { 45, LVCFMT_CENTER, NULL /*LOCALIZE (L"PlayerCard_Draws")*/},
  33.    { 45, LVCFMT_CENTER, NULL /*LOCALIZE (L"PlayerCard_Totals")*/},
  34. };
  35. static wchar_t personalmessage_text[1024];
  36. static wchar_t invitee_nickname[32];
  37.  
  38.  
  39. // prototypes of local functions
  40. static void StartThread_PlayerCard (void *thread_parms);
  41. static int CALLBACK DialogProc_PlayerCard (HWND hWnd, unsigned int message, WPARAM wParam, LPARAM lParam);
  42.  
  43.  
  44. void DialogBox_PlayerCard (int playercard_index)
  45. {
  46.    // helper function to fire up the modeless dialog box
  47.  
  48.    _beginthread (StartThread_PlayerCard, 0, (void *) playercard_index); // fire up the thread
  49.    return; // return as soon as the thread is fired up
  50. }
  51.  
  52.  
  53. void DialogBox_PlayerCard_Validated (void)
  54. {
  55.    // callback function called by the main game thread when the dialog box is validated
  56.  
  57.    challenge_t *challenge;
  58.  
  59.    // remember this callback is no longer to be called
  60.    is_dialogbox_playercard_validated = false;
  61.  
  62.    // TODO: verify if not ourselves
  63.  
  64.    // player is available for an invitation. Is he already inviting us ?
  65.    challenge = Challenge_Find (invitee_nickname);
  66.    if ((challenge != NULL) && challenge->is_active && IsWindow (challenge->hWnd))
  67.       EndDialog (challenge->hWnd, 0); // if so, close the challenge dialog box (this will also make us decline it properly)
  68.  
  69.    Interlocutor_FindOrCreate (invitee_nickname); // fire up the chat window with this player
  70.    return; // finished, a new chat window has been opened with this player
  71. }
  72.  
  73.  
  74. static void StartThread_PlayerCard (void *thread_parms)
  75. {
  76.    // this function runs in a separate thread, for that's the only way (seemingly)
  77.    // to implement a non-modal message box using the Common Controls library.
  78.  
  79.    int playercard_index;
  80.    playercard_t *playercard;
  81.  
  82.    playercard_index = (int) thread_parms;
  83.    if (playercard_index >= playercard_count)
  84.       return; // consistency check; _endthread() implied
  85.    playercard = &playercards[playercard_index]; // quick access to player card structure
  86.  
  87.    // display the dialog box and attach this playercard to it
  88.    if (DialogBoxParam (hAppInstance, MAKEINTRESOURCE (THIS_DIALOG), NULL, DialogProc_PlayerCard, (LPARAM) playercard_index) == 1)
  89.       is_dialogbox_playercard_validated = true;
  90.  
  91.    // now that we're sure the window disappeared...
  92.    playercard = &playercards[playercard_index]; // quick access to player card structure (it may have relocated)
  93.    playercard->is_active = false; // remember interlocutor has gone away
  94.    SAFE_free ((void **) &playercard->fingertext); // free its text
  95.    playercard->fingertext_length = 0; // and reset its text length
  96.    SAFE_free ((void **) &playercard->gamestyleratings); // free its game style ratings
  97.    playercard->gamestylerating_count = 0; // and reset its count
  98.  
  99.    return; // _endthread() implied
  100. }
  101.  
  102.  
  103. static int CALLBACK DialogProc_PlayerCard (HWND hWnd, unsigned int message, WPARAM wParam, LPARAM lParam)
  104. {
  105.    // message handler for the dialog box
  106.  
  107.    unsigned short wParam_hiword;
  108.    unsigned short wParam_loword;
  109.    gamestylerating_t *gamestylerating;
  110.    onlineplayer_t *onlineplayer;
  111.    playercard_t *playercard;
  112.    wchar_t text_to_send[256];
  113.    wchar_t *current_line;
  114.    wchar_t *wcstok_context;
  115.    player_t *network_player;
  116.    HIMAGELIST imagelist;
  117.    HWND hListWnd;
  118.    LVCOLUMN lvc;
  119.    LVITEM lvi;
  120.    int insert_index;
  121.    int column_index;
  122.    int player_index;
  123.    int gsr_index;
  124.  
  125.    // filter out the commonly used message values
  126.    wParam_hiword = HIWORD (wParam);
  127.    wParam_loword = LOWORD (wParam);
  128.  
  129.    // have we just fired up this window ?
  130.    if (message == WM_INITDIALOG)
  131.    {
  132.       playercard = &playercards[lParam]; // quick access to player card
  133.       SetWindowLongPtr (hWnd, DWLP_USER, lParam); // attach player card
  134.       playercard->hWnd = hWnd; // and save window handle
  135.  
  136.       // center the window
  137.       CenterWindow (hWnd, hMainWnd);
  138.  
  139.       // set dialog icons (small one for title bar & big one for task manager)
  140.       SendMessage (hWnd, WM_SETICON, ICON_SMALL, (LPARAM) LoadIcon (hAppInstance, MAKEINTRESOURCE (ICON_CARD)));
  141.       SendMessage (hWnd, WM_SETICON, ICON_BIG, (LPARAM) LoadIcon (hAppInstance, MAKEINTRESOURCE (ICON_CARD)));
  142.  
  143.       // find the remote player
  144.       network_player = Player_FindByType (PLAYER_INTERNET);
  145.  
  146.       // make network player ask an update from the server
  147.       if (network_player != NULL)
  148.       {
  149.          if (lastonlineplayers_time + 5.0f < current_time)
  150.             Player_SendBuffer_Add (network_player, 1000, L"who\n"); // finger requests need an updated player list
  151.          Player_SendBuffer_Add (network_player, 1000, L"finger %s\n", playercard->nickname); // send the finger request
  152.       }
  153.  
  154.       // set the finger data text area font
  155.       SendMessage (GetDlgItem (hWnd, EDITBOX_PLAYERCARD_FINGERDATA), WM_SETFONT, (WPARAM) hFontChat, false);
  156.  
  157.       // set the dialog text editable if it's ours, and read-only if it's not
  158.       Edit_SetReadOnly (GetDlgItem (hWnd, EDITBOX_PLAYERCARD_FINGERDATA), !playercard->is_own);
  159.  
  160.       // prepare the list view : do it before anything that could trigger a fill
  161.  
  162.       // get a quick access to the list control
  163.       hListWnd = GetDlgItem (hWnd, COMBOBOX_GAMESTYLES);
  164.  
  165.       // tell Windows which members of the LVCOLUMN structure we're filling
  166.       memset (&lvc, 0, sizeof (lvc));
  167.       lvc.mask = LVCF_FMT | LVCF_WIDTH | LVCF_TEXT | LVCF_SUBITEM;
  168.       for (column_index = 0; column_index < sizeof (listviewcolumns) / sizeof (listviewcolumn_t); column_index++)
  169.       {
  170.          lvc.iSubItem = column_index;
  171.          if (column_index == 0) lvc.pszText = LOCALIZE (L"PlayerCard_GameStyle");
  172.          else if (column_index == 1) lvc.pszText = LOCALIZE (L"PlayerCard_Rating");
  173.          else if (column_index == 2) lvc.pszText = LOCALIZE (L"PlayerCard_RD");
  174.          else if (column_index == 3) lvc.pszText = LOCALIZE (L"PlayerCard_Wins");
  175.          else if (column_index == 4) lvc.pszText = LOCALIZE (L"PlayerCard_Losses");
  176.          else if (column_index == 5) lvc.pszText = LOCALIZE (L"PlayerCard_Draws");
  177.          else if (column_index == 6) lvc.pszText = LOCALIZE (L"PlayerCard_Totals");
  178.          lvc.cx = listviewcolumns[column_index].width;
  179.          lvc.fmt = listviewcolumns[column_index].alignment;
  180.          ListView_InsertColumn (hListWnd, column_index, &lvc); // add each column to list view
  181.       }
  182.  
  183.       // create the listview image list
  184.       imagelist = ImageList_Create (16, 16, ILC_COLOR32, sizeof (handlestatus) / sizeof (handlestatus_t), 1); // create an imagelist holding N 32-bit images
  185.       for (insert_index = 1; insert_index < sizeof (handlestatus) / sizeof (handlestatus_t); insert_index++)
  186.          listviewicons[insert_index] = ImageList_AddIcon (imagelist, handlestatus[insert_index].icon); // add our icons in the image list
  187.       ListView_SetImageList (hListWnd, imagelist, LVSIL_SMALL); // associate it with the listview
  188.  
  189.       // set window title and control texts
  190.       swprintf_s (text_to_send, WCHAR_SIZEOF (text_to_send), LOCALIZE (L"PlayerCard_TitleBuildingCard"), playercard->nickname);
  191.       SetWindowText (hWnd, text_to_send);
  192.       if (playercard->is_own)
  193.          wcscpy_s (text_to_send, WCHAR_SIZEOF (text_to_send), LOCALIZE (L"PlayerCard_YourStats"));
  194.       else
  195.          swprintf_s (text_to_send, WCHAR_SIZEOF (text_to_send), LOCALIZE (L"PlayerCard_Stats"), playercard->nickname);
  196.       SetDlgItemText (hWnd, STATICTEXT_PLAYERCARD_STATSTEXT, text_to_send);
  197.       SetDlgItemText (hWnd, STATICTEXT_PLAYERCARD_ONLINEFORKEY, LOCALIZE (L"PlayerCard_OnlineForKey"));
  198.       SetDlgItemText (hWnd, STATICTEXT_PLAYERCARD_ONLINEFORVALUE, L"");
  199.       SetDlgItemText (hWnd, STATICTEXT_PLAYERCARD_CURRENTSTATUSKEY, LOCALIZE (L"PlayerCard_CurrentStatusKey"));
  200.       SetDlgItemText (hWnd, STATICTEXT_PLAYERCARD_CURRENTSTATUSVALUE, L"");
  201.       SetDlgItemText (hWnd, STATICTEXT_PLAYERCARD_GAMEPLAYEDKEY, LOCALIZE (L"PlayerCard_GamePlayedKey"));
  202.       SetDlgItemText (hWnd, STATICTEXT_PLAYERCARD_GAMEPLAYEDVALUE, L"");
  203.       SetDlgItemText (hWnd, STATICTEXT_PLAYERCARD_LASTACTIVITYKEY, LOCALIZE (L"PlayerCard_LastActivityKey"));
  204.       SetDlgItemText (hWnd, STATICTEXT_PLAYERCARD_LASTACTIVITYVALUE, L"");
  205.       SetDlgItemText (hWnd, BUTTON_CLOSE, LOCALIZE (L"Button_Close"));
  206.       SetDlgItemText (hWnd, STATICTEXT_PLAYERCARD_STATUSBAR, LOCALIZE (L"PlayerCard_StatusBar"));
  207.  
  208.       // refresh the server message area every second
  209.       SetTimer (hWnd, TIMER_REFRESHDIALOG, 1000, NULL);
  210.       SendMessage (hWnd, WM_TIMER, TIMER_REFRESHDIALOG, 0); // but call it now
  211.  
  212.       // convert the game played and status bar message to a hyperlink
  213.       ConvertStaticToHyperlink (GetDlgItem (hWnd, STATICTEXT_PLAYERCARD_GAMEPLAYEDVALUE));
  214.       ConvertStaticToHyperlink (GetDlgItem (hWnd, STATICTEXT_PLAYERCARD_STATUSBAR));
  215.    }
  216.  
  217.    // else did we click the close button on the title bar ?
  218.    else if (message == WM_CLOSE)
  219.    {
  220.       playercard = &playercards[GetWindowLongPtr (hWnd, DWLP_USER)]; // quick access to player card
  221.  
  222.       // was it our own card ? if so, update our personal info
  223.       if (playercard->is_own)
  224.       {
  225.          // find the remote player
  226.          network_player = Player_FindByType (PLAYER_INTERNET);
  227.          if (network_player != NULL)
  228.          {
  229.             // retrieve the personal message text from the control
  230.             GetDlgItemText (hWnd, EDITBOX_PLAYERCARD_FINGERDATA, personalmessage_text, WCHAR_SIZEOF (personalmessage_text));
  231.  
  232.             // is it NOT the default text ?
  233.             if (wcscmp (personalmessage_text, LOCALIZE (L"PlayerCard_TypeYourPersonalMessageHere")) != NULL)
  234.             {
  235.                // set finger variables 1 to 10 (max 10 lines)
  236.                current_line = wcstok_s (personalmessage_text, L"\r\n", &wcstok_context);
  237.                for (insert_index = 1; insert_index < 10; insert_index++)
  238.                {
  239.                   Player_SendBuffer_Add (network_player, 1000, L"set %d %s\n", insert_index, (current_line != NULL ? current_line : L""));
  240.                   current_line = wcstok_s (NULL, L"\r\n", &wcstok_context);
  241.                }
  242.             }
  243.          }
  244.       }
  245.  
  246.       KillTimer (hWnd, TIMER_REFRESHDIALOG); // destroy the timer we used to refresh the dialog text
  247.       EndDialog (hWnd, 0); // close the dialog box
  248.    }
  249.  
  250.    // else did we take action on one of the controls ?
  251.    else if (message == WM_COMMAND)
  252.    {
  253.       // did we cancel the dialog box ? (IDCANCEL is a system-wide dialog box handler value, that catches the ESC key)
  254.       if (wParam_loword == IDCANCEL)
  255.       {
  256.          KillTimer (hWnd, TIMER_REFRESHDIALOG); // destroy the timer we used to refresh the dialog text
  257.          EndDialog (hWnd, 0); // close the dialog box
  258.       }
  259.  
  260.       // else was it the game played hyperlink ?
  261.       else if (wParam_loword == STATICTEXT_PLAYERCARD_GAMEPLAYEDVALUE)
  262.       {
  263.          playercard = &playercards[GetWindowLongPtr (hWnd, DWLP_USER)]; // quick access to player card
  264.  
  265.          // see which player it is
  266.          for (player_index = 0; player_index < onlineplayer_count; player_index++)
  267.             if (wcscmp (onlineplayers[player_index].nickname, playercard->nickname) == 0)
  268.                break; // stop searching as soon as player is found
  269.  
  270.          // have we found it ?
  271.          if (player_index < onlineplayer_count)
  272.          {
  273.             onlineplayer = &onlineplayers[player_index]; // quick access to online player
  274.  
  275.             // is player actually playing a game ?
  276.             if (playercard->game_played != 0)
  277.                ; // yes, so watch it as spectator (TODO)
  278.  
  279.             // else is player invitable ?
  280.             else if ((playercard->minutes_online > 0) && !playercard->is_own
  281.                      && (onlineplayer->handlestatus != HANDLESTATUS_NOTOPENFORAMATCH))
  282.             {
  283.                // save concerned nickname before destroying window
  284.                wcscpy_s (invitee_nickname, WCHAR_SIZEOF (invitee_nickname), playercard->nickname);
  285.  
  286.                KillTimer (hWnd, TIMER_REFRESHDIALOG); // destroy the timer we used to refresh the dialog text
  287.                EndDialog (hWnd, 1); // close the dialog box and return a success value
  288.             }
  289.          }
  290.       }
  291.  
  292.       // else was it the status bar hyperlink ?
  293.       else if (wParam_loword == STATICTEXT_PLAYERCARD_STATUSBAR)
  294.          ShellExecute (NULL, L"open", PROGRAM_URL, NULL, NULL, SW_MAXIMIZE); // open the donation page in the default browser, maximized
  295.    }
  296.  
  297.    // else is it a timer event AND is it our refresh timer ?
  298.    else if ((message == WM_TIMER) && (wParam == TIMER_REFRESHDIALOG))
  299.    {
  300.       playercard = &playercards[GetWindowLongPtr (hWnd, DWLP_USER)]; // quick access to player card
  301.  
  302.       // do we need to update dialog ?
  303.       if (playercard->update_dialog)
  304.       {
  305.          swprintf_s (text_to_send, WCHAR_SIZEOF (text_to_send), LOCALIZE (L"PlayerCard_Title"), playercard->nickname);
  306.          SetWindowText (hWnd, text_to_send); // set window title
  307.  
  308.          // does this player NOT exist ?
  309.          if (playercard->doesnt_exist)
  310.          {
  311.             // set personal message
  312.             SetDlgItemText (hWnd, EDITBOX_PLAYERCARD_FINGERDATA, L"");
  313.  
  314.             // set statistics phrase
  315.             swprintf_s (text_to_send, WCHAR_SIZEOF (text_to_send), LOCALIZE (L"PlayerCard_DoesNotExist"), playercard->nickname);
  316.             SetDlgItemText (hWnd, STATICTEXT_PLAYERCARD_STATSTEXT, text_to_send);
  317.  
  318.             // set current activity stats
  319.             SetDlgItemText (hWnd, STATICTEXT_PLAYERCARD_ONLINEFORVALUE, L"-");
  320.             SetDlgItemText (hWnd, STATICTEXT_PLAYERCARD_CURRENTSTATUSVALUE, L"-");
  321.             SetDlgItemText (hWnd, STATICTEXT_PLAYERCARD_GAMEPLAYEDVALUE, L"-");
  322.             SetDlgItemText (hWnd, STATICTEXT_PLAYERCARD_LASTACTIVITYVALUE, L"-");
  323.          }
  324.          else
  325.          {
  326.             // set personal message
  327.             if (playercard->fingertext_length > 0)
  328.                SetDlgItemText (hWnd, EDITBOX_PLAYERCARD_FINGERDATA, playercard->fingertext);
  329.             else if (playercard->got_reply)
  330.             {
  331.                // if it's our card, invite player to write a personal message; else tell this player has none
  332.                if (playercard->is_own)
  333.                   SetDlgItemText (hWnd, EDITBOX_PLAYERCARD_FINGERDATA, LOCALIZE (L"PlayerCard_TypeYourPersonalMessageHere"));
  334.                else
  335.                   SetDlgItemText (hWnd, EDITBOX_PLAYERCARD_FINGERDATA, LOCALIZE (L"PlayerCard_NoPersonalMessage"));
  336.             }
  337.             else
  338.                SetDlgItemText (hWnd, EDITBOX_PLAYERCARD_FINGERDATA, L"");
  339.  
  340.             // if it's our card, select all the personal message text
  341.             if (playercard->is_own)
  342.                SendMessage (GetDlgItem (hWnd, EDITBOX_PLAYERCARD_FINGERDATA), EM_SETSEL, 0, -1); // select all text
  343.  
  344.             // set statistics phrase
  345.             if (playercard->gamestylerating_count > 0)
  346.             {
  347.                if (playercard->is_own)
  348.                   wcscpy_s (text_to_send, WCHAR_SIZEOF (text_to_send), LOCALIZE (L"PlayerCard_YourStats"));
  349.                else
  350.                   swprintf_s (text_to_send, WCHAR_SIZEOF (text_to_send), LOCALIZE (L"PlayerCard_Stats"), playercard->nickname);
  351.             }
  352.             else if (playercard->got_reply)
  353.             {
  354.                if (playercard->is_own)
  355.                   wcscpy_s (text_to_send, WCHAR_SIZEOF (text_to_send), LOCALIZE (L"PlayerCard_NoStatsYetForYou"));
  356.                else
  357.                   swprintf_s (text_to_send, WCHAR_SIZEOF (text_to_send), LOCALIZE (L"PlayerCard_NoStatsYet"), playercard->nickname);
  358.             }
  359.             else
  360.                text_to_send[0] = 0;
  361.             SetDlgItemText (hWnd, STATICTEXT_PLAYERCARD_STATSTEXT, text_to_send);
  362.  
  363.             // set statistics
  364.             hListWnd = GetDlgItem (hWnd, COMBOBOX_GAMESTYLES); // get a quick access to the list control
  365.             ListView_DeleteAllItems (hListWnd); // start by emptying it first
  366.             memset (&lvi, 0, sizeof (lvi)); // tell Windows which members of the LVCOLUMN structure we're filling
  367.             lvi.mask = LVIF_IMAGE | LVIF_PARAM; // we want to set the image and the item's pointer
  368.             for (gsr_index = 0; gsr_index < playercard->gamestylerating_count; gsr_index++)
  369.             {
  370.                gamestylerating = &playercard->gamestyleratings[gsr_index]; // quick access to game style rating
  371.  
  372.                // set item's image and name
  373.                lvi.iItem = gsr_index;
  374.                lvi.iImage = listviewicons[HANDLESTATUS_INGAME];
  375.                insert_index = ListView_InsertItem (hListWnd, &lvi); // add each item to list view
  376.  
  377.                // set item's substrings
  378.                ListView_SetItemText (hListWnd, insert_index, 0, gamestylerating->name); // game style name
  379.                swprintf_s (text_to_send, WCHAR_SIZEOF (text_to_send), L"%d", gamestylerating->rating);
  380.                ListView_SetItemText (hListWnd, insert_index, 1, text_to_send); // rating
  381.                swprintf_s (text_to_send, WCHAR_SIZEOF (text_to_send), L"%.1f", gamestylerating->rd);
  382.                ListView_SetItemText (hListWnd, insert_index, 2, text_to_send); // RD
  383.                swprintf_s (text_to_send, WCHAR_SIZEOF (text_to_send), L"%d", gamestylerating->win_count);
  384.                ListView_SetItemText (hListWnd, insert_index, 3, text_to_send); // wins
  385.                swprintf_s (text_to_send, WCHAR_SIZEOF (text_to_send), L"%d", gamestylerating->loss_count);
  386.                ListView_SetItemText (hListWnd, insert_index, 4, text_to_send); // losses
  387.                swprintf_s (text_to_send, WCHAR_SIZEOF (text_to_send), L"%d", gamestylerating->draw_count);
  388.                ListView_SetItemText (hListWnd, insert_index, 5, text_to_send); // draws
  389.                swprintf_s (text_to_send, WCHAR_SIZEOF (text_to_send), L"%d", gamestylerating->total_matches);
  390.                ListView_SetItemText (hListWnd, insert_index, 6, text_to_send); // totals
  391.             }
  392.  
  393.             // set status
  394.             swprintf_s (text_to_send, WCHAR_SIZEOF (text_to_send), LOCALIZE (L"Opponents_StatusOffline")); // assume offline until found
  395.  
  396.             // cycle through all online players and see if this one is online
  397.             for (player_index = 0; player_index < onlineplayer_count; player_index++)
  398.                if (wcscmp (onlineplayers[player_index].nickname, playercard->nickname) == 0)
  399.                   break; // break as soon as we find it
  400.  
  401.             // have we found it ?
  402.             if (player_index < onlineplayer_count)
  403.                onlineplayer = &onlineplayers[player_index]; // quick access to online player
  404.             else
  405.                onlineplayer = NULL; // else this player is not online
  406.  
  407.             // is player online ?
  408.             if (onlineplayer != NULL)
  409.             {
  410.                // verify status before setting it
  411.                if (((onlineplayer->handlestatus == HANDLESTATUS_INGAME) || (onlineplayer->handlestatus == HANDLESTATUS_EXAMININGAGAME))
  412.                      && (playercard->game_played == 0))
  413.                   onlineplayer->handlestatus = HANDLESTATUS_AVAILABLE; // if player was reported playing but no game, mark it free
  414.  
  415.                SetDlgItemText (hWnd, STATICTEXT_PLAYERCARD_CURRENTSTATUSVALUE, handlestatus[onlineplayer->handlestatus].text);
  416.             }
  417.             else
  418.                SetDlgItemText (hWnd, STATICTEXT_PLAYERCARD_CURRENTSTATUSVALUE, handlestatus[HANDLESTATUS_OFFLINE].text);
  419.  
  420.             // set played game name
  421.             if (playercard->game_played != 0)
  422.                swprintf_s (text_to_send, WCHAR_SIZEOF (text_to_send), L"%d - %s", playercard->game_played, playercard->game_name);
  423.             else if ((playercard->minutes_online > 0) && !playercard->is_own
  424.                      && (onlineplayer != NULL) && (onlineplayer->handlestatus != HANDLESTATUS_NOTOPENFORAMATCH))
  425.                swprintf_s (text_to_send, WCHAR_SIZEOF (text_to_send), LOCALIZE (L"PlayerCard_ChatOrInvite")); // no game ; if online, we can invite him
  426.             else
  427.                text_to_send[0] = 0;
  428.             SetDlgItemText (hWnd, STATICTEXT_PLAYERCARD_GAMEPLAYEDVALUE, text_to_send);
  429.  
  430.             // only set online time and idle time if player is not offline (if we have found him, then he's online)
  431.             if (onlineplayer != NULL)
  432.             {
  433.                MinutesToWideCharString (text_to_send, WCHAR_SIZEOF (text_to_send), playercard->minutes_online);
  434.                SetDlgItemText (hWnd, STATICTEXT_PLAYERCARD_ONLINEFORVALUE, text_to_send); // set online time value
  435.  
  436.                SecondsToWideCharString (text_to_send, WCHAR_SIZEOF (text_to_send), playercard->seconds_idle);
  437.                SetDlgItemText (hWnd, STATICTEXT_PLAYERCARD_LASTACTIVITYVALUE, text_to_send); // set idle time value
  438.             }
  439.             else
  440.             {
  441.                SetDlgItemText (hWnd, STATICTEXT_PLAYERCARD_ONLINEFORVALUE, L"-"); // player is offline
  442.  
  443.                if (playercard->disconnection_month == 1) swprintf_s (text_to_send, WCHAR_SIZEOF (text_to_send), L"%d %s %d", playercard->disconnection_day, LOCALIZE (L"Month_January"), playercard->disconnection_year);
  444.                else if (playercard->disconnection_month == 2) swprintf_s (text_to_send, WCHAR_SIZEOF (text_to_send), L"%d %s %d", playercard->disconnection_day, LOCALIZE (L"Month_February"), playercard->disconnection_year);
  445.                else if (playercard->disconnection_month == 3) swprintf_s (text_to_send, WCHAR_SIZEOF (text_to_send), L"%d %s %d", playercard->disconnection_day, LOCALIZE (L"Month_March"), playercard->disconnection_year);
  446.                else if (playercard->disconnection_month == 4) swprintf_s (text_to_send, WCHAR_SIZEOF (text_to_send), L"%d %s %d", playercard->disconnection_day, LOCALIZE (L"Month_April"), playercard->disconnection_year);
  447.                else if (playercard->disconnection_month == 5) swprintf_s (text_to_send, WCHAR_SIZEOF (text_to_send), L"%d %s %d", playercard->disconnection_day, LOCALIZE (L"Month_May"), playercard->disconnection_year);
  448.                else if (playercard->disconnection_month == 6) swprintf_s (text_to_send, WCHAR_SIZEOF (text_to_send), L"%d %s %d", playercard->disconnection_day, LOCALIZE (L"Month_June"), playercard->disconnection_year);
  449.                else if (playercard->disconnection_month == 7) swprintf_s (text_to_send, WCHAR_SIZEOF (text_to_send), L"%d %s %d", playercard->disconnection_day, LOCALIZE (L"Month_July"), playercard->disconnection_year);
  450.                else if (playercard->disconnection_month == 8) swprintf_s (text_to_send, WCHAR_SIZEOF (text_to_send), L"%d %s %d", playercard->disconnection_day, LOCALIZE (L"Month_August"), playercard->disconnection_year);
  451.                else if (playercard->disconnection_month == 9) swprintf_s (text_to_send, WCHAR_SIZEOF (text_to_send), L"%d %s %d", playercard->disconnection_day, LOCALIZE (L"Month_September"), playercard->disconnection_year);
  452.                else if (playercard->disconnection_month == 10) swprintf_s (text_to_send, WCHAR_SIZEOF (text_to_send), L"%d %s %d", playercard->disconnection_day, LOCALIZE (L"Month_October"), playercard->disconnection_year);
  453.                else if (playercard->disconnection_month == 11) swprintf_s (text_to_send, WCHAR_SIZEOF (text_to_send), L"%d %s %d", playercard->disconnection_day, LOCALIZE (L"Month_November"), playercard->disconnection_year);
  454.                else if (playercard->disconnection_month == 12) swprintf_s (text_to_send, WCHAR_SIZEOF (text_to_send), L"%d %s %d", playercard->disconnection_day, LOCALIZE (L"Month_December"), playercard->disconnection_year);
  455.                else swprintf_s (text_to_send, WCHAR_SIZEOF (text_to_send), LOCALIZE (L"Never"));
  456.                SetDlgItemText (hWnd, STATICTEXT_PLAYERCARD_LASTACTIVITYVALUE, text_to_send); // print last disconnection date
  457.             }
  458.          }
  459.  
  460.          playercard->update_dialog = false; // remember we refreshed dialog text
  461.       }
  462.    }
  463.  
  464.    // call the default dialog message processing function to keep things going
  465.    return (false);
  466. }
  467.