Экспертная система Delphi.int.ru

Сообщество программистов
Общение, помощь, обмен опытом

Логин:
Пароль:
Регистрация | Забыли пароль?

Delphi.int.ru Expert

Другие разделы портала

Переход к вопросу:

#   

Статистика за сегодня:  


Лучшие эксперты

Подробнее »



Вопрос # 5 012

/ вопрос решён /

Здравствуйте, эксперты!
Вопрос яйца ломанного не сто'ит и простыми средствами
решается на раз, но хочется научиться это делать красиво.
Итак, есть две кнопки A и B и соответственно 2 обработчика :

( См. код )

Простой путь - прописать процедуры alfa и beta отдельно и
вызвать первую по кнопке А безусловно, по B - по условию.

А если написа'ть один обработчик, а в нем :
Begin
if ((вызов по кнопке А) or (условие)) then выполнить действия аlfa .........
;

Интуиция мне подсказывает, что "вызвавшего абонента" можно определить по Sender, но дельфийскими словами выразить не могу.

Я так понимаю, что goto lab_другого_обработчика не годится.

Приложение:
  1. Procedure BtnA.Click ( Sender : Tobject )
  2. Begin
  3.  
  4.  
  5. end ;
  6.  
  7. Procedure BtnB.Click ( Sender : Tobject )
  8. Begin
  9.  
  10.  
  11. end ;
  12.  
  13.  


Толяныч Вопрос решён, но можно продолжить его обсуждение в мини-форуме

Вопрос задал: Толяныч (статус: 4-ый класс)
Вопрос отправлен: 9 февраля 2011, 22:10
Состояние вопроса: решён, ответов: 1.

Ответ #1. Отвечает эксперт: IlluminatI

Здравствуйте, Толяныч!
Практически у каждого компанента в Delphi есть такое замечательное свойство Tag. Выставляем у BtnA свойство Tag = 1, у BtnB соответственно Tag = 2 (на самом деле, можно любые int числа :) ). Дальше тыкаем два раза в любую из двух кнопок - среда создаст нам обработчик для этой кнопки. У второй кнопки находим событие OnClick и соотносим его с событием OnClick первой кнопки. В самом обработчике пишем такое:
case (Sender as TButton).Tag of
1: // нажали первую кнопку...
2: // нажали вторую кнопку...
end;
Вот вроде бы и вся хитрость.
P.S: Также, чтобы проверить является-ли Sender нужным нам объектом можно так: if (Sender is TButton) then ...; // является

Ответ отправил: IlluminatI (статус: 2-ой класс)
Время отправки: 9 февраля 2011, 22:59
Оценка за ответ: 5

Комментарий к оценке: Спасибо. Исчерпывающе. Про Tag я не знал - свойство не самоочевидное. А Sender, выходит, определят тип объекта, не имя ?

Мини-форум вопроса

Всего сообщений: 11; последнее сообщение — 11 февраля 2011, 08:28; участников в обсуждении: 5.
Ерёмин А.А.

Ерёмин А.А. (статус: *Администратор), 10 февраля 2011, 09:44 [#1]:

Цитата (Толяныч):

А Sender, выходит, определят тип объекта, не имя ?

(Sender as TButton).Name даст имя.
Вадим К

Вадим К (статус: Академик), 10 февраля 2011, 10:47 [#2]:

Толяныч: Мне исходное Ваше решение нравится больше, чем предложенное IlluminatI. Почему? да просто кликнул по кнопке - увидел. А в варианте IlluminatI ещё нужно идти, проверять свойство tag.

Шумиха вокруг свойстав Tag сильно уж перегрета.
Галочка "подтверждения прочтения" - вселенское зло.
bugmenot

bugmenot (статус: 3-ий класс), 10 февраля 2011, 11:58 [#3]:

Толяныч, есть еще одна возможность ветвления
procedure TForm17.ButtOnClick(Sender: TObject);
begin
  { православный CASE использовать нельзя :-/ }
  if Sender = ButtOn then
    PlaySound(PChar(SND_ALIAS_SYSTEMSTART), 0, SND_ALIAS_ID)
  else if Sender = ButtOff then
    PlaySound(PChar(SND_ALIAS_SYSTEMEXIT), 0, SND_ALIAS_ID)
как видишь, привязываться к Name - не очень кошерно

Волшебные числа в Tag чрезвычайно неудобно поддерживать
виконання програми розпочинається з того самого мiсця, де призупинилося.

10 февраля 2011, 12:08: Статус вопроса изменён на решённый (изменил автор вопроса — Толяныч)

Толяныч

Толяныч (статус: 4-ый класс), 10 февраля 2011, 12:18 [#4]:

Вадим К: Как-то это уж очень просто и не по ООП-овски :-) и не хочется плодить лишних процедур и функций, потому как если их больше 7, то в них запутываюсь :-(
bugmenot : Sorry, туплю малость, не въехал : из последнего примера конструкция компилиться не будет или будет работать неправильно? И можно ли вместо (Sender as TButton).Tag применить просто Sender.Tag - мол, дайте мне тэг вызвавшего событие объекта, а кто он - кнопка или чекбокс - неважно?
А напоследок я спрошу : public бывают только Var или Label тоже могут, хотя по идее последнее противоречит принципам инкапсуляции.
Вадим К

Вадим К (статус: Академик), 10 февраля 2011, 12:34 [#5]:

если alfa и beta - не просто процедуры, а методы формы, то никакого противоречия ООП нет.
Во вторых - лучше две маленькие процедуры, чем одна большая.
В третьих, если запутываетесь - пишите коментарии, пишите более понятные имена процедур и методов.

Sender.Tag - так нельзя, дело в том, что Sender имеет тип TObject, где этого свойства еще нет. Нужно привести как минимум к TComponent (если правильно помню, та там оно появляется).

а вот что такое public label - я не знаю. или это label, объявленный в секции interface?
Галочка "подтверждения прочтения" - вселенское зло.
Толяныч

Толяныч (статус: 4-ый класс), 10 февраля 2011, 12:49 [#6]:

Вадим К:
а вот что такое public label - я не знаю. или это label, объявленный в секции interface?
Если таким макаром метку в одном обработчике сделать доступной из другого обработчика? Нельзя? Ну и ладно. Нет - так нет.
min@y™

min@y™ (статус: Доктор наук), 10 февраля 2011, 13:05 [#7]:

Не смотря на то, что вопрос решен, предложу свои 5 копеек с одним обработчиком:
procedure BtnA_and_B.Click(Sender: TObject);
begin
  // выполнить действия аlfa, если нажата BtnA ИЛИ (нажата BtnB И (условие = true ))
  if (Sender = BtnA) or ((Sender = BtnB) and ({ условие }))
    then { выполнить действия аlfa };
  // выполнить действия beta (в любом случае)
end;
Делаю лабы и курсачи по Delphi и Turbo Pascal. За ПИВО! Пишите в личку, а лучше в аську. А ещё лучше - звоните в скайп!
Вадим К

Вадим К (статус: Академик), 10 февраля 2011, 13:18 [#8]:

Толяныч:
с помощью меток нельзя перейти в середину другой процедуры/метода. это противоречит паскалю вообще.
Галочка "подтверждения прочтения" - вселенское зло.
bugmenot

bugmenot (статус: 3-ий класс), 10 февраля 2011, 13:47 [#9]:

> из последнего примера конструкция компилиться не будет или будет работать неправильно?
не понял вопроса, прекрасно работает потому что сравниваются указатели на объекты
а в CASE требуются константные выражения, коими указатели не являются
виконання програми розпочинається з того самого мiсця, де призупинилося.

Толяныч

Толяныч (статус: 4-ый класс), 10 февраля 2011, 23:57 [#10]:

Все, теперь полная ясность до следующего туману.Всем мерси.
bugmenot: А конструкцию case я недолюбливаю еще с тех пор, когда ( лет 10 назад ) на фирме делал микроконтроллерные устройства , а мой молодой коллега - к ним программы верхнего уровня. Так он мне сказал : поскольку я как верхний уровень тут главный, то ты в своем протоколе применяять модификатор в команде не смей, т.к. в таком случае я не смогу применить Case, в результате мне пришлось дописывать пару страниц ассемблера в МК. Справедливости ради cто'ит отметить, что моих изделий с МК было поставлено несколько сотен, но увы - ни у одного заказчика не появилась потребность в верхнем уровне.
Все, сорри за маленький оффтоп. Bye !
min@y™

min@y™ (статус: Доктор наук), 11 февраля 2011, 08:28 [#11]:

Цитата (Толяныч):

когда ( лет 10 назад ) на фирме делал микроконтроллерные устройства

Ой, тоже молодость вспоминаю, когда помимо программ я написал на Delphi свой отладчик под свои же программы для микроконтроллеров. Было время!
Щас смотрю я на ентот свой отладчик - ЁПРСТ, что за корявая хренотень! А люди до сих пор им пользуются, не смотря на ошибки. :)
Делаю лабы и курсачи по Delphi и Turbo Pascal. За ПИВО! Пишите в личку, а лучше в аську. А ещё лучше - звоните в скайп!

Чтобы оставлять сообщения в мини-форумах, Вы должны авторизироваться на сайте.

Версия движка: 2.6+ (26.01.2011)
Текущее время: 16 ноября 2024, 16:28
Выполнено за 0.03 сек.