// // Copyright 2020 Electronic Arts Inc. // // TiberianDawn.DLL and RedAlert.dll and corresponding source code 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. // TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed // in the hope that it will be useful, but with permitted additional restrictions // under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT // distributed with this program. You should have received a copy of the // GNU General Public License along with permitted additional restrictions // with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection /* $Header: /CounterStrike/LIST.CPP 1 3/03/97 10:25a Joe_bostic $ */ /*********************************************************************************************** *** 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 : Command & Conquer * * * * File Name : LIST.CPP * * * * Programmer : Joe L. Bostic * * * * Start Date : 01/15/95 * * * * Last Update : January 23, 1996 [JLB] * * * *---------------------------------------------------------------------------------------------* * Functions: * * ListClass::Add -- This object adds itself to the given list * * ListClass::Add_Head -- This gadget makes itself the head of the given list. * * ListClass::Add_Item -- Adds a text item (as number) to the list box. * * ListClass::Add_Item -- Adds an item to the list box. * * ListClass::Add_Scroll_Bar -- Adds a scroll bar to the list box. * * ListClass::Add_Tail -- Add myself to the end of the given list. * * ListClass::Bump -- Bumps the list box up/down one "page". * * ListClass::Current_Index -- Fetches the current selected index. * * ListClass::Current_Item -- Fetches pointer to current item string. * * ListClass::Draw_Entry -- Draws a list box text line as indicated. * * ListClass::Draw_Me -- Draws the listbox. * * ListClass::Get_Item -- Fetches an arbitrary item string. * * ListClass::Peer_To_Peer -- A peer gadget was touched -- make adjustments. * * ListClass::Remove -- Removes the specified object from the list. * * ListClass::Remove_Item -- Remove specified text from list box. * * ListClass::Remove_Scroll_Bar -- Removes the scroll bar if present * * ListClass::Set_Selected_Index -- Set the top of the listbox to index specified. * * ListClass::Set_Tabs -- Sets the tab stop list to be used for text printing. * * ListClass::Set_View_Index -- Sets the top line for the current list view. * * ListClass::Step -- Moves the list view one line in direction specified. * * ListClass::Step_Selected_Index -- Change the listbox top line in direction specified. * * ListClass::~ListClass -- Destructor for list class objects. * * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ #include "function.h" /*************************************************************************** * ListClass::ListClass -- class constructor * * * * INPUT: id button ID * * * * x,y upper-left corner, in pixels * * * * w,h width, height, in pixels * * * * list ptr to array of char strings to list* * * * flags, style flags for mouse, style of listbox * * * * OUTPUT: none. * * * * WARNINGS: none. * * * * HISTORY: 01/05/1995 MML : Created. * *=========================================================================*/ ListClass::ListClass (int id, int x, int y, int w, int h, TextPrintType flags, void const * up, void const * down) : ControlClass(id, x, y, w, h, LEFTPRESS | LEFTRELEASE | KEYBOARD, false), UpGadget(0, up, x+w, y), DownGadget(0, down, x+w, y+h), ScrollGadget(0, x+w, y, 0, h, true) { /* ** Set preliminary values for the slider related gadgets. They don't automatically ** appear at this time, but there are some values that can be pre-filled in. */ UpGadget.X -= UpGadget.Width; DownGadget.X -= DownGadget.Width; DownGadget.Y -= DownGadget.Height; ScrollGadget.X -= max(UpGadget.Width, DownGadget.Width); ScrollGadget.Y = Y+UpGadget.Height; ScrollGadget.Height -= UpGadget.Height + DownGadget.Height; ScrollGadget.Width = max(UpGadget.Width, DownGadget.Width); /* ** Set the list box to a default state. */ TextFlags = flags; IsScrollActive = false; Tabs = 0; SelectedIndex = 0; CurrentTopIndex = 0; //PG_TO_FIX //Fancy_Text_Print(TXT_NONE, 0, 0, TBLACK, TBLACK, TextFlags); LineHeight = FontHeight+FontYSpacing-1; LineCount = (h-1) / LineHeight; } ListClass::ListClass(ListClass const & list) : ControlClass(list), TextFlags(list.TextFlags), Tabs(list.Tabs), List(list.List), LineHeight(list.LineHeight), LineCount(list.LineCount), IsScrollActive(list.IsScrollActive), UpGadget(list.UpGadget), DownGadget(list.DownGadget), ScrollGadget(list.ScrollGadget), SelectedIndex(list.SelectedIndex), CurrentTopIndex(list.CurrentTopIndex) { UpGadget.Make_Peer(*this); DownGadget.Make_Peer(*this); ScrollGadget.Make_Peer(*this); } void ListClass::Set_Position(int x, int y) { UpGadget.X = x + Width - UpGadget.Width; UpGadget.Y = y; DownGadget.X = x + Width - DownGadget.Width; DownGadget.Y = y + Height - DownGadget.Height; ScrollGadget.X = x + Width - max(UpGadget.Width, DownGadget.Width); ScrollGadget.Y = y + UpGadget.Height; ScrollGadget.Height = Height - (UpGadget.Height + DownGadget.Height); ScrollGadget.Width = max(UpGadget.Width, DownGadget.Width); } /*********************************************************************************************** * ListClass::~ListClass -- Destructor for list class objects. * * * * This is the destructor for list objects. It handles removing anything it might have * * allocated. This is typically the scroll bar. * * * * INPUT: none * * OUTPUT: none * * WARNINGS: none * * HISTORY: 01/16/1995 JLB : Created. * *=============================================================================================*/ ListClass::~ListClass(void) { Remove_Scroll_Bar(); } /*********************************************************************************************** * ListClass::Add_Item -- Adds an item to the list box. * * * * This will add the specified string to the list box. The string is added to the end * * of the list. * * * * INPUT: text -- Pointer to the string to add to the list box. * * OUTPUT: none * * WARNINGS: none * * HISTORY: 01/15/1995 JLB : Created. * *=============================================================================================*/ int ListClass::Add_Item(char const * text) { if (text) { List.Add(text); Flag_To_Redraw(); /* ** Add scroll gadget if the list gets too large to display all of the items ** at the same time. */ if (List.Count() > LineCount) { Add_Scroll_Bar(); } /* ** Tell the slider that there is one more entry in the list. */ if (IsScrollActive) { ScrollGadget.Set_Maximum(List.Count()); } } return(List.Count() - 1); } /*********************************************************************************************** * ListClass::Add_Item -- Adds a text item (as number) to the list box. * * * * This will add the text as specified by the text number provided, to the list box. * * The string is added to the end of the list. * * * * INPUT: text -- The text number for the string to add to the list box. * * OUTPUT: none * * WARNINGS: Once a string is added to the list box in this fashion, there is no method of * * retrieving the text number as it relates to any particular index in the list. * * HISTORY: * * 01/15/1995 JLB : Created. * *=============================================================================================*/ int ListClass::Add_Item(int text) { if (text != TXT_NONE) { Add_Item(Text_String(text)); } return(List.Count() - 1); } void ListClass::Remove_Item(int index) { if (index < List.Count()) { List.Delete(index); /* ** If the list is now small enough to display completely within the list box region, ** then delete the slider gadget (if they are present). */ if (List.Count() <= LineCount) { Remove_Scroll_Bar(); } /* ** Tell the slider that there is one less entry in the list. */ if (IsScrollActive) { ScrollGadget.Set_Maximum(List.Count()); } /* ** If we just removed the selected entry, select the previous one */ if (SelectedIndex >= List.Count()) { SelectedIndex--; if (SelectedIndex < 0) { SelectedIndex = 0; } } /* ** If we just removed the top-displayed entry, step up one item */ if (CurrentTopIndex >= List.Count()) { CurrentTopIndex--; if (CurrentTopIndex < 0) CurrentTopIndex = 0; if (IsScrollActive) ScrollGadget.Step(1); } } } /*********************************************************************************************** * ListClass::Remove_Item -- Remove specified text from list box. * * * * This routine will remove the specified text string from the list box. * * * * INPUT: text -- Pointer to the string to remove. * * * * OUTPUT: none * * * * WARNINGS: The text pointer passed into this routine MUST be the same text pointer that * * was used to add the string to the list. * * * * HISTORY: * * 01/15/1995 JLB : Created. * *=============================================================================================*/ void ListClass::Remove_Item(char const * text) { if (text) { Remove_Item(List.ID(text)); } } /*************************************************************************** * ListClass::Action -- If clicked on, do this! * * * * INPUT: int flags -- combination of mouse flags indicating * * what action to take. * * * * OUTPUT: bool result. * * * * WARNINGS: none. * * * * HISTORY: 01/05/1995 MML : Created. * *=========================================================================*/ int ListClass::Action(unsigned flags, KeyNumType & key) { if (flags & LEFTRELEASE) { key = KN_NONE; flags &= (~LEFTRELEASE); ControlClass::Action(flags, key); return(true); } else { /* ** Handle keyboard events here. */ if (flags & KEYBOARD) { /* ** Process the keyboard character. If indicated, consume this keyboard event ** so that the edit gadget ID number is not returned. */ if (key == KN_UP) { Step_Selected_Index(-1); key = KN_NONE; } else if (key == KN_DOWN) { Step_Selected_Index(1); key = KN_NONE; } else { flags &= ~KEYBOARD; } } else { int index = Get_Mouse_Y() - (Y+1); index = index / LineHeight; SelectedIndex = CurrentTopIndex + index; SelectedIndex = min(SelectedIndex, List.Count()-1); if (SelectedIndex == -1) SelectedIndex = 0; } } return(ControlClass::Action(flags, key)); } /*********************************************************************************************** * ListClass::Draw_Me -- Draws the listbox. * * * * This routine will render the listbox. * * * * INPUT: forced -- Should the listbox be redrawn even if it already thinks it doesn't * * need to be? This is true when something outside of the gadget system * * has trashed the screen. * * * * OUTPUT: Was the listbox redrawn? * * * * WARNINGS: none * * * * HISTORY: * * 06/25/1995 JLB : Created. * *=============================================================================================*/ int ListClass::Draw_Me(int forced) { if (GadgetClass::Draw_Me(forced)) { /* ** Turn off the mouse. */ if (LogicPage == &SeenBuff) { Conditional_Hide_Mouse(X, Y, X+Width, Y+Height); } Draw_Box (X, Y, Width, Height, BOXSTYLE_BOX, true); /* ** Draw List. */ if (List.Count()) { for (int index = 0; index < LineCount; index++) { int line = CurrentTopIndex + index; if (List.Count() > line) { /* ** Prints the text and handles right edge clipping and tabs. */ Draw_Entry(line, X+1, Y+(LineHeight*index)+1, Width-2, (line == SelectedIndex)); } } } /* ** Turn on the mouse. */ if (LogicPage == &SeenBuff) { Conditional_Show_Mouse(); } return(true); } return(false); } /*********************************************************************************************** * ListClass::Bump -- Bumps the list box up/down one "page". * * * * Use this routine to adjust the "page" that is being viewed in the list box. The view * * will move up or down (as specified) one page (screen full) of text strings. * * * * INPUT: up -- Should the adjustment be up? * * * * OUTPUT: none * * * * WARNINGS: none * * * * HISTORY: * * 01/15/1995 JLB : Created. * *=============================================================================================*/ void ListClass::Bump(int up) { if (IsScrollActive) { if (ScrollGadget.Step(up)) { CurrentTopIndex = ScrollGadget.Get_Value(); Flag_To_Redraw(); } } } /*********************************************************************************************** * ListClass::Step -- Moves the list view one line in direction specified. * * * * This routine will move the current view "page" one line in the direction specified. * * * * INPUT: up -- Should the view be moved upward? * * * * OUTPUT: none * * * * WARNINGS: none * * * * HISTORY: * * 01/15/1995 JLB : Created. * *=============================================================================================*/ void ListClass::Step(int up) { if (IsScrollActive) { if (ScrollGadget.Step(up)) { CurrentTopIndex = ScrollGadget.Get_Value(); Flag_To_Redraw(); } } } /*********************************************************************************************** * ListClass::Get_Item -- Fetches an arbitrary item string. * * * * This routine will fetch an item string from the list box. The item fetched can be any * * one of the ones in the list. * * * * INPUT: index -- The index to examine and return the text pointer from. * * * * OUTPUT: Returns with the text pointer to the string at the index position specified. * * * * WARNINGS: none * * * * HISTORY: * * 01/16/1995 JLB : Created. * *=============================================================================================*/ char const * ListClass::Get_Item(int index) const { if (List.Count() == 0) { return NULL; } index = min(index, List.Count()-1); return(List[index]); } /*********************************************************************************************** * ListClass::Current_Item -- Fetches pointer to current item string. * * * * This routine will fetch a pointer to the currently selected item's text. * * * * INPUT: none * * * * OUTPUT: Return with pointer to currently selected text. * * * * WARNINGS: none * * * * HISTORY: * * 01/16/1995 JLB : Created. * *=============================================================================================*/ char const * ListClass::Current_Item(void) const { if (List.Count() <= SelectedIndex) { return(0); } return(List[SelectedIndex]); } /*********************************************************************************************** * ListClass::Current_Index -- Fetches the current selected index. * * * * This routine will fetch the index number for the currently selected line. * * * * INPUT: none * * * * OUTPUT: Returns with the index of the currently selected line. This ranges from zero to * * the number of items in the list minus one. * * * * WARNINGS: none * * * * HISTORY: * * 01/16/1995 JLB : Created. * *=============================================================================================*/ int ListClass::Current_Index(void) const { return(SelectedIndex); } /*********************************************************************************************** * ListClass::Peer_To_Peer -- A peer gadget was touched -- make adjustments. * * * * This routine is called when one of the peer gadgets (the scroll arrows or the slider) * * was touched in some fashion. This routine will sort out whom and why and then make * * any necessary adjustments to the list box. * * * * INPUT: flags -- The event flags that affected the peer gadget. * * * * key -- The key value at the time of the event. * * * * whom -- Which gadget is being touched. * * * * OUTPUT: none * * * * WARNINGS: none * * * * HISTORY: * * 01/16/1995 JLB : Created. * *=============================================================================================*/ void ListClass::Peer_To_Peer(unsigned flags, KeyNumType &, ControlClass & whom) { if (flags & LEFTRELEASE) { if (&whom == &UpGadget) { Step(true); } if (&whom == &DownGadget) { Step(false); } } /* ** The slider has changed, so reflect the current list position ** according to the slider setting. */ if (&whom == &ScrollGadget) { Set_View_Index(ScrollGadget.Get_Value()); } } /*********************************************************************************************** * ListClass::Set_View_Index -- Sets the top line for the current list view. * * * * This routine is used to set the line that will be at the top of the list view. This is * * how the view can be scrolled up and down. This does not affect the currently selected * * item. * * * * INPUT: index -- The line (index) to move to the top of the list view. * * * * OUTPUT: bool; Was the view actually changed? * * * * WARNINGS: none * * * * HISTORY: * * 01/16/1995 JLB : Created. * *=============================================================================================*/ int ListClass::Set_View_Index(int index) { index = Bound(index, 0, max(0, List.Count() - LineCount)); if (index != CurrentTopIndex) { CurrentTopIndex = index; Flag_To_Redraw(); if (IsScrollActive) { ScrollGadget.Set_Value(CurrentTopIndex); } return(true); } return(false); } /*********************************************************************************************** * ListClass::Add_Scroll_Bar -- Adds a scroll bar to the list box. * * * * This routine will add a scroll bar (with matching arrows) to the list box. They are * * added to the right edge and cause the interior of the list box to become narrower. * * * * INPUT: none * * * * OUTPUT: bool; Was the scroll bar added? * * * * WARNINGS: The list box becomes narrower when the scroll bar is added. * * * * HISTORY: * * 01/16/1995 JLB : Created. * *=============================================================================================*/ int ListClass::Add_Scroll_Bar(void) { if (!IsScrollActive) { IsScrollActive = true; /* ** Everything has been created successfully. Flag the list box to be ** redrawn because it now must be made narrower to accomodate the new ** slider gadgets. */ Flag_To_Redraw(); Width -= ScrollGadget.Width; /* ** Tell the newly created gadgets that they should inform this list box ** whenever they get touched. In this way, the list box will automatically ** be updated under control of the slider buttons. */ UpGadget.Make_Peer(*this); DownGadget.Make_Peer(*this); ScrollGadget.Make_Peer(*this); /* ** Add these newly created gadgets to the same gadget list that the ** list box is part of. */ UpGadget.Add(*this); DownGadget.Add(*this); ScrollGadget.Add(*this); /* ** Make sure these added gadgets get redrawn at the next opportunity. */ UpGadget.Flag_To_Redraw(); DownGadget.Flag_To_Redraw(); ScrollGadget.Flag_To_Redraw(); /* ** Inform the slider of the size of the window and the current view position. */ ScrollGadget.Set_Maximum(List.Count()); ScrollGadget.Set_Thumb_Size(LineCount); ScrollGadget.Set_Value(CurrentTopIndex); /* ** Return with success flag. */ return(true); } return(false); } /*********************************************************************************************** * ListClass::Remove_Scroll_Bar -- Removes the scroll bar if present * * * * Use this routine to remove any attached scroll bar to this list box. If the scroll bar * * is not present, then no action occurs. * * * * INPUT: none * * * * OUTPUT: bool; Was the scroll bar removed? * * * * WARNINGS: none * * * * HISTORY: * * 01/16/1995 JLB : Created. * *=============================================================================================*/ int ListClass::Remove_Scroll_Bar(void) { if (IsScrollActive) { IsScrollActive = false; Width += ScrollGadget.Width; ScrollGadget.Remove(); UpGadget.Remove(); DownGadget.Remove(); Flag_To_Redraw(); return(true); } return(false); } /*********************************************************************************************** * ListClass::Set_Tabs -- Sets the tab stop list to be used for text printing. * * * * This sets the tab stop list to be used for text printing. It specifies a series of * * pixel offsets for each tab stop. The offsets are from the starting pixel position that * * the text begins at. * * * * INPUT: tabs -- Pointer to a list of tab pixel offsets. * * * * OUTPUT: none * * * * WARNINGS: Only a pointer to the tabs is recorded by the ListClass object. Make sure that * * the list remains intact for the duration of the existence of this object. * * * * HISTORY: * * 01/16/1995 JLB : Created. * *=============================================================================================*/ void ListClass::Set_Tabs(int const * tabs) { Tabs = tabs; } /*********************************************************************************************** * ListClass::Draw_Entry -- Draws a list box text line as indicated. * * * * This routine is called by the Draw_Me function when it desired to redraw a particular * * text line in the list box. * * * * INPUT: index -- The index of the list entry to draw. This index is based on the * * total list and NOT the current visible view page. * * * * x,y -- Pixel coordinates for the upper left corner of the text entry. * * * * width -- The maximum width that the text may draw over. It is expected that * * this drawing routine entirely fills this length. * * * * selected -- bool; Is this a selected (highlighted) listbox entry? * * * * OUTPUT: none * * WARNINGS: none * * HISTORY: * * 01/16/1995 JLB : Created. * *=============================================================================================*/ void ListClass::Draw_Entry(int index, int x, int y, int width, int selected) { TextPrintType flags = TextFlags; RemapControlType * scheme = GadgetClass::Get_Color_Scheme(); if (selected) { flags = flags | TPF_BRIGHT_COLOR; LogicPage->Fill_Rect (x, y, x + width - 1, y + LineHeight - 1, scheme->Shadow); } else { if (!(flags & TPF_USE_GRAD_PAL)) { flags = flags | TPF_MEDIUM_COLOR; } } Conquer_Clip_Text_Print(List[index], x, y, scheme, TBLACK, flags, width, Tabs); } /*********************************************************************************************** * ListClass::Add -- Adds myself to list immediately after given object * * * * Adds the list box to the chain, immediately after the given object. The order will be: * * - Listbox * * - Up arrow (if active) * * - Down arrow (if active) * * - Scroll gadget (if active) * * * * * INPUT: object -- Pointer to the object to be added right after this one. * * * * OUTPUT: Returns with a pointer to the head of the list. * * * * WARNINGS: none * * * * HISTORY: * * 01/19/1995 JLB : Created. * *=============================================================================================*/ LinkClass & ListClass::Add(LinkClass & list) { /* ** Add the scroll bar gadgets if they're active. */ if (IsScrollActive) { ScrollGadget.Add(list); DownGadget.Add(list); UpGadget.Add(list); } /* ** Add myself to the list, then return. */ return(ControlClass::Add(list)); } /*********************************************************************************************** * ListClass::Add_Head -- Adds myself to head of the given list * * * * INPUT: list -- list to add myself to * * * * OUTPUT: Returns with a reference to the object at the head of the list. This should be * * the same object that is passed in. * * * * WARNINGS: none * * * * HISTORY: * * 01/19/1995 JLB : Created. * *=============================================================================================*/ LinkClass & ListClass::Add_Head(LinkClass & list) { /* ** Add the scroll bar gadgets if they're active. */ if (IsScrollActive) { ScrollGadget.Add_Head(list); DownGadget.Add_Head(list); UpGadget.Add_Head(list); } /* ** Add myself to the list, then return. */ return(ControlClass::Add_Head(list)); } /*********************************************************************************************** * ListClass::Add_Tail -- Adds myself to tail of given list * * * * Adds the list box to the tail of the give chain. The order will be: * * - Listbox * * - Up arrow (if active) * * - Down arrow (if active) * * - Scroll gadget (if active) * * * * INPUT: list -- list to add myself to * * * * OUTPUT: none * * * * WARNINGS: The previous and next pointers for the added object MUST have been properly * * initialized for this routine to work correctly. * * * * HISTORY: * * 01/15/1995 JLB : Created. * *=============================================================================================*/ LinkClass & ListClass::Add_Tail(LinkClass & list) { /* ** Add myself to the list. */ ControlClass::Add_Tail(list); /* ** Add the scroll bar gadgets if they're active. */ if (IsScrollActive) { UpGadget.Add_Tail(list); DownGadget.Add_Tail(list); ScrollGadget.Add_Tail(list); } return(Head_Of_List()); } /*********************************************************************************************** * ListClass::Remove -- Removes the specified object from the list. * * * * This routine will remove the specified object from the list of objects. Because of the * * previous and next pointers, it is possible to remove an object from the list without * * knowing the head of the list. To do this, just call Remove() with the parameter of * * "this". * * * * INPUT: none * * * * OUTPUT: Returns with the new head of list. * * * * WARNINGS: none * * * * HISTORY: * * 01/15/1995 JLB : Created. * *=============================================================================================*/ GadgetClass * ListClass::Remove(void) { /* ** Remove the scroll bar if it's active */ if (IsScrollActive) { ScrollGadget.Remove(); DownGadget.Remove(); UpGadget.Remove(); } /* ** Remove myself & return */ return(ControlClass::Remove()); } /*********************************************************************************************** * ListClass::Set_Selected_Index -- Set the top of the listbox to index specified. * * * * This routine will set the top line of the listbox to the index value specified. * * * * INPUT: index -- The index to set the top of the listbox to. * * * * OUTPUT: none * * * * WARNINGS: The requested index may be adjusted to fit within legal parameters. * * * * HISTORY: * * 06/25/1995 JLB : Created. * * 01/23/1996 JLB : Forces selected index to always be zero for a null list. * *=============================================================================================*/ void ListClass::Set_Selected_Index(int index) { if (index < List.Count()) { SelectedIndex = index; Flag_To_Redraw(); if (SelectedIndex < CurrentTopIndex) { Set_View_Index(SelectedIndex); } if (SelectedIndex >= CurrentTopIndex+LineCount) { Set_View_Index(SelectedIndex-(LineCount-1)); } } else { SelectedIndex = 0; } } /*********************************************************************************************** * ListClass::Step_Selected_Index -- Change the listbox top line in direction specified. * * * * This routine will scroll the top line of the listbox in the direction specified. * * * * INPUT: step -- The direction (and amount) to adjust the listbox. If negative value, then * * the top line is scrolled upward. * * * * OUTPUT: Returns with the original top line index number. * * * * WARNINGS: none * * * * HISTORY: * * 06/25/1995 JLB : Created. * *=============================================================================================*/ int ListClass::Step_Selected_Index(int step) { int old = SelectedIndex; Set_Selected_Index(old + step); return(old); } void ListClass::Flag_To_Redraw(void) { if (IsScrollActive) { UpGadget.Flag_To_Redraw(); DownGadget.Flag_To_Redraw(); ScrollGadget.Flag_To_Redraw(); } ControlClass::Flag_To_Redraw(); } void ListClass::Set_Selected_Index(char const * text) { if (text && List.Count() > 0) { for (int index = 0; index < List.Count(); index++) { if (stricmp(List[index], text) == 0) { Set_Selected_Index(index); break; } } } }