Виклик процедури OnClick з модуля
Привіт, шановні майстри.
Є форма Form1. На формі 2 кнопки. Є модуль Unit2 (без форми).
uses
# XA0; Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
# XA0; Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls;
type
# XA0; TForm1 = class (TForm)
# XA0; # XA0; Button1: TButton;
# XA0; # XA0; Button2: TButton;
# XA0; # XA0; procedure Button1Click (Sender: TObject);
# XA0; # XA0; procedure Button2Click (Sender: TObject);
# XA0; private
# XA0; # XA0;
# XA0; public
# XA0; # XA0;
# XA0; end;
var
# XA0; Form1: TForm1;
procedure TForm1.Button1Click (Sender: TObject);
begin
# XA0; Test;
end;
procedure TForm1.Button2Click (Sender: TObject);
begin
# XA0; ShowMessage ( "Button2Click");
end;
procedure Test;
begin
# XA0; Form1.Button2Click (Form1);
end;
procedure Test (Sender: TObject);
procedure Test (Sender: TObject);
begin
# XA0; Form1.Button2Click (Sender);
end;
Ну і, відповідно, виклик процедури Test буде такий:
procedure TForm1.Button1Click (Sender: TObject);
begin
# XA0; Test (Self);
end;
1. Поясніть, будь ласка, популярно в чому різниця між:
Form1.Button2Click (Sender); // Тільки за умови, що процедура оголошена як: procedure Test (Sender: TObject);
Form1.Button2Click (Form1);
Form1.Button2Click (nil);
Form1.Button2.Click;
2. Чи є необхідність оголошувати, як procedure Test (Sender: TObject)?
не перевіряв коректність, але для рядків
Form1.Button2Click (Sender); // Тільки за умови, що процедура оголошена як: procedure Test (Sender: TObject);
Form1.Button2Click (Form1);
Form1.Button2Click (nil);
Зголоситься метод-обробник події OnClick, в який в якості аргументу передається те, що в дужках
А навіщо це потрібно? Подібні ручні виклики обробників - поганий код.
Form1.Button2.Click;
Зголоситься метод Click, всередині якого, зокрема, викликається обробник OnClick, якщо він був призначений, а аргументом обробника буде екземпляр кнопки Button2
Щиро дякую за відповідь.
Тобто краще використовувати Form1.Button2.Click; ?
Для чого використовувати? Вручну викликати подія натискання кнопки?
Не зовсім так.
У моєму випадку існує кілька кнопок, за якими закріплені якісь дії у великій кількості (тому доводиться обробник цих кнопок виносити в окремий модуль, розбивати на окремі процедури і т.д.).
Так ось, іноді потрібно, щоб при натисканні однієї кнопки зголосився обробник OnClick інший кнопки, яка може бути неактивна.
Тобто мені важливо не сама подія натискання кнопки, а алгоритм дій, який закріплений за цією кнопкою.
Щоб було зрозуміліше, наведу приклад.
Є глобальна змінна, наприклад, perem: integer;
У Unit2 за процедурою закріплено, наприклад, наступне:
procedure Test (Sender: TObject);
begin
with Form1 do
# XA0; case perem of
# XA0; 1: // щось зробити
# XA0; 2: // щось зробити
# XA0 ;.
# XA0; 50: Button2Click (Form1);
# XA0 ;.
# XA0; 100: // щось зробити
end;
end;
azl. якщо
> Важливо не сама подія натискання кнопки, а алгоритм
> Дій, який закріплений за цією кнопкою.
то
> Щоб було зрозуміліше, наведу приклад.
type
# XA0; TForm1 = class (TForm)
# XA0; # XA0; Button1: TButton;
# XA0; # XA0; Button2: TButton;
# XA0; # XA0; Button3: TButton;
# XA0; # XA0; procedure Button1Click (Sender: TObject);
# XA0; # XA0; procedure Button2Click (Sender: TObject);
# XA0; # XA0; procedure Button3Click (Sender: TObject);
# XA0; private
# XA0; # XA0;
# XA0; public
# XA0; # XA0;
# XA0; # XA0; procedure Raz ();
# XA0; # XA0; procedure Dva ();
# XA0; # XA0; procedure Tru ();
# XA0; end;
var
# XA0; Danc123: TForm1;
procedure TForm1.Raz;
begin
# XA0; // Raz-raz-raz
# XA0; Dva;
# XA0; Tru;
end;
procedure TForm1.Dva;
begin
# XA0; Raz;
# XA0; // Dva-dva-dva;
# XA0; Tru;
end;
procedure TForm1.Tru;
begin
# XA0; Raz;
# XA0; Dva;
# XA0; // Tru-tru-tru;
end;
procedure TForm1.Button1Click (Sender: TObject);
begin
# XA0; Raz;
end;
procedure TForm1.Button2Click (Sender: TObject);
begin
# XA0; Dva;
end;
procedure TForm1.Button3Click (Sender: TObject);
begin
# XA0; Tru;
end;
end.
Це зрозуміло? і вирішує твою задачу, або розповідати про "Sender" # XA0; і "Unit2"?
> При натисканні однієї кнопки зголосився обробник OnClick інший кнопки
Оскільки в окремому модулі Self не працює, то замість Self потрібно писати ім'я форми. Наприклад, Form1.Button2Click (Form1);
І це працює. Тому, думаю, що тему можна закривати.
> An a Bad Idea.
Your English is poor. You shouldn "t use two indefinite article in a row.
Каюсь, в інституті теж так часто робив. Але тепер розумію що якщо "при натисканні однієї кнопки зголосився обробник OnClick інший кнопки", то це явно погано продумана архітектура. Втім, якщо це «домашній проект одного програміста» ™, може і зійде, як хочете.
І все ж чим вам не догодили Form1.Button2.Click; або Form1.Button2Click (Nil); (За замовчуванням ж Sender не задіяне)?
> Відповідь від Юрія Зотова [19]
А з цього якраз слід що якщо і робити через це місце, то правильніше робити Form1.Button2Click (Form1.Button2);
> Form1.Button2Click (Sender); // Тільки за умови, що процедура
> Оголошена як: procedure Test (Sender: TObject);
> Form1.Button2Click (Form1);
> Form1.Button2Click (nil);
> Form1.Button2.Click;
>
Говнокод, що приводить до помилки доступу до пам'яті.
Багаторазово використовується код оформляється в окремі процедури / функції. Хоча, ч # 235; ї щось я. про ази просили не згадувати.
> Але тепер розумію що якщо "при натисканні однієї кнопки зголосився
> Обробник OnClick інший кнопки ", то це явно погано продумана
> Архітектура.
Мабуть, варто було назвати тему по-іншому. Правильніше, напевно, потрібно було назвати: "Виклик процедури з параметром (Sender: TObject) з модуля без форми". Бо тут сіль не в OnClick, а саме в (Sender: TObject)
> І все ж чим вам не догодили Form1.Button2.Click; або Form1.
> Button2Click (Nil);
Я не писав, що вони мені не догодили, я запитав у чому різниця. І можна було б ще додати: в яких випадках, що правильніше використовувати?
> А з цього якраз слід що якщо і робити через це місце,
> # XA0; то правильніше робити Form1.Button2Click (Form1.Button2);
Це залежить від того, що потрібно отримати.
Sender - (Form1.Button2)
Self - (Form1)
> Багаторазово використовується код оформляється в окремі процедури / функції.
А якщо у цієї окремої процедури параметр (Sender: TObject), як її викликати з модуля?
procedure TForm1.Example (Sender: TObject);
begin
# XA0; // do something;
end;
> А якщо у цієї окремої процедури параметр (Sender: TObject),
Цією твоєї окремою процедурою нафіг не потрібен цей параметр, раз у тебе працює маревний код
Button2Click (Self)
> Цією твоєї окремою процедурою нафіг не потрібен цей параметр,
> # XA0; раз у тебе працює маревний код
Да ти що? Правда? А якщо ця процедура виглядає так:
procedure TForm1.Example (Sender: TObject);
begin
# XA0; if (Sender is TButton) then
.
end;
Тут програміста наймати треба, без варіантів.
вилучено модератором
Примітка: конференція для початківців
Просто треба зрозуміти просту основу: модуль - первинний, а форма - вторинна.
Модуль нічого не знає ні про яких формах, а форма знає необхідні їй модулі.
Роби так, як зручно. Хоч гоу-ту використовуй. бо всякі "традиції" програмування не завжди обґрунтовані чимось більш, ніж брякнувшем з похмілля якимось гуру, що так робити не добре, що тут же бездумно підхопили інші.
Я, наприклад, взагалі на все кнопки вішаю один обробник, в ньому свитч від tag кнопки, що дозволяє мені ваще особливо не морочитися з викликом чого завгодно звідки завгодно. Мені так зручно. А програми пишуться для користувачів, а не для інших програмістів. І якщо мені зручно, користувачам зручно, то інше несуттєво.
> Конференція для початківців, а також для тих, кому складно
> Пояснити чого він хоче. Прохання до учасників бути взаємоввічливими,
> # XA0; професіоналам окрема прохання - бути поблажливими.
По-друге, якщо не можеш пояснити, навіщо відповідати? Або сам не знаєш, або не можеш пояснити. Я адже спеціально загострив на цьому увагу, знаючи, як тут народ любить стрясати повітря і робити подібні заяви. Мені не потрібно вирішити конкретну задачу, мені потрібно всього лише чітке розуміння використання параметрів, що я і попросив пояснити.
> Просто треба зрозуміти просту основу: модуль - первинний, а
> Форма - вторинна.
> Модуль нічого не знає ні про яких формах, а форма знає
> Необхідні їй модулі.
Ось це вже більш конструктивно. Але це і так зрозуміло, суть питання зовсім в іншому.
Ну і нарешті, пояснення-то просте.
> Procedure TForm1.Example (Sender: TObject);
> begin
> # XA0; if (Sender is TButton) then
> # XA0; # XA0; ShowMessage ( "Button")
> # XA0; else
> # XA0; # XA0; ShowMessage ( "BitBtn")
> End;
>
> Procedure TForm1.BitBtn1Click (Sender: TObject);
> begin
> # XA0; Example (Sender);
> End;
>
> Procedure TForm1.Button1Click (Sender: TObject);
> begin
> # XA0; Example (Sender);
> End;
Тільки при такому обработчике умова в процедурі Example виконається так, як нам потрібно, тобто з'явиться повідомлення про те, яка дійсно кнопка була натиснута. У випадку з Example (Self); Example (Form1); Example (nil); весь час буде виконуватися ShowMessage ( "BitBtn"), незалежно від того, яка кнопка була натиснута.
Ну і нарешті Form1.Button2.Click; - метод, призначений для програмного натискання кнопки. Наприклад, якщо потрібно багато разів натискати кнопку, скажімо, через певний інтервал. Щоб не робити цього вручну, можна це зробити за таймером. Вказавши в обробнику таймера Button2.Click; По суті таймер замість нас буде кликати цю кнопку.
Ось, власне, те, що я хотів почути.
Дякую всім, тему можна закривати.
Тут питання було навіть не в тому, як краще або як правильніше. Просто хотів почути пояснення для повного розуміння.
Питання "що таке send"? Ось що туди поставиш, то і буде визиватель події, а що з цим робити або не робити, вже вирішувати в обробнику. Взагалі Send якраз і потрібен, щоб можна було звернутися до об'єкта, незалежно від поточних імен, від поточної кількості об'єктів на формі і т.п ..
Як там його використовувати вже залежить від бажань. Може, мені треба просто визначити кнопка це або кнопка_с_пріделанной_мной_фінтіфлюшкой - це одне, а, може, я настворювала динамічно (в рантайм) 100 кнопок і привласнив один обробник, тоді визначати буду що за кнопка - це інше, а, может. і п'яте, і десяте, і ще багато чого может.
> Не зовсім так чи зовсім не так.
Не зовсім так, згоден. Оскільки при неактивній кнопці мишкою її натиснути не можна, а за допомогою цього методу процедура OnClick все одно виконається.
> azl # XA0; (20.10.14 14:21) [26]
> Оскільки при неактивній кнопці мишкою її натиснути не можна,
Ось-ось, саме цього напевно і хотів програміст, коли в якийсь момент часу робив кнопку неактивній.
> А за допомогою цього методу процедура OnClick все одно виконається.
А це вже якийсь інший --буратіно-- програміст, все одно шукає спосіб проткнути носом грубку, - мовляв, є ж законний спосіб зробити це, а ви, панове Майстри, від мене його приховуєте.
Дурниці якісь. Як може бути пов'язаний код всередині обробника з такими теоріяміо бажаннях програміста і Буратіно?
Приклад: є якийсь регулятор температури (код в обробнику), що займається охрененно процедурою нагріву-охолодження. Є дві кнопки, якими можна вручну нагрівати-охолоджувати. Вони викликають цю процедуру.
Є автоматичний режим. Він вимикає ці кнопки, але суть його дій, що він теж то одну натисне, то іншу.
І що, писати купу однакового, щоб не бути Буратіно?
> Не пов'язану безпосередньо з натисканням кнопки? І ту ж процедуру
> Викликати при натисканні кнопки?
звичайно ж можна. ненапрямую. написати функцію, весь сенс якої в виклику іншої функції. ось вже не чекав такої пропозиції від електронщика;)
Загальні приклади можна привести. Той же регулятор температури.
Температура в баку 98Ц. Робота прорамми:
Ручний режим. Виводимо поруч з клавішею "+" червону напис "Максимально допустима температура". Забороняємо кнопку "+", або при спробі натискання ввічливим поставленим голосом повідомляємо "Тепература досягла межі, з метою запобігання вибуховий аварії резервуара, подальше збільшення не було вироблено".
Кілька різні шляхи у обробника кнопки і обробника компаратора.
ех. У будь-якому випадку якщо "обробник кнопок виносити в окремий модуль, розбивати на окремі процедури" то смикати звідти назад за інтерфейс.
Не тільки поставити віз попереду коня, але ещ # 235; і придушити цю кобилу.
Пропоную впровадити в саморобку веб-сервіси, штук надцять, на каждо # 235; д # 235; рганье свій і датаснап, для купи.