Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Delphi программирование > Общие вопросы Delphi
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 01.05.2011, 19:12   #1
Вадим Мошев

Старожил
 
Аватар для Вадим Мошев
 
Регистрация: 12.11.2010
Сообщений: 8,568
По умолчанию Что нужно передавать в качестве параметра обработчика нажатия кнопки при его вызове из другого метода?

Здравствуйте.
У меня возникла необходимость при вызове пункта меню (меню – имеется ввиду: файл, правка, вид, и так далее, как в большинстве программ) дублировать действие, выполняемое при нажатии кнопки, располагающейся на этой же форме, что и меню (для избыточности).

В коде это выглядит следующим образом:

Код:
unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, Menus;

type
  TForm1 = class(TForm)
    Button1: TButton;
    Label1: TLabel;
    MainMenu1: TMainMenu;
    N111111: TMenuItem;
    Menu: TMenuItem;
    procedure Button1Click(Sender: TObject);
    procedure MenuClick(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
begin
{Этот метод вызывается в том случае,
Если была нажата кнопка}
label1.Caption:=TimeToStr(now);
end;

procedure TForm1.MenuClick(Sender: TObject);
begin
{Это обработчик события нажатия на пункт меню
Здесь просто происходит дублирование действия нажатия кнопки
Через вызов соответствующего метода}
form1.Button1Click(form1);
end;

end.
Когда я описывал метод обработчика нажатия на пункт меню, возник большой соблазн в качестве передаваемого параметра вызова обработчика нажатия кнопки передать переменную form1, что я и сделал. Всё работало хорошо.

Но в более серьёзных проектах переменна form1 имеет существенно больший размер, нежели чем в данном примере, и при попытке передать её в качестве параметра происходит переполнение стека (как это произошло у меня).

Итак, я прошу помочь мне в данном вопросе: каким образом можно выполнить описанное здесь дублирование; что необходимо передавать в качестве параметра, чтобы не свалиться в переполнение стека. Я пробовал передавать адрес переменной Form1 (через оператор @) – не помогло
Заранее большое спасибо.

P.S. Программу-пример леплю в качестве приложения
Вложения
Тип файла: rar Project1.rar (158.5 Кб, 5 просмотров)
Вадим Мошев вне форума Ответить с цитированием
Старый 01.05.2011, 19:49   #2
Stilet
Белик Виталий :)
Старожил
 
Аватар для Stilet
 
Регистрация: 23.07.2007
Сообщений: 57,097
По умолчанию

Цитата:
form1.Button1Click(form1);
Замени на form1.Button1.Click; и не парься.
I'm learning to live...
Stilet вне форума Ответить с цитированием
Старый 01.05.2011, 19:55   #3
Прик
Форумчанин
 
Регистрация: 08.09.2010
Сообщений: 880
По умолчанию

Когда вызывается процедура обработки события кнопки, то ей в качестве параметра передается указатель на эту самую кнопку. Так происходит в недрах винды.
Для "самостоятельного" вызова обработчика можно передать nil, если в процедуре обработки параметр Sender никак не участвует. Если же будет участвовать, то передается указатель на саму кнопку.
Код:
  Button1Click(nil);
  //или
  Button1Click(Button1);
Прик вне форума Ответить с цитированием
Старый 01.05.2011, 21:30   #4
Аватар
Старожил
 
Аватар для Аватар
 
Регистрация: 17.11.2010
Сообщений: 18,922
По умолчанию

Цитата:
Сообщение от Вадим Мошев Посмотреть сообщение
Но в более серьёзных проектах переменна form1 имеет существенно больший размер, нежели чем в данном примере, и при попытке передать её в качестве параметра происходит переполнение стека (как это произошло у меня).
Переменная такого типа в любых проектах будет иметь один и тот же размер, поскольку это указатель. И если Sender не используется в процедуре, то в общем-то не важно что передать: от nil до любого TObject
Если бы архитекторы строили здания так, как программисты пишут программы, то первый залетевший дятел разрушил бы цивилизацию

Последний раз редактировалось Аватар; 01.05.2011 в 21:32.
Аватар вне форума Ответить с цитированием
Старый 01.05.2011, 23:19   #5
Вадим Мошев

Старожил
 
Аватар для Вадим Мошев
 
Регистрация: 12.11.2010
Сообщений: 8,568
По умолчанию

Всем огромное спасибо. И за предоставленную информацию тоже. Всё оказалось просто. Причина - у меня в подписи.

Вот смотрите.

Процедура обработки нажатия кнопки у меня имеет такой заголовок:

Цитата:

procedure TForm3.ButtonAddNewQuestionClick(Sender: TObject);
А процедура обработки клика на пункт меню (заголовок) выглядит так:

Цитата:
procedure TForm3.AddNewQuestionClick(Sender: TObject);
По условию задачи, в этой процедуре должно было быть обращение к обработчику нажатия кнопки. И тут я, видимо запутался, в общем, не знаю, почему, там я написал:

Цитата:
Form3.AddNewQuestionClick(form3);
То есть у меня было написано:

Код:
procedure TForm3.AddNewQuestionClick(Sender: TObject);
begin
Form3.AddNewQuestionClick(form3);
Процедура вызывала сама себя рекурсивно, при этом об условии выхода и речи не было. Бесконечная рекурсия, стек забился и переполнился...

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

Stilet. Не могу что-то я тебе поднять репутацию...

Последний раз редактировалось Вадим Мошев; 01.05.2011 в 23:22.
Вадим Мошев вне форума Ответить с цитированием
Старый 03.05.2011, 10:14   #6
phomm
personality
Старожил
 
Аватар для phomm
 
Регистрация: 28.04.2009
Сообщений: 2,882
По умолчанию

советую для написания множественных "вызывателей" одного действия поизучать Tactionlist
примерный аналог ему же - писать собственные процедуры/функи в public формы или в интерфейсе unit'a и потом просто вызывать их нужными кнопками/менюшками/тулбарами

ну и маленький хинт - лучше внутри метода конкретной формы не указывать конкретная_форма.её_поле(или метод) а просто сразу её_поле , а то потом захотите рефакторить , переназвать форму, и везде придётся удалять/менять эти строки
phomm вне форума Ответить с цитированием
Старый 03.05.2011, 14:00   #7
Вадим Мошев

Старожил
 
Аватар для Вадим Мошев
 
Регистрация: 12.11.2010
Сообщений: 8,568
По умолчанию

Цитата:
ну и маленький хинт - лучше внутри метода конкретной формы не указывать конкретная_форма.её_поле(или метод) а просто сразу её_поле , а то потом захотите рефакторить , переназвать форму, и везде придётся удалять/менять эти строки
Да, спасибо, я сам просто потом уже понял.
Во-первых, нет никакого смысла к объекту, если мы описываем его метод, ну, а, во-вторых, всё то, что сказали вы. Спасибо.

Цитата:
советую для написания множественных "вызывателей" одного действия поизучать Tactionlist
примерный аналог ему же - писать собственные процедуры/функи в public формы или в интерфейсе unit'a и потом просто вызывать их нужными кнопками/менюшками/тулбарами
Лучше, действительно, мне раскурить этот компонент (как и другие компоненты делфи), чтобы легче жилось и чайниковские вопросы не сыпались...
Вадим Мошев вне форума Ответить с цитированием
Старый 03.05.2011, 14:31   #8
ZvEr_HaCkEr
VisualC++/DirectX
Форумчанин
 
Аватар для ZvEr_HaCkEr
 
Регистрация: 16.07.2010
Сообщений: 831
По умолчанию

А я бы просто написал процедуру, а после вызывал ее.
Код:
procedure Click;
begin
Form1.label1.Caption:=TimeToStr(now);
end;

procedure TForm1.MenuClick(Sender: TObject);
begin
Click;
end;
ZvEr_HaCkEr вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
что нужно сделать с <td> что бы между картинками другого <table> не было разделения? alex555 HTML и CSS 22 24.04.2012 16:43
Ошибка при вызове метода класса coNsept Общие вопросы C/C++ 2 14.12.2010 13:09
Передача метода класса в качестве параметра в другой метод Dmytry87 Общие вопросы C/C++ 0 12.11.2008 15:28
что нужно сделать, чтобы при нажатии кнопки запускалась процедура mager Общие вопросы Delphi 15 19.11.2006 15:02