Форум программистов, компьютерный форум, киберфорум
C++ Builder
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 5.00/18: Рейтинг темы: голосов - 18, средняя оценка - 5.00
44 / 2 / 0
Регистрация: 12.11.2009
Сообщений: 40

Запомнить текущее состояние компонентов (для таймера)

17.04.2011, 11:37. Показов 3663. Ответов 18
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Возможно ли? Поясню: Есть, допустим, StringGrid1 с двумя строками, вторая пустая, есть StringGrid2, допустим, тоже с двумя строками, вторая пустая, есть ValueListEditor - тоже пустой
Теперь - есть таймер, который через каждую секунду принимает данные с сервера, и раскидывает их по этим компонентам.
Если тупо в таймер вогнать прием с сервера, то выйдет фигня. Надо, что бы компоненты, так сказать, стирали из себя предыдущие поступившие данные, и вписывали новые.

Или может есть более простое решение?

p.s. И так, что бы скроллы не шалили)
0
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
17.04.2011, 11:37
Ответы с готовыми решениями:

Запомнить состояние двухсот CheckBox
Добрый день подскажите как организовать такую задачу, есть форма на ней расположено более 200 CheckBox, необходимо состояние каждого...

Запомнить состояние строк
Как можно реализовать сохранение в Ini-файл последовательность строк после сортировки в DBGrid. Намикните пожалуйста.

Стоит запрет записи на флеш
такая же проблема, что может быть не пойму, уважаемые может кто знает как решить эту проблему? на скрине есть один интересный факт:...

18
 Аватар для cpp_developer
20124 / 5691 / 417
Регистрация: 09.04.2010
Сообщений: 22,546
Записей в блоге: 1
17.04.2011, 14:57
можно использовать для всего этого ReplaceString()
0
44 / 2 / 0
Регистрация: 12.11.2009
Сообщений: 40
17.04.2011, 15:58  [ТС]
эм. Быстрое гугление что-то ничего интересного не показало, маны по ф1 не работают)) Можно поподробнее про эту функцию?
0
 Аватар для cpp_developer
20124 / 5691 / 417
Регистрация: 09.04.2010
Сообщений: 22,546
Записей в блоге: 1
17.04.2011, 16:08
C++
1
2
3
4
5
6
7
lAnsiStrings S1= "Можно поподробнее про эту функцию? "; 
AnsiStrings S2 = "эту";
AnsiStrings S3 = "другую";
S1 = StringReplace(S1, S2, S3, TReplaceFlags()
                   << rfReplaceAll // заменить все
                   << rfIgnoreCase); // без учета регистра
ShowMessage(S1);
0
44 / 2 / 0
Регистрация: 12.11.2009
Сообщений: 40
17.04.2011, 16:57  [ТС]
Не, чет это не то. У меня с сервера приходит инфа, забивает компоненты. Начальное состояние, к примеру, стрингГрида - две строки (3 столбца). Когда с серва инфа пришла, то она показывается в стрингГриде. К примеру это еще плюс 4 строки. В итоге видим СтрингГрид с шестью строками. Таймер установлен на 1 сек - через секунду снова посылается запрос, снова идет инфа, снова в стрингГрид - но в нём уже забита инфа. Вот вопрос - так как не хочется прописывать начальное состояние стрингГрида в ноль, через цикл, чтобы через секунду он очищался и принимал новые данные , то, может, есть решение проще и красивее?
И вдобавок получается, если очищать, например, какой-нибудь ValueList, то скролл всё время в верх поднимается, и каждую секунду так и будет - тоже не очень хорошо.
0
 Аватар для cpp_developer
20124 / 5691 / 417
Регистрация: 09.04.2010
Сообщений: 22,546
Записей в блоге: 1
17.04.2011, 17:10
зачем очищать ? можно просто менять запись, и не объязательно через StringReplace
C++
1
2
3
if (ЧтоНибудь) {
 StringGrid->Cells[i][j] = ТоЧтоВашеЧтоНибудьПринесло;
}
0
44 / 2 / 0
Регистрация: 12.11.2009
Сообщений: 40
17.04.2011, 17:21  [ТС]
Не подходит Если строк придет меньше, чем было, то лишнее останется.
0
 Аватар для cpp_developer
20124 / 5691 / 417
Регистрация: 09.04.2010
Сообщений: 22,546
Записей в блоге: 1
17.04.2011, 17:28
а сравнить RowsCount с тем, что пришло, папка с мамкой не научили ?
0
44 / 2 / 0
Регистрация: 12.11.2009
Сообщений: 40
17.04.2011, 17:34  [ТС]
Так что-то совсем мудрено будет... особенно с моим личным парсером

Добавлено через 1 минуту
Хотяяяяя.... по сути то мне надо всего два стрингГрида обновлять. Ох уж этот быдлокод =/
0
 Аватар для cpp_developer
20124 / 5691 / 417
Регистрация: 09.04.2010
Сообщений: 22,546
Записей в блоге: 1
17.04.2011, 17:38
Цитата Сообщение от DizzWebS Посмотреть сообщение
Так что-то совсем мудрено будет... особенно с моим личным парсером

Добавлено через 1 минуту
1. Хотяяяяя.... по сути то мне надо всего два стрингГрида обновлять. 2. Ох уж этот быдлокод =/
1. речь в самом начале шла про две строки .
2. не обижай код - уйдет в запой .
0
44 / 2 / 0
Регистрация: 12.11.2009
Сообщений: 40
17.04.2011, 17:48  [ТС]
ну 1 - да, согласен, я изначально чуть не так выразился. А 2 - в принципе по таймеру циклом проходиться по стрингГрид - делать две строчки, и занулять их. Потом записывать туда данные. На данный момент, надеюсь, работающий вариант. А вообще лучше посижу поразбираюсь, может чего еще в голову придет
0
 Аватар для cpp_developer
20124 / 5691 / 417
Регистрация: 09.04.2010
Сообщений: 22,546
Записей в блоге: 1
17.04.2011, 17:53
это
C++
1
StringGrid->Cells[i][j] = ТоЧтоВашеЧтоНибудьПринесло;
не будет само менять строку, без лишних телодвижений ?
0
44 / 2 / 0
Регистрация: 12.11.2009
Сообщений: 40
17.04.2011, 18:45  [ТС]
Таким способом я и буду делать.

Добавлено через 33 минуты
Блин, честно говоря, фигня какая-то получается совсем, эх... Надо как-то по другому делать
Короче, приведу явный пример, как делаю я. Возможно это совсем не правильно.
В общем раньше у меня было так:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
IdUDPClient1->Active = true;
 
Sysutils::TBytes ReceiveBuff; // честно говоря, не совсем понимаю, для чего нужны
ReceiveBuff.set_length(1800);   // эти две строчки, и что они конкретно делают, 
                                             // но просто нашел такое вот решение
 
//Ну дальше понятно, добавляю в комбобокс адрес:порт сервера
ComboBox1->Items->Add(IdUDPClient1->Host + ":" + IdUDPClient1->Port);
ComboBox1->ItemIndex = 0;
 
//Дальше отправляю на сервер команду
char *gstats = "\xff\xff\xff\xff getstatus";
IdUDPClient1->SendBuffer(RawToBytes(gstats,strlen(gstats)));
 
//Принимаю ответ с сервера
IdUDPClient1->ReceiveBuffer(ReceiveBuff, 1000);
//строчка приходит вида Admin\AdminName\_Param1\1\Param_3\asdf\ServName\Name Of server\1(дальше тут идет перенос строки \n и строка принимает след. вид)3 56 "nickname 1"(снова \n)7 38 "name2"(\n)7 42 "asdf" и т.д.
 
 
//дальше идут костыли с парсингом
AnsiString str;
for(int i=20;ReceiveBuff[i]!=0;i++)
   str += (char)ReceiveBuff[i]; //заносим пришедшую инфу в str
 
AnsiString param = str; //(копия) Заносим в param всё из str
 
//---------- собираем param ---------------   параметры сервера
int idx = param.Pos('\n'); //Ищем первое вхождение \n по байтам
int all = strlen(param.c_str()); //берем всю длину строки
int kostil = all - idx; //делаем костыль в виде кол-ва нужных байт
param.Delete(idx,kostil); //удаляем от idx на кол-во байт kostil
 
//Memo1->Lines->Add("Параметры: " + param);
 
//------------ собираем str ----------------   игроки сервера
str.Delete(1,idx);
 
// И вот дальше приведу пример для первого СтрингГрида
 
TStringList *list = new TStringList;
list->StrictDelimiter = true;
list->Delimiter = '\\';
list->DelimitedText = param;
 
StringGrid1->Cells[0][0] = "Название сервера";
StringGrid1->Cells[1][0] = "Режим";
StringGrid1->Cells[2][0] = "Карта";
StringGrid1->Cells[3][0] = "Игроки";
StringGrid1->Cells[4][0] = "Пинг";
 
for (int i=0; i < list->Count; i++)
{
   if (list->Strings[i] == "sv_hostname")
   {
      StringGrid1->Cells[0][1] = list->Strings[i+1];
   }
 
   if (list->Strings[i] == "g_gametype")
   {
      StringGrid1->Cells[1][1] = list->Strings[i+1];
   }
 
   if (list->Strings[i] == "mapname")
   {
      StringGrid1->Cells[2][1] = list->Strings[i+1];
   }
 
   if (list->Strings[i] == "sv_maxclients")
   {
      if (StringGrid2->Cells[1][0]!=NULL)
      {
         StringGrid1->Cells[3][1] = AnsiString(StringGrid2->RowCount-1) + "/" + list->Strings[i+1]; // тут пока более лучшего решения не нашел. Потом придумаю лучше.
      } else {
         StringGrid1->Cells[3][1] = "0/" + list->Strings[i+1];
      }
   }
 
delete list;
list = NULL;
В общем тут вроде всё написал основное, что надо, и если это всё написать на FormCreate, то работает просто отлично, все данные принимает просто на ура, и всё по полочкам раскладывает так же отлично. Но мне требуется принимать данные каждую секунду или две, у меня программа мониторит сервер. И если это тупо вписать в таймер, то будет вылазить ошибка что-то про List out of bounds (какое-то число, зависящее от кол-ва игроков на сервере кажется).
И, допустим, если в другом стрингГриде если выбрать ячейку, то через секунду выберется станадртная первая ячейка. Или если переместить столбцы, то через секунду они так же вернутся так, как были раскиданы вначале. Соответственно, если СкроллБар переместить вниз, то через секунду он снова скакнёт наверх в исходное положение.

Вот какое решение можно сделать, что бы всё динамически обновлялось, но при этом не терялись позиции элементов? Мне кажется, у меня что-то крутится в голове, но никак не могу собрать мысли все воедино, потому что за прогой несколько дней подряд с утра до вечера сижу))
Ох, надеюсь, нормально объяснил)
0
 Аватар для cpp_developer
20124 / 5691 / 417
Регистрация: 09.04.2010
Сообщений: 22,546
Записей в блоге: 1
17.04.2011, 18:59
List out of bounds - в списке нет записей
1
44 / 2 / 0
Регистрация: 12.11.2009
Сообщений: 40
17.04.2011, 19:36  [ТС]
Самое смешное, что тот код, который я привел выше, прекрасно работает. Сложности возникают с этим (он расположен сразу после кода, что я привел выше):
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
TStringList *gamers = new TStringList;
gamers->DelimitedText = str;
 
   StringGrid2->Cells[0][0] = "Имя";
   StringGrid2->Cells[1][0] = "Фраги";
   StringGrid2->Cells[2][0] = "Пинг";
 
   int j=1;
   for (int i=0; i < gamers->Count; i++)
   {
 
          StringGrid2->Cells[0][j] = gamers->Strings[i+2];
          StringGrid2->Cells[1][j] = gamers->Strings[i];
          StringGrid2->Cells[2][j] = gamers->Strings[i+1];
          i+=2;
          j++;
          StringGrid2->RowCount = j;
   }
 
delete gamers;
gamers = NULL;
то есть надо сделать так, что бы gamers не забивался всякой фигнёй, и условие, если он не пустой, то выполнить код.. вроде так...

p.s. Да, код тут ппц какой)
0
 Аватар для cpp_developer
20124 / 5691 / 417
Регистрация: 09.04.2010
Сообщений: 22,546
Записей в блоге: 1
17.04.2011, 19:51
C++
1
2
if (gamers->Count != 0) {
  for (int i=0; i < gamers->Count; i++) {
0
44 / 2 / 0
Регистрация: 12.11.2009
Сообщений: 40
18.04.2011, 11:53  [ТС]
Не, так уже делал, не помогало. Я думаю, сделать проверку, если многократно посылать команду и принимать буфер, что получится, не присылает ли он чего лишнего, если не присылает, то проверку иф (str!="") создаем лист gamers. Ох, чето еще какие-то мысли были, но вылетели. Ща, в общем, попробую всё.

Добавлено через 14 часов 43 минуты
В принципе получилось сделать, что бы не вылетало ошибок, сделав вот так:
C++
1
2
//------------ собираем str ----------------   игроки сервера
str.Delete(1,idx+1);
потому что мы же '\n' искали, а занесся по .Pos байт, в котором хранится '\'. Хотя это странно, потому что без таймера все нормально было и лишних символов не рисовалось.

Теперь не знаю, как такое побороть: при каждой секунде таймера все фокусы, все скроллы и колонки таблиц возвращаются в исходное положение. Само собой не всех компонентов, а только тех, которые в таймере висят.

Добавлено через 41 минуту
точнее нет, не так сделал, вот так:
C++
1
2
3
4
5
6
if (kostil<6) {
str.Delete(1,idx+1);
Memo1->Lines->Add(str);
} else {
   str=NULL;
}
И теперь у меня str всё время обнуляется.

Добавлено через 1 минуту
Что-то я вообще на грани паники блин =/
0
 Аватар для cpp_developer
20124 / 5691 / 417
Регистрация: 09.04.2010
Сообщений: 22,546
Записей в блоге: 1
18.04.2011, 17:18
наверное, потому, что у тебя kostil всегда <6
0
44 / 2 / 0
Регистрация: 12.11.2009
Сообщений: 40
18.04.2011, 19:10  [ТС]
по идее если на сервере будут игроки, то там должна быть строка, к примеру 3 46 "nickname". Хм, хотя появился еще вариант - проверить длину строки, что после \n идет не через костыль))
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
18.04.2011, 19:10
Помогаю со студенческими работами здесь

Текущее состояние дел
Итак. Дело с новой партией худо бедно пошло. Поставщики комплектухи почти вышли из новогоднего коматоза, монтажники загружены и первые...

TTimer текущее состояние
Добрый день, Возникла такая проблемка, запускаю таймер и нужно по нажатию узнать сколько он натикал в данный момент, но у него никаких...

текущее состояние сокета
здравствуйте! никто не подскажет как можно проверить текущее состояние сокета, точнее даже будет так: предположим работает сервер и...

Проверить текущее состояние клавиши
Собственно делаю прогу и надо проверить состояние клавиши NumLock без использования обработчиков,тоесть в реальном времени,т.е активирована...

MediaElement. Не определяет текущее состояние
Здравствуйте. Делаю плеер. Есть кнопка при нажатии на которую плеер будет либо останавливаться, если он запущен, либо наоборот. Пишу...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
19
Ответ Создать тему
Новые блоги и статьи
SDL3 для Web (WebAssembly): Реализация движения на Box2D v3 - трение и коллизии с повёрнутыми стенами
8Observer8 20.02.2026
Содержание блога Box2D позволяет легко создать главного героя, который не проходит сквозь стены и перемещается с заданным трением о препятствия, которые можно располагать под углом, как верхнее. . .
Конвертировать закладки radiotray-ng в m3u-плейлист
damix 19.02.2026
Это можно сделать скриптом для PowerShell. Использование . \СonvertRadiotrayToM3U. ps1 <path_to_bookmarks. json> Рядом с файлом bookmarks. json появится файл bookmarks. m3u с результатом. # Check if. . .
Семь CDC на одном интерфейсе: 5 U[S]ARTов, 1 CAN и 1 SSI
Eddy_Em 18.02.2026
Постепенно допиливаю свою "многоинтерфейсную плату". Выглядит вот так: https:/ / www. cyberforum. ru/ blog_attachment. php?attachmentid=11617&stc=1&d=1771445347 Основана на STM32F303RBT6. На борту пять. . .
Камера Toupcam IUA500KMA
Eddy_Em 12.02.2026
Т. к. у всяких "хикроботов" слишком уж мелкий пиксель, для подсмотра в ESPriF они вообще плохо годятся: уже 14 величину можно рассмотреть еле-еле лишь на экспозициях под 3 секунды (а то и больше),. . .
И ясному Солнцу
zbw 12.02.2026
И ясному Солнцу, и светлой Луне. В мире покоя нет и люди не могут жить в тишине. А жить им немного лет.
«Знание-Сила»
zbw 12.02.2026
«Знание-Сила» «Время-Деньги» «Деньги -Пуля»
SDL3 для Web (WebAssembly): Подключение Box2D v3, физика и отрисовка коллайдеров
8Observer8 12.02.2026
Содержание блога Box2D - это библиотека для 2D физики для анимаций и игр. С её помощью можно определять были ли коллизии между конкретными объектами и вызывать обработчики событий столкновения. . . .
SDL3 для Web (WebAssembly): Загрузка PNG с прозрачным фоном с помощью SDL_LoadPNG (без SDL3_image)
8Observer8 11.02.2026
Содержание блога Библиотека SDL3 содержит встроенные инструменты для базовой работы с изображениями - без использования библиотеки SDL3_image. Пошагово создадим проект для загрузки изображения. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru