| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837 |
- /*
- ** Command & Conquer Renegade(tm)
- ** Copyright 2025 Electronic Arts Inc.
- **
- ** This program is free software: you can redistribute it and/or modify
- ** it under the terms of the GNU General Public License as published by
- ** the Free Software Foundation, either version 3 of the License, or
- ** (at your option) any later version.
- **
- ** This program is distributed in the hope that it will be useful,
- ** but WITHOUT ANY WARRANTY; without even the implied warranty of
- ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- ** GNU General Public License for more details.
- **
- ** You should have received a copy of the GNU General Public License
- ** along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
- /***********************************************************************************************
- *** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ***
- ***********************************************************************************************
- * *
- * Project Name : Combat *
- * *
- * $Archive:: /Commando/Code/commando/dlgmpingamechat.cpp $*
- * *
- * Author:: Tom SS *
- * *
- * $Modtime:: 2/19/02 2:40p $*
- * *
- * $Revision:: 20 $*
- * *
- *---------------------------------------------------------------------------------------------*
- * Functions: *
- * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
- #include "dlgmpingamechat.h"
- #include "cnetwork.h"
- #include "dialogcontrol.h"
- #include "dialogmgr.h"
- #include "gamedata.h"
- #include "cstextobj.h"
- #include "sctextobj.h"
- #include "comboboxctrl.h"
- #include "playermanager.h"
- #include "player.h"
- #include "listctrl.h"
- #include "messagewindow.h"
- #include "wolgmode.h"
- #include "translatedb.h"
- #include "string_ids.h"
- static const WCHAR* Get_Parameter_From_String(const WCHAR* command, WideStringClass& param);
- ////////////////////////////////////////////////////////////////
- //
- // MPChatChildDialogClass
- //
- ////////////////////////////////////////////////////////////////
- MPChatChildDialogClass::MPChatChildDialogClass (void) :
- MessageType (TEXT_MESSAGE_PUBLIC),
- TestForAutoCompletion (false),
- EndDialogOnSend (true),
- ChildDialogClass (IDD_CHAT_MODULE)
- {
- return ;
- }
- ////////////////////////////////////////////////////////////////
- //
- // On_Init_Dialog
- //
- ////////////////////////////////////////////////////////////////
- void
- MPChatChildDialogClass::On_Init_Dialog (void)
- {
- WWASSERT (The_Game () != NULL);
- //
- // Allow the base class to process the message
- //
- ChildDialogClass::On_Init_Dialog ();
- //
- // Set the text of the type control accordingly
- //
- if (MessageType == TEXT_MESSAGE_TEAM) {
- Set_Dlg_Item_Text (IDC_TYPE_STATIC, TRANSLATE (IDS_MENU_TEAM_MESSAGE));
- } else if (MessageType == TEXT_MESSAGE_PUBLIC) {
- Set_Dlg_Item_Text (IDC_TYPE_STATIC, TRANSLATE (IDS_MENU_PUBLIC_MESSAGE));
- }
- //
- // Put the focus into the text control
- //
- ((EditCtrlClass *)Get_Dlg_Item (IDC_MESSAGE_EDIT))->Set_Text_Limit (100);
- Get_Dlg_Item (IDC_MESSAGE_EDIT)->Set_Focus ();
- return ;
- }
- ////////////////////////////////////////////////////////////////
- //
- // Send_Message
- //
- ////////////////////////////////////////////////////////////////
- void
- MPChatChildDialogClass::Process_Message (void)
- {
- // Get the text to send...
- WideStringClass message(0, true);
- message = Get_Dlg_Item_Text(IDC_MESSAGE_EDIT);
- message.Trim();
- if (message.Is_Empty() == false) {
- if (Process_Commands(message) == false) {
- TextMessageEnum message_type = MessageType;
- int recipient_id = -1;
- bool is_ok_to_send = true;
- //
- // Determine who to send the message to...
- //
- if (RecipientName.Is_Empty() == false) {
-
- //
- // Lookup the player we're sending the message to
- //
- cPlayer *recipient = cPlayerManager::Find_Player (RecipientName);
- if (recipient != NULL) {
- message_type = TEXT_MESSAGE_PRIVATE;
- recipient_id = recipient->Get_Id ();
- } else {
- is_ok_to_send = false;
- }
- }
- //
- // Transmit the message
- //
- if (is_ok_to_send) {
- Send_Message(message, message_type, recipient_id);
- }
- }
- //
- // Clear the edit control
- //
- Set_Dlg_Item_Text (IDC_MESSAGE_EDIT, L"");
- }
- return ;
- }
- void MPChatChildDialogClass::Send_Message(WideStringClass& message, TextMessageEnum type, int recipientID)
- {
- //
- // Send the message
- //
- if (cNetwork::I_Am_Client ()) {
- cCsTextObj *event_obj = new cCsTextObj;
- event_obj->Init(message, type, cNetwork::Get_My_Id(), recipientID);
- } else {
- cScTextObj *event_obj = new cScTextObj;
- event_obj->Init(message, type, false, HOST_TEXT_SENDER, recipientID);
- }
- }
- ////////////////////////////////////////////////////////////////
- //
- // Process Commands
- //
- ////////////////////////////////////////////////////////////////
- bool MPChatChildDialogClass::Process_Commands(const WCHAR* message)
- {
- // Does this look like a command?
- if (message && message[0] == L'/') {
- // Separate the parameters into individual strings
- WideStringClass command(255, true);
- const WCHAR* curr_pos = Get_Parameter_From_String(&message[1], command);
- if (command.Get_Length() > 0 && curr_pos[0] != 0) {
- // Kick a player from the game
- if (command.Compare_No_Case(L"kick") == 0) {
- GameModeClass* gameMode = GameModeManager::Find("WOL");
- if (gameMode && gameMode->Is_Active()) {
- // Get the name parameter from the string
- WideStringClass user_name(64, true);
- curr_pos = Get_Parameter_From_String(curr_pos, user_name);
- if (user_name.Get_Length() > 0) {
- WolGameModeClass* wolGame = reinterpret_cast<WolGameModeClass*>(gameMode);
- wolGame->Kick_Player(user_name);
- }
- }
-
- return true;
- }
- // Page users outside of this game.
- if (command.Compare_No_Case(L"page") == 0) {
- GameModeClass* gameMode = GameModeManager::Find("WOL");
- if (gameMode && gameMode->Is_Active()) {
- // Get the name parameter from the string
- WideStringClass user_name(64, true);
- curr_pos = Get_Parameter_From_String(curr_pos, user_name);
- if (user_name.Get_Length() > 0) {
- WideStringClass message(0, true);
- message = curr_pos;
- message.Trim();
- // If the user is in this game then just send them a private message.
- cPlayer* recipient = cPlayerManager::Find_Player(user_name);
- if (recipient) {
- int recipient_id = recipient->Get_Id();
- Send_Message(message, TEXT_MESSAGE_PRIVATE, recipient_id);
- } else {
- // Page external users.
- WolGameModeClass* wolGame = reinterpret_cast<WolGameModeClass*>(gameMode);
- wolGame->Page_WOL_User(user_name, message);
- }
- }
- }
-
- return true;
- }
- // Reply to the last page
- if (command.Compare_No_Case(L"r") == 0) {
- GameModeClass* gameMode = GameModeManager::Find("WOL");
- if (gameMode && gameMode->Is_Active()) {
- WolGameModeClass* wolGame = reinterpret_cast<WolGameModeClass*>(gameMode);
- WideStringClass message(0, true);
- message = curr_pos;
- message.Trim();
- wolGame->Reply_Last_Page(message);
- }
-
- return true;
- }
- // Locate a WOL user
- if (command.Compare_No_Case(L"locate") == 0) {
- GameModeClass* gameMode = GameModeManager::Find("WOL");
- if (gameMode && gameMode->Is_Active()) {
- // Get the name parameter from the string
- WideStringClass user_name(64, true);
- curr_pos = Get_Parameter_From_String(curr_pos, user_name);
- if (user_name.Get_Length() > 0) {
- WolGameModeClass* wolGame = reinterpret_cast<WolGameModeClass*>(gameMode);
- wolGame->Locate_WOL_User(user_name);
- }
- }
-
- return true;
- }
- // Invite another WOL user to this game
- if (command.Compare_No_Case(L"invite") == 0) {
- GameModeClass* gameMode = GameModeManager::Find("WOL");
- if (gameMode && gameMode->Is_Active()) {
- // Get the name parameter from the string
- WideStringClass user_name(64, true);
- curr_pos = Get_Parameter_From_String(curr_pos, user_name);
- if (user_name.Get_Length() > 0) {
- WolGameModeClass* wolGame = reinterpret_cast<WolGameModeClass*>(gameMode);
- WideStringClass message(0, true);
- message = curr_pos;
- message.Trim();
- wolGame->Invite_WOL_User(user_name, message);
- }
- }
-
- return true;
- }
- // Join another WOL user at their location
- if (command.Compare_No_Case(L"join") == 0) {
- GameModeClass* gameMode = GameModeManager::Find("WOL");
- if (gameMode && gameMode->Is_Active()) {
- // Get the name parameter from the string
- WideStringClass user_name(64, true);
- curr_pos = Get_Parameter_From_String(curr_pos, user_name);
- if (user_name.Get_Length() > 0) {
- WolGameModeClass* wolGame = reinterpret_cast<WolGameModeClass*>(gameMode);
- wolGame->Join_WOL_User(user_name);
- }
- }
-
- return true;
- }
- }
- }
- return false;
- }
- ////////////////////////////////////////////////////////////////
- //
- // Get_Parameter_From_String
- //
- ////////////////////////////////////////////////////////////////
- const WCHAR* Get_Parameter_From_String(const WCHAR* command, WideStringClass& param)
- {
- #define LOCAL_STRIP_WHITESPACE(str) \
- while (str[0] != 0 && str[0] == L' ') {++str;}
- // Strip off whitespace
- LOCAL_STRIP_WHITESPACE(command);
- const WCHAR* curr_pos = command;
- // Look for the first whitespace break
- while (curr_pos[0] != 0 && curr_pos[0] != L' ') {
- ++curr_pos;
- }
- // Return the string contents to the caller
- int length = ((curr_pos + 1) - command);
- if (length > 0) {
- WCHAR* buffer = param.Get_Buffer(length + 1);
- wcsncpy(buffer, command, length);
- buffer[length - 1] = 0;
- }
- // Strip off whitespace
- LOCAL_STRIP_WHITESPACE(curr_pos);
- return curr_pos;
- }
- //////////////////////////////////////////////////////////////////////
- //
- // Auto_Complete_Name
- //
- //////////////////////////////////////////////////////////////////////
- void
- MPChatChildDialogClass::Auto_Complete_Name (void)
- {
- EditCtrlClass *edit_ctrl = (EditCtrlClass *)Get_Dlg_Item (IDC_MESSAGE_EDIT);
- if (edit_ctrl == NULL) {
- return ;
- }
- //
- // Examine everything left of the caret
- //
- int caret_pos = edit_ctrl->Get_Caret_Pos ();
- if (caret_pos > 0) {
- //
- // Get the message
- //
- WideStringClass message = Get_Dlg_Item_Text (IDC_MESSAGE_EDIT);
- int message_len = message.Get_Length ();
- if (message_len > 0) {
- //
- // Check to see if we are typing in a command
- //
- int cmd_start_index = 0;
- int cmd_end_index = 0;
- if (Find_Current_Command (message, cmd_start_index, cmd_end_index)) {
- cmd_start_index ++;
-
- //
- // Try to find the start of the name
- //
- const WCHAR *name_start = message.Peek_Buffer () + cmd_start_index;
- //
- // Make a copy of the first part of the message before the command
- //
- WideStringClass first_part (cmd_start_index + 1, true);
- ::wcsncpy (first_part.Peek_Buffer (), message, cmd_start_index);
- first_part.Peek_Buffer ()[cmd_start_index] = 0;
- //
- // Make a copy of the remainder of the message after the command
- //
- WideStringClass last_part (message_len - cmd_end_index, true);
- ::wcscpy (last_part.Peek_Buffer (), message.Peek_Buffer () + cmd_end_index);
-
- //
- // Copy the typed characters into their own buffer
- //
- int typed_len = caret_pos - cmd_start_index;
- WideStringClass typed_name (typed_len + 1, true);
- ::wcsncpy (typed_name.Peek_Buffer (), name_start, typed_len);
- typed_name.Peek_Buffer ()[typed_len] = 0;
- //
- // Try to complete the name that the user typed in
- //
- WideStringClass completed_name (0, true);
- Complete_Player_Name (typed_name, completed_name);
- //
- // Did we find a valid completed name?
- //
- int completed_name_len = completed_name.Get_Length ();
- if (completed_name_len >= typed_len) {
- CurrRecipientName = completed_name;
-
- //
- // Rebuild the message...
- //
- WideStringClass new_message (first_part);
- new_message += completed_name;
- new_message += last_part;
-
- //
- // Put the new text into the edit control and reset the caret
- //
- edit_ctrl->Set_Text (new_message);
- edit_ctrl->Set_Caret_Pos (caret_pos);
-
- //
- // Hilight the auto-completed characters
- //
- int hilight_end = caret_pos + (completed_name_len - typed_len);
- edit_ctrl->Set_Sel (caret_pos, hilight_end);
- } else {
- CurrRecipientName = L"";
- }
- }
- }
- }
- return ;
- }
- //////////////////////////////////////////////////////////////////////
- //
- // Complete_Player_Name
- //
- //////////////////////////////////////////////////////////////////////
- void
- MPChatChildDialogClass::Complete_Player_Name (const WCHAR *typed_name, WideStringClass &completed_name)
- {
- int typed_len = ::wcslen (typed_name);
-
- //
- // Require more then one character for any name starting with "R'. This is
- // so that Denzil's "reply to last page" code will work...
- //
- if (typed_len == 1 && (typed_name[0] == L'r' || typed_name[0] == L'R')) {
- return ;
- }
- //
- // Find the player's name that most closely matches the typed name
- //
- for ( SLNode<cPlayer> *player_node = cPlayerManager::Get_Player_Object_List ()->Head ();
- player_node != NULL;
- player_node = player_node->Next ())
- {
- cPlayer *player = player_node->Data ();
- WWASSERT (player != NULL);
- if (player->Get_Is_Active().Is_False()) {
- continue;
- }
- const WCHAR *player_name = player->Get_Name ();
- //
- // Is this the best match so far?
- //
- if (::wcsnicmp (player_name, typed_name, typed_len) == 0) {
- if ( completed_name.Get_Length () == 0 ||
- ::wcsicmp (player_name, completed_name) < 0)
- {
- completed_name = player_name;
- }
- }
- }
- return ;
- }
- //////////////////////////////////////////////////////////////////////
- //
- // On_EditCtrl_Enter_Pressed
- //
- //////////////////////////////////////////////////////////////////////
- void
- MPChatChildDialogClass::On_EditCtrl_Enter_Pressed (EditCtrlClass *edit_ctrl, int ctrl_id)
- {
- //
- // Send the message
- //
- Process_Message ();
-
- //
- // Close the dialog
- //
- if (EndDialogOnSend) {
- Get_Parent_Dialog ()->End_Dialog ();
- }
- return ;
- }
- //////////////////////////////////////////////////////////////////////
- //
- // On_EditCtrl_Change
- //
- //////////////////////////////////////////////////////////////////////
- void
- MPChatChildDialogClass::On_EditCtrl_Change (EditCtrlClass *edit_ctrl, int ctrl_id)
- {
- if (TestForAutoCompletion == false) {
- return ;
- }
- //
- // Examine everything left of the caret
- //
- int caret_pos = edit_ctrl->Get_Caret_Pos ();
- if (caret_pos > 0) {
- //
- // Get the message
- //
- WideStringClass message = Get_Dlg_Item_Text (IDC_MESSAGE_EDIT);
- if (message.Get_Length () > 0) {
- //
- // Check to see if we are typing in a command
- //
- int cmd_start_index = 0;
- int cmd_end_index = 0;
- if (Find_Current_Command (message, cmd_start_index, cmd_end_index)) {
- //
- // Fill in the rest of the name for the user
- //
- Auto_Complete_Name ();
- }
- }
- }
-
- return ;
- }
- //////////////////////////////////////////////////////////////////////
- //
- // Find_Current_Command
- //
- //////////////////////////////////////////////////////////////////////
- bool
- MPChatChildDialogClass::Find_Current_Command(const WCHAR* message, int& start_index, int& end_index)
- {
- EditCtrlClass *edit_ctrl = (EditCtrlClass *)Get_Dlg_Item (IDC_MESSAGE_EDIT);
- if (edit_ctrl == NULL) {
- return false;
- }
- bool retval = false;
- //
- // Get the caret position so we can determine where to
- // start looking for the command
- //
- int caret_pos = edit_ctrl->Get_Caret_Pos ();
- if (caret_pos > 0) {
- //
- // Look to see if there is a command designator preceding the caret.
- //
- const WCHAR *command_start = ::wcsrchr (message, L'/');
- if (command_start != NULL) {
- start_index = command_start - message;
- command_start ++;
-
- //
- // Check to ensure there isn't a space between the designator
- // and the caret
- //
- const WCHAR *first_space = ::wcschr (command_start, L' ');
- if (first_space == NULL) {
- end_index = ::wcslen (message);
- retval = true;
- } else if (caret_pos <= (first_space - message)) {
- end_index = (first_space - message);
- retval = true;
- }
- }
- }
- return retval;
- }
- //////////////////////////////////////////////////////////////////////
- //
- // On_EditCtrl_Key_Down
- //
- //////////////////////////////////////////////////////////////////////
- bool
- MPChatChildDialogClass::On_EditCtrl_Key_Down
- (
- EditCtrlClass * edit_ctrl,
- uint32 key_id,
- uint32 key_data
- )
- {
- bool retval = false;
- TestForAutoCompletion = false;
- //
- // Examine everything left of the caret
- //
- int caret_pos = edit_ctrl->Get_Caret_Pos ();
- if (caret_pos > 0) {
- //
- // Get the message
- //
- WideStringClass message = Get_Dlg_Item_Text (IDC_MESSAGE_EDIT);
- if (message.Get_Length () > 0) {
- //
- // Check to see if we are typing in a command
- //
- int cmd_start_index = 0;
- int cmd_end_index = 0;
- if (Find_Current_Command (message, cmd_start_index, cmd_end_index)) {
-
- //
- // Special-case the space key
- //
- if (key_id == VK_SPACE && CurrRecipientName.Get_Length () > 0) {
- RecipientName = CurrRecipientName;
- //
- // Erase the user's name from the string
- //
- message.Erase (cmd_start_index, cmd_end_index - cmd_start_index);
- edit_ctrl->Set_Text (message);
- edit_ctrl->Set_Caret_Pos (cmd_start_index);
- //
- // Update the dialog with the user's name...
- //
- WideStringClass heading_text(0, true);
- heading_text.Format (L"%s:", CurrRecipientName.Peek_Buffer ());
- Set_Dlg_Item_Text (IDC_TYPE_STATIC, heading_text);
- //
- // Eat the spacebar...
- //
- retval = true;
- } else if (key_id != VK_BACK && key_id != VK_DELETE) {
- TestForAutoCompletion = true;
- }
- }
- }
- }
-
- return retval;
- }
- ////////////////////////////////////////////////////////////////
- //
- // On_Command
- //
- ////////////////////////////////////////////////////////////////
- void
- MPChatChildDialogClass::On_Command (int ctrl_id, int message_id, DWORD param)
- {
- switch (ctrl_id)
- {
- case IDC_SEND:
- Process_Message ();
- if (EndDialogOnSend) {
- Get_Parent_Dialog ()->End_Dialog ();
- }
- break;
- }
- ChildDialogClass::On_Command (ctrl_id, message_id, param);
- return ;
- }
- ////////////////////////////////////////////////////////////////
- //
- // MPIngameChatPopupClass
- //
- ////////////////////////////////////////////////////////////////
- MPIngameChatPopupClass::MPIngameChatPopupClass (void) :
- DefaultType (TEXT_MESSAGE_PUBLIC),
- ChatModule (NULL),
- PopupDialogClass (IDD_MULTIPLAY_INGAME_CHAT)
- {
- //
- // Configure the background renderer
- //
- StyleMgrClass::Configure_Renderer (&WindowBackgroundRenderer);
- WindowBackgroundRenderer.Get_Shader ()->Set_Depth_Compare (ShaderClass::PASS_ALWAYS);
- return ;
- }
- ////////////////////////////////////////////////////////////////
- //
- // ~MPIngameChatPopupClass
- //
- ////////////////////////////////////////////////////////////////
- MPIngameChatPopupClass::~MPIngameChatPopupClass (void)
- {
- REF_PTR_RELEASE (ChatModule);
- return ;
- }
- ////////////////////////////////////////////////////////////////
- //
- // On_Init_Dialog
- //
- ////////////////////////////////////////////////////////////////
- void
- MPIngameChatPopupClass::On_Init_Dialog (void)
- {
- WWASSERT (The_Game () != NULL);
- //
- // Align the window with the bottom of the screen
- //
- const RectClass &screen_rect = Render2DClass::Get_Screen_Resolution ();
- RectClass window_rect = Get_Rect ();
- float height = window_rect.Height ();
- window_rect.Bottom = int(screen_rect.Bottom - 40.0F);
- window_rect.Top = int(window_rect.Bottom - height);
- Set_Rect (window_rect);
- //
- // Insert the chat module dialog into our window area
- //
- ChatModule = new MPChatChildDialogClass;
- ChatModule->Set_Default_Type (DefaultType);
- ChatModule->Start_Dialog ();
- Add_Child_Dialog (ChatModule);
- ChatModule->Set_Rect (window_rect);
- //
- // Darken the background behind this window
- //
- WindowBackgroundRenderer.Add_Quad (window_rect, RGBA_TO_INT32 (0, 0, 0, 200));
- WindowBackgroundRenderer.Enable_Texturing (false);
- //
- // Let the base class process...
- //
- Set_Background_Darkened (false);
- PopupDialogClass::On_Init_Dialog ();
- return ;
- }
- ////////////////////////////////////////////////////////////////
- //
- // Render
- //
- ////////////////////////////////////////////////////////////////
- void
- MPIngameChatPopupClass::Render (void)
- {
- //
- // Render the black backdrop
- //
- WindowBackgroundRenderer.Render ();
- //
- // Allow the base class to render
- //
- PopupDialogClass::Render ();
- return ;
- }
- ////////////////////////////////////////////////////////////////
- //
- // On_Command
- //
- ////////////////////////////////////////////////////////////////
- void
- MPIngameChatPopupClass::On_Command (int ctrl_id, int message_id, DWORD param)
- {
- /*switch (ctrl_id)
- {
- case IDOK:
- ChatModule->Send_Message ();
- End_Dialog ();
- break;
- }*/
- PopupDialogClass::On_Command (ctrl_id, message_id, param);
- return ;
- }
|