Форум программистов, компьютерный форум, киберфорум
C++ Builder
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.67/15: Рейтинг темы: голосов - 15, средняя оценка - 4.67
 Аватар для mr sinister
1 / 1 / 0
Регистрация: 28.01.2014
Сообщений: 49

Перегрузка обработчика событий

26.04.2014, 14:00. Показов 3106. Ответов 6
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Я хочу создать прямоугольное поле клеток (используя список). Сами "клетки" это просто наследники от кнопок, собственно кроме пары свойств, все, что мне нужно поменять, это событие клика для них. Когда я делал что то похожее на C++/CLR в ВидимойСтудии, я просто передавал указатель на функцию конструктору обработчика событий, и по событию автоматически вызывалась эта функция.
Выглядело это примерно так:
.h
C++
1
2
3
4
cell(<...>, System::EventHandler^ eh) : {
        <...>;
        Click += eh;
    }
.cpp
C++
1
List^ list = gcnew List(<...>, gcnew System::EventHandler(^Form1, &Form1::cell_Click));
Погуглив про наследование управляемых компонентов в Ц++ Билдере, я понял, что это не просто написать двоеточие при объявлении пользовательского класса и написать родителя. Это некое "Создание компонента". Так вот, сам "компонент" в моем случае не что-то серьезное, а одноразовая мелочь, посему ни создавать новый пакет (package), ни добавлять в существующий желания нет, поэтому я создал модуль (unit). однако если без этого никак, сообщите
Собственно вопросы:
1. Где и как в [cut] заголовочном файле[/URL] модуля писать объявление обработчика событий?
2. Где и как в [cut] основном файле[/URL] модуля писать реализацию?
3. Как мне, собственно, использовать написанный пользовательский класс в проекте, к которому я этот модуль добавил? Например, достаточно ли просто "включать" (#include) этот модуль в те .h и .cpp файлы, где я хочу объявлять переменные пользовательского типа и собственно объявлять их? Или нужны дополнительные телодвижения?
0
Лучшие ответы (1)
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
26.04.2014, 14:00
Ответы с готовыми решениями:

Отделение работы обработчика событий клавиатуры от событий ввода текста в поля редактирования
Проблема: есть форма с графическими компонентами, в которых редактируется текст. И вот проблема - обработчик событий клавиатуры...

Задачи на использование событий. Осуществить использование событий в программе с применением синтаксиса обработчика, рекомендованного для среды NET Fr
NET Framework. Программа для поиска простых чисел среди чисел Фибоначчи. При нахождении очередного простого числа активировать событие...

Вызов обработчика событий
Доброй ночи. Пишу свой компонент, и вот наткнулся на такую проблему у idHTTP есть обработчик события OnDisconected и мне нужно его...

6
 Аватар для BRcr
4043 / 2333 / 292
Регистрация: 03.02.2011
Сообщений: 5,066
Записей в блоге: 10
26.04.2014, 14:43
Можно сделать так. Обработчик события может быть членом любого класса, не обязательно формы - можно сделать его членом класса-наследника кнопки, например. Ну и объявлять свои классы можно где угодно, но логичнее в заголовках естественно.

Можно еще использовать TMethod, но это для более изощренных случаев.

Цитата Сообщение от mr sinister Посмотреть сообщение
достаточно ли просто "включать" (#include) этот модуль в те .h и .cpp файлы, где я хочу объявлять переменные пользовательского типа и собственно объявлять их? Или нужны дополнительные телодвижения?
Достаточно заинклудить заголовок.
1
 Аватар для mr sinister
1 / 1 / 0
Регистрация: 28.01.2014
Сообщений: 49
27.04.2014, 19:13  [ТС]
BRcr, Спасибо за ответ, но для такого тупицы как я вы прояснили недостаточно.
Итак, уточнения:
1. Функция, которая должна являться обработчиком событий, написана и имеет в аргументах TObject* Sender. Как теперь обратиться к текущему обработчику события OnClick в этом наследованном классе чтобы перегрузить его этой функцией?
2. Как, собственно, перегружать? Слева текущий обработчик событий (см. вопрос 1), справа моя функция, а посередине?.. =? +=? Что-то еще?
3. Почему, когда я пишу
C++
1
class seat : public TButton
а затем пишу что-либо в конструкторе этого класса (собственно, перегрузку) на меня ругаются, что у TButton (от которого я наследую) нет конструктора по умолчанию?
0
 Аватар для BRcr
4043 / 2333 / 292
Регистрация: 03.02.2011
Сообщений: 5,066
Записей в блоге: 10
27.04.2014, 19:49
Лучший ответ Сообщение было отмечено mr sinister как решение

Решение

Надо было просто внимательно посмотреть код, там все это есть.

1. 2.
C++
1
2
TButton * btn( new TButton( this ) );
btn->OnClick = &custon_onclick_method;
3. А потому что нет у него конструктора по умолчанию. Есть конструктор, принимающий параметр Owner, вот его и надо вызывать из своих конструкторов:
C++
1
2
3
4
5
6
    __fastcall t_cell_shape( TComponent * Owner ) :
        TShape( Owner ),
        charge_id( 0 ),
        just_received( false )
    {
    }
1
 Аватар для mr sinister
1 / 1 / 0
Регистрация: 28.01.2014
Сообщений: 49
28.04.2014, 21:47  [ТС]
BRcr, извините, что все еще докапываюсь, просто ради такой мелочи отдельную тему создавать...
В общем, вот [cut] заголовочный файл, вот [cut] файл .cpp. Никак не могу понять, что я делаю не так, но хоть все это и собирается без ошибок, при попытке собственно создать поле кнопок на первом же вызове NewSeat сразу после вызова конструктора вылетает ошибка выполнения (нарушение доступа к памяти, видимо пытаюсь куда то не туда обратиться)
0
 Аватар для BRcr
4043 / 2333 / 292
Регистрация: 03.02.2011
Сообщений: 5,066
Записей в блоге: 10
29.04.2014, 11:23
Докапывайся на здоровье - форум для этого и существует. До книжек ведь куда дольше докапываться надо...

Во-первых, всегда выкладывай код на форум под тэги - не сказал бы этого я, сказали бы модераторы, так что...

Во-вторых, ты уже второй раз подряд упускаешь из виду оператор new. В структурке seat у тебя объявлен указатель на панель, в методе NewSeat его надо инициализировать, выделив память под новую панель:
C++
1
n->n = new TPanel( Form1 );
Далее...

Приводить типы того подобия на делегаты, что есть в С++, не стоит:
C++
1
n->n->OnClick = (TNotifyEvent)(&Occupy);
- при различных условиях это чревато самыми разными неявными последствиями. Если тебе нужен обработчик, лучше объяви его как положено. Определение TNotifyEvent можно посмотреть в справке.

При создании списка у тебя упущен еще один момент: в самой первой созданной структурке указатель next будет указывать неизвестно куда, так как изначально указатель First не обнулен. Обдумай логику.
Да и неудобно работать с такими списками, лучше бы использовал какой-нибудь контейнер из stl или что-то вроде TList.

В методе Button1Click тоже чехарда у тебя. Память под new room выделяешь, а освобождать ее кто будет? И где? И как? Указатель-то на новосозданное теряется.
1
 Аватар для mr sinister
1 / 1 / 0
Регистрация: 28.01.2014
Сообщений: 49
29.04.2014, 16:42  [ТС]
Черт, насчет new вы правы, спасибо. Я очень долго парился с этими конструкторами, потом прочитал в справке успокаивающую сентенцию мол все автоматически (хотя это, конечно, не так) и выпилил все конструкторы связанные с seat.
Насчет OnClick и приведений. Я написал так же как вы мне и сказали
C++
1
sh->OnMouseDown = &cell_mouse_down;
и поганая среда сказала, что
ругательства
E2034 Cannot convert 'bool (_fastcall * (_closure )(TPanel *))(TPanel *)' to 'TNotifyEvent'

Я опять же, посмотрел справку и сделал как там говорили - явно привел, интересно, что это работает.
Раз чревато - значит поправим. Впрочем, в этой омерзительной справке от эмбаркадеро полезная нагрузка только впервой строчке (объявлении), ни примеров создания обработчиков, ни какой либо другой полезной инфы я не нашел, так что буду отдельно гуглить и глядеть в самоучители.
Насчет списка - спасибо, опять упущенная мелочь с моей стороны, First = 0 дописал.
Вы знаете, я бы с удовольствием использовал массив, а не список, избавился бы от свойства Tag. Увы, насколько я знаю, массива управляемых элементов быть не может. А в чем плюсы TList и контейнеров из stl, если единственная "работа со списком" это вот такой цикл
C++
1
for (tmp = First; tmp; tmp = tmp->next)
который будет бегать по таблице в базе данных и найдя там определенные записи менять цвет определенных панелек? Ну и по клику собственно тоже самое, просто обращение к БД пишет другой человек, я его в код еще не добавил.
Также спасибо за напоминание про потерю указателей, поправил.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
29.04.2014, 16:42
Помогаю со студенческими работами здесь

Задача на 2 обработчика событий
Вот текст самой программы:type время = record час: 0..23; мин,...

Создание обработчика событий
На форме компоненты Memo1 и MainMenu, где созданы подпункты TMenuItem. В учебнике нашел процедуру: procedure TForm1.Put(Sender:...

Реализация обработчика событий
Помогите написать обработчик событий, такой, что при клике мыли в окне, будет появляться квадрат (по каждому клику новый квадрат)

Отключение обработчика событий
На форме есть несколько чекбоксов, для которых прописаны события this-&gt;checkBox1-&gt;CheckedChanged += gcnew System::EventHandler(this,...

Добавление обработчика событий
Здравствуйте! Есть такой код, который выдаёт список процессов, и модулей принадлежащих процессу. #include &lt;windows.h&gt; ...


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

Или воспользуйтесь поиском по форуму:
7
Ответ Создать тему
Новые блоги и статьи
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