Форум программистов, компьютерный форум, киберфорум
C++ Builder
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.73/11: Рейтинг темы: голосов - 11, средняя оценка - 4.73
 Аватар для Bigeron
4 / 4 / 0
Регистрация: 01.02.2013
Сообщений: 139

Переборка элементов

17.08.2015, 22:05. Показов 2444. Ответов 11
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Всем привет. Вопрос такой, возможно ли программно изменять имя объекта ? Поясню о чем я:

У меня есть множество элементов одного и того же класса, на пример TButton. И идея собственно в том, чтобы скомпоновать обработку элементов, а именно

не в ручную перебирать все кнопки button1, button2, button3 ... button159

C++
1
2
3
4
5
button1-> Enable = false;
button2-> Enable = false;
button3-> Enable = false;
...
button159-> Enable = false;
а объединить это всё в один цикл

C++
1
2
3
for(int i=0;i<160;i++) {
     ???
}
0
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
17.08.2015, 22:05
Ответы с готовыми решениями:

Переборка элементов матрицы для построения др. матрицы
Есть матрица 13 порядка допустим P. Из неё посредством формул надо получить S матрицу той же разрядности. ...

Переборка listbox'a
Здравствуйте, есть 2 листбокса, первый такого типа: Первый: Петров Иванов Дзагоев Пупкин Второй: Михаил петров Иван...

Переборка значений переменной
Здравствуйте, у меня появился довольно интересный вопрос.Можно ли указать несколько значений,которая принимает переменная (по очереди). Вот...

11
Практикантроп
 Аватар для nick42
4841 / 2726 / 534
Регистрация: 23.09.2011
Сообщений: 5,798
18.08.2015, 00:48
Если компоненты (кнопки) обзывались "монотонно", то достаточно создать глобальный массив, напр. myBut[160] и в цикле__
C++
1
2
3
4
5
6
    TButton *myBut[160]={0};
    int t=0,p=-1; while(++p<ComponentCount)
      if(FindComponent("button"+IntToStr(t+1)))
        myBut[t]=((TButton*)FindComponent("button"+IntToStr(t++)));
 
    for(int i=0;i<160;i++) if(myBut[i]) Memo1->Lines->Add(myBut[i]->Name);
Добавлено через 16 минут
Кстати, тут же и загадка: если вышеприведённый фрагмент стартануть на форме, где есть PageControl с 3-мя вкладками, на первой из которых Memo1, а на остальных двух по 80 кнопок, - то список в Memo выводится не полный: от Button1 до Button158 (всего компонентов насчитывает 165: 160 кнопок,Memo,PageControl и три TabSheet) Why?? Где зарыта собака?

Добавлено через 40 минут
.. одну ошибку нашёл сам_
C++
1
2
3
4
5
6
    Caption = ComponentCount;
    int t=0,p=-1; while(++p<ComponentCount)
      if(FindComponent("Button"+IntToStr(t+1)))
        myBut[t]=((TButton*)FindComponent("Button"+IntToStr([COLOR="Blue"]1+t++[/COLOR])));
 
    for(int i=0;i<161;i++) if(myBut[i]) Memo1->Lines->Add(myBut[i]->Name);
а вот почему в цикле вывода в мэмо при ограничителе в 160 выводится последней не Button160, а Button159, а при ограничителе 161 (должен быть вылет за пределы индексов) показывает правильно - не пойму... .
0
 Аватар для kodv
1449 / 1121 / 347
Регистрация: 11.04.2011
Сообщений: 2,621
18.08.2015, 05:39
nick42, Выполните в уме или на бумажке все действия согласно очередности в следующей строке
C++
1
myBut[t]=((TButton*)FindComponent("Button"+IntToStr(1+t++)))
И тогды вы поймете, что Button1 записывается в myBut[1], а не в myBut[0], как ожидаете, так как myBut[t] выполняется уже после t++.
0
Практикантроп
 Аватар для nick42
4841 / 2726 / 534
Регистрация: 23.09.2011
Сообщений: 5,798
18.08.2015, 08:09
Верно! Про очерёдность я как-то не подумал. Тогда правильнее так__
C++
1
2
3
4
5
6
7
8
9
10
11
12
     TButton *myBut[160]={0};
//---------------------------------------------------------------------------
void __fastcall TForm1::TabSheet1ContextPopup(TObject *Sender,
      TPoint &MousePos, bool &Handled)
{
    Caption = ComponentCount;
    int t=0,p=-1; while(++p<ComponentCount)
      if(FindComponent("Button"+IntToStr(t+1)))
        myBut[t++]=((TButton*)FindComponent("Button"+IntToStr(t+1))); 
    for(int i=0;i<160;i++) if(myBut[i]) Memo1->Lines->Add(myBut[i]->Name);
}
//---------------------------------------------------------------------------
0
управление сложностью
 Аватар для Почтальон
1693 / 1306 / 259
Регистрация: 22.03.2015
Сообщений: 7,545
Записей в блоге: 5
18.08.2015, 09:21
Так, вроде, же недавно было похожее, перебор компонент
Как урезать код (CheckBox)
0
Модератор
 Аватар для D1973
9929 / 6466 / 2457
Регистрация: 21.01.2014
Сообщений: 27,422
Записей в блоге: 3
18.08.2015, 11:06
Вот так можно (без привязки к имени компонента)
C++
1
2
3
for(int i = 0; i < this->ControlCount; i++)
   if(this->Controls[i]->ClassNameIs("TButton"))
    ((TButton *)Controls[i])->Enabled = false;
0
Супер-модератор
Эксперт Pascal/DelphiАвтор FAQ
 Аватар для volvo
33404 / 21514 / 8236
Регистрация: 22.10.2011
Сообщений: 36,914
Записей в блоге: 12
18.08.2015, 12:56
Я бы вообще перегрузил в форме обработку сообщения об изменении списка контролов:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
// класс формы
// ...
private:
    void __fastcall CMControlListChange(TCMControlListChange& Message);
protected:
    BEGIN_MESSAGE_MAP
        VCL_MESSAGE_HANDLER(CM_CONTROLLISTCHANGE, TCMControlListChange, CMControlListChange)
    END_MESSAGE_MAP(TForm)
// ...
 
// реализация
void __fastcall TForm1::CMControlListChange(TCMControlListChange& Message)
{
    TForm::Dispatch(&Message);
    if(Message.Inserting && (Message.Control->ClassNameIs("TButton")))
    {
        // заносим все кнопки в какой-нибудь контейнер, например в std::list или std::vector
    }
}
, и потом спокойно бы в самом простом цикле работал бы с элементами контейнера, и делал бы с ними то, что нужно... Если какие-то кнопки не нужно обрабатывать - всегда можно выставить им в дизайнере Tag, отличный от 0, и добавить еще одно условие для проверки. И не надо ничего заполнять вручную, и при любом добавлении кнопки на форму (хоть через дизайнер, хоть динамически) она будет уже учитываться при следующем запуске программы...
1
Практикантроп
 Аватар для nick42
4841 / 2726 / 534
Регистрация: 23.09.2011
Сообщений: 5,798
18.08.2015, 17:06
Я попробовал с эдитами (10 шт. на табшитах) по примеру volvo, и не могу понять, почему не отрабатывает изменение стиля__
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
      std::vector<TEdit*>mEd(20);
//---------------------------------------------------------------------------
void __fastcall TForm1::CMControlListChange(TCMControlListChange& Message)
{
    TForm::Dispatch(&Message);
    if(Message.Inserting && (Message.Control->ClassNameIs("TEdit")))
    {
      static int dx=0;
      mEd[dx] = (TEdit*)Message.Control;
      DWORD oldStyle = GetWindowLong(mEd[dx]->Handle, GWL_STYLE);
      DWORD newStyle = (oldStyle & ~(ES_CENTER | ES_LEFT)) | ES_RIGHT;
      SetWindowLong(mEd[dx]->Handle, GWL_STYLE, newStyle);
      mEd[dx]->Repaint();
      dx++;
    }
}
//---------------------------------------------------------------------------
void __fastcall TForm1::FormCreate(TObject *Sender)
{
      DWORD oldStyle = GetWindowLong(mEd[1]->Handle, GWL_STYLE);
      DWORD newStyle = (oldStyle & ~(ES_CENTER | ES_LEFT)) | ES_RIGHT;
      SetWindowLong(mEd[1]->Handle, GWL_STYLE, newStyle);
      mEd[1]->Repaint();
}
Это немного не в тему, но всё же... - почему с эдитом2 всё сработало (текст справа) из обработчика FormCreate, а в блоке ControlChange эти мои манипуляции смысла не имеют? И, кстати, как это оформляется через вектор ПРАВИЛЬНО, а не по моему?

Добавлено через 1 час 57 минут
П.С. Пока пришёл у выводу, что обработка при ControlChange "запаздывает" (или типа того). Потому что переделанная таким образом...
C++
1
2
3
4
5
6
7
8
9
10
11
12
void __fastcall TForm1::CMControlListChange(TCMControlListChange& Message)
{
    TForm::Dispatch(&Message);
    if(Message.Inserting && (Message.Control->ClassNameIs("TEdit")))
    {
      static int dx=0;
      mEd[dx] = (TEdit*)Message.Control;
      HWND hw = dx==0 ? mEd[0]->Handle : mEd[dx-1]->Handle;
      SetWindowLong(hw, GWL_STYLE, 0x02L); 
      dx++;                  
    }
}
функция даёт результат (кроме, естественно, последнего в списке эдита): у всех обработанных эдитов стиль меняется. А вот почему?...

Добавлено через 6 минут
.. исправьте, кто понимает. Тестовое приложение, на котором я экспериментирую, после корректировки эдитов вообще входит в ступор... - не реагирует на переключение вкладки, на попытку вызвать системное меню или просто закрыть приложение. Ужас.
0
Супер-модератор
Эксперт Pascal/DelphiАвтор FAQ
 Аватар для volvo
33404 / 21514 / 8236
Регистрация: 22.10.2011
Сообщений: 36,914
Записей в блоге: 12
18.08.2015, 17:20
Это вообще некорректный способ установки стилей, MSDN явно говорит:
After the control has been created, these styles cannot be modified, except as noted.
(никаких замечаний по поводу того, что можно с помощью SetWindowLong применять стили ES_CENTER, ES_LEFT, ES_RIGHT по ссылке нет)

Не надо играть против правил ОС - не будет неожиданностей.
1
Практикантроп
 Аватар для nick42
4841 / 2726 / 534
Регистрация: 23.09.2011
Сообщений: 5,798
18.08.2015, 19:35
Что касается "ступора" программы, то тут всё просто. Запивая тараньку, я вдруг тихо осознал, что нельзя вот так запросто с тонкими свойствами компонента формы. Если вот ту 0x02L заменить на более правильное 0x440100C2L, то всё нормально устаканивается, и те же эдиты становятся послушными как овечки. Хотя, конечно, правильнее всё же как рекомендуется, - использовать старое значение, изменив в нём лишь несколько нужных битов. Сложнее с объяснением поведения программы. Нет! я могу, конечно, понять, что вмешался с изменением свойств компонента прямо на этапе его создания, и система просто проигнорировала вписанные мной в структуру (вернее: заготовку для структуры) компонента значения, заменив их шаблонными и ничего мне об этом не сообщив. Но ведь не было ни разу сообщения об ошибке, даже "варнинга".
0
Супер-модератор
Эксперт Pascal/DelphiАвтор FAQ
 Аватар для volvo
33404 / 21514 / 8236
Регистрация: 22.10.2011
Сообщений: 36,914
Записей в блоге: 12
19.08.2015, 11:24
Цитата Сообщение от nick42 Посмотреть сообщение
я могу, конечно, понять, что вмешался с изменением свойств компонента прямо на этапе его создания
Еще раз повторяю: нельзя подобным образом менять стили компонента. Для того, чтобы сделать это корректно - нужно перегрузить метод CreateParams в классе-перехватчике TEdit:
C++
1
2
3
4
5
6
7
8
9
10
    class TEdit : public Stdctrls::TEdit
    {
    public:
        __fastcall virtual TEdit(Classes::TComponent* AOwner) : Stdctrls::TEdit(AOwner) {}
        virtual void __fastcall CreateParams(TCreateParams& Params)
        {
                Stdctrls::TEdit::CreateParams(Params);
                Params.Style = (Params.Style & ~(ES_CENTER | ES_LEFT)) | ES_RIGHT;
        };
    };
, а не пытаться после создания компонента вмешиваться в его поведение. Для приведенного тобой примера обработка CM_CONTROLLISTCHANGE просто не нужна, это не тот случай. Именно потому, что после того, как элемент добавлен на форму, с ним уже нельзя проделывать все эти вещи. То, что оно у тебя работает - это еще не показатель. Программа в любом случае некорректна, потому что явно нарушает то, что написано в MSDN - то есть, инструкцию производителя ОС. Сегодня работает - завтра (или после перезагрузки, или в зависимости от положения Сатурна в ночном небе) перестанет.

Ну, или (на новых версиях Билдера) изменение Alignment-а Edit-ов на taRightJustify в методе CMControlListChange. Это не будет нарушать запретов MS.

А вот для случая, описанного в первом посте, отлов CM_CONTROLLISTCHANGE - то, что нужно. Потому что работать со свойством Enabled можно в любой момент после создания компонента.
0
Практикантроп
 Аватар для nick42
4841 / 2726 / 534
Регистрация: 23.09.2011
Сообщений: 5,798
19.08.2015, 12:20
Цитата Сообщение от volvo Посмотреть сообщение
элемент добавлен на форму
Ну, добавлен... - и что? Во всех встречающихся в сети примерах изменения стиля TEdit в конце операций стоит Edit->Repaint(). Рипэйнт перерисовывает компонент практически "с нуля" в соответствии с его обновленным шаблоном. И в моей практике я не помню ни одного случая неприятностей с таким компонентом впоследствии.
И по поводу метода присвоения
Цитата Сообщение от nick42 Посмотреть сообщение
mEd[dx] = (TEdit*)Message.Control;
я так и не услышал возражений. Что, действительно такой приём правильный и другого не существует?
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
19.08.2015, 12:20
Помогаю со студенческими работами здесь

Переборка комбинаций объектов
Добрый вечер всем! Извиняюсь, если вопрос дурацкий, просто не знаю даже, что конкретно искать в гугле (наверное, комбинаторика?) ...

В массиве A из N элементов (N не больше 30) определить количество элементов, имеющих четные значения, и сумму этих элементов.
1. В массиве A из N элементов (N не больше 30) определить количество элементов, имеющих четные значения, и сумму этих элементов. Число N и...

Найти количество элементов, больших среднего всех элементов массива и максимум из элементов с четным номером
1. количество элементов, больших среднего арифметического всех элементов массива; 2. самый большой из элементов с четным номером; ...

Найти суммы четных элементов (элементов с четным номером) массива вещественных чисел A(22) и нечетных элементов
Здравствуйте, дорогие форумчане. Не могли бы вы мне помочь? Мне нужно составить программу с таким условием: &quot;Найти суммы четных...

Определить сумму указанных элементов, количество нечетных элементов и среднее арифметическое четных элементов массива
Дан двумерный массив целых чисел. Определить: 1. Сумму элементов массива, больших 30 2. Количество нечетных элементов массива 3....


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

Или воспользуйтесь поиском по форуму:
12
Ответ Создать тему
Новые блоги и статьи
Программный контроль заполнения реквизита табличной части документа
Maks 02.04.2026
Алгоритм из решения ниже реализован на примере нетипового документа "СписаниеМатериалов", разработанного в конфигурации КА2. Задача: реализовать контроль заполнения реквизита "ПричинаСписания". . .
wmic не является внутренней или внешней командой
Maks 02.04.2026
Решение: DISM / Online / Add-Capability / CapabilityName:WMIC~~~~ Отсюда: https:/ / winitpro. ru/ index. php/ 2025/ 02/ 14/ komanda-wmic-ne-naydena/
Программная установка даты и запрет ее изменения
Maks 02.04.2026
Алгоритм из решения ниже реализован на примере нетипового документа "СписаниеМатериалов", разработанного в конфигурации КА2. Задача: при создании документов установить период списания автоматически. . .
Вывод данных в справочнике через динамический список
Maks 01.04.2026
Реализация из решения ниже выполнена на примере нетипового справочника "Спецтехника" разработанного в конфигурации КА2. Задача: вывести данные из ТЧ нетипового документа. . .
Программное заполнения текстового поля в реквизите формы документа
Maks 01.04.2026
Алгоритм из решения ниже реализован на нетиповом документе "ВыдачаОборудованияНаСпецтехнику" разработанного в конфигурации КА2, в дополнении к предыдущему решению. На форме документа создается. . .
К слову об оптимизации
kumehtar 01.04.2026
Вспоминаю начало 2000-х, университет, когда я писал на Delphi. Тогда среди программистов на форумах активно обсуждали аккуратную работу с памятью: нужно было следить за переменными, вовремя. . .
Идея фильтра интернета (сервер = слой+фильтр).
Hrethgir 31.03.2026
Суть идеи заключается в том, чтобы запустить свой сервер, о чём я если честно мечтал давно и давно приобрёл книгу как это сделать. Но не было причин его запускать. Очумелые учёные напечатали на. . .
Модель здравосоХранения 6. ESG-повестка и устойчивое развитие; углублённый анализ кадрового бренда
anaschu 31.03.2026
В прикрепленном документе раздумья о том, как можно поменять модель в будущем
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru