Есть форма на которой куча картинок, на которые нужно нажимать и в зависимости от этого происходят разные действия.
Вот код:
procedure TForm1.Image10DblClick(Sender: TObject);
begin
if vb='б' then begin
case pos of
0: begin
image15.Picture.LoadFromFile('б/б1.bmp');
pos:=pos+1;
Shape20.Visible:=false;
timer2.Enabled:=false;
Shape0.Visible:=true;
end;
1: begin
image16.Picture.LoadFromFile('б/б1.bmp');
pos:=pos+1;
Shape20.Visible:=false;
timer2.Enabled:=false;
Shape1.Visible:=true;
end;
2: begin
image17.Picture.LoadFromFile('б/б1.bmp');
pos:=pos+1;
Shape20.Visible:=false;
timer2.Enabled:=false;
Shape2.Visible:=true;
end;
3: begin
image18.Picture.LoadFromFile('б/б1.bmp');
pos:=pos+1;
Shape20.Visible:=false;
timer2.Enabled:=false;
Shape3.Visible:=true;
GroupBox2.Enabled:=false;
timer1.Enabled:=true;
end;
end;
end
else begin
shape20.Visible:=true;
timer2.Enabled:=true;
end;
Как это все можно сделать на порядок проще, я знаю это можно сделать функцией, но поковырял малость инет, ничего вразумительного не нашел.
В даном примере меняеться значение переменной vb и пос, а также ссылка на рисунок, все остальное идентичное во всех остальных процедурах.
Уважаемые авторы вопросов! Большая просьба сообщить о результатах решения проблемы на этой странице. Иначе, следящие за обсуждением, возможно имеющие аналогичные проблемы, не получают ясного представления об их решении. А авторы ответов не получают обратной связи. Что можно расценивать, как проявление неуважения к отвечающим от автора вопроса.
18-03-2007 13:15 | Вопрос к автору: запрос дополнительной информации
Нет, все-таки уточните, что ваша программа должна делать, тогда можно будет предложить нормальное решение проблемы. На данный момент я совершенно не понимаю, как связаны Image10 и изменяемые Image15, Image16... Image18. Как связана пара щелкаемый Image и загружаемый файл? Как связан Shape20 и Image10 (на котором кликнули). И 200 картинок - это конечно же перебор, проще обойтись одной картинкой и сделать несколько "горячих областей". И наконец, что проще всего, написать HTML и загрузить его в WebBrowser, пусть Windows разбирается со всем геморроем. И еще, если цель программы - только выбор и отображение некоей информации, то получится действительно разумнее использовать HTML и отображать в Opera (ибо Ослика я не признаю, только за неимением лучшего...)
17-03-2007 12:14 | Комментарий к предыдущим ответам
Поправка к пред-предыдущему сообщению. В следующем тексте:
Таким образом, строчка в файле Form1.dfm
OnDblClick = Image1DblClick
совершенно аналогична коду где-нибудь в программе:
Form1.OnDblClick := Form1.Image1DblClick;
>>> Если не будет лень, немного позже напишу про Sender и Tag...
Итак, в обработчик передается параметр Sender - это указатель на объект, от которого пришло событие, грубо говоря, это указатель на ту картинку, по которой кликнули. Только тип приведен к общему прародителю всех объектов, соответственно, преобразовав тип (указателя) вы получаете доступ к объекту, чъе событие вы обрабатываете.
Все компоненты имеют сойство Tag:
property Tag: Longint;
Это свойство никак не используется VCL и предназначено исключительно для использования программистом для своих нужд. В нем можно хранить все, что угодно, что помещается в 32 бита: Integer, Pointer, 2 Word, 4 Char.
Пример использования Sender и Tag смотрите в »вопрос КС №50227«
Тут описан вариант сработки события только на одной картинке. А у меня их 200 прийдеться данный код копировать в нажатие на каждую картинку!!! А если прийдеться подправить код, там вообще под стол можно залезть.
Не надо никуда залезать. Лучше разобратьтя что есть что и как это использовать.
Первое, в чем вам надо разобраться - это что такое есть обработчик.
Те события, которые вы видите в инспекторе объектов на закладке Events, на самом деле являются не процедурами, а указателями на процедуры, с которыми вы вправе поступать по своему усмотрению как угдно в рамках существующих правил.
Для примера рассмотрим OnDblClick
Итак, вы заходите на закладку Events своего TImage и видите OnDblClick...
Что это такое? Нажимаем F1 и смотрим объявление:
property OnDblClick: TNotifyEvent;
Непонятно, что такое TNotifyEvent... Но он подчеркнут... Щелкаем мышью и видим:
type TNotifyEvent = procedure (Sender: TObject) of object;
Все становится на свои места. Итак: свойство OnDblClick - это указатель на процедуру с одним параметром типа TObject и являющейся не просто процедурой, а методом какого-либо класса. И мы имеем полное право назначить этому свойству указатель на любую процедуру, удовлетворяющую этим требованиям.
Итак, вы заходите на вкладку Events компонета Image1, находящегося на форме Form1 и дважды кликаете на строчке OnDblClick... Что происходит? Создается процедура, в код которой вы сразу и попадаете:
procedure TForm1.Image1DblClick(Sender: TObject);
begin
end;
После этого вы пишете там то, что нужно делать по двойному щелчку на вашей картинке. Но давайте рассмотрим, что при этом происходит на самом деле. На самом деле создается процедура - метод класса TForm1. И это просто процедура, как и любая другая, ничем от них не отличающаяся. Имя может быть любым, а то, что она автоматически называется таким образом, это всего лишь облегчение жизни программисту и не более того. Вы можете назвать ее как угодно. После этого в файл Form1.dfm записывается дополнительная строчка "OnDblClick = Image1DblClick":
object Image1: TImage
Left = 15
Top = 105
Width = 105
Height = 105
OnDblClick = Image1DblClick
end
Что это за строчки? Начну издалека. Все, что делается визульно на форме и в инспекторе объектов, можно замечательно сделать чистым кодом, а то, что вы делаете в инспекторе объектов - это всего лишь задание начальных значений свойствам и не более того. Это просто облегчение жизни. Но не надо делать это единственным способом работы.
Таким образом, строчка в файле Form1.dfm
OnDblClick = Image1DblClick
совершенно аналогична коду где-нибудь в программе:
Form1.OnDblClick := Form1.Image1DblClick;
Что следует из вышесказанного?
Вы можете не создавать отдельный обработчик для конкретного компонента, например Image1, а назначить какой-то уже существующий, например TForm1.DBEdit1Click(Sender: TObject)...
или Form1.Image2DblClick... или Form1.Image1125DblClick... Мысль понятна? Вы даже можете назначить во время выполнения программы в качестве обработчика процедуру вообще из другого класса (но сейчас это не будем рассматривать).
Итак, на все ваши сотни или тысячи ImageNNN можно создать одну единственную процедуру-обработчик и назначить ее сразу всем своим TImage либо прямо в инспекторе объектов, либо во время выполнеия программы, например, при создании картинок в цикле:
procedure TForm1.Button1Click(Sender: TObject);
var
Img: TImage;
i: Integer;
begin
for i := ... to ... do
begin
Img := TImage.Create(Form1);
Img.Parent := Form1;
Img.Top := ...
Img.Left := ...
...
Img.OnDblClick := SomeImageDblClick; // без скобок и параметров
end;
end;
procedure TForm1.SomeImageDblClick(Sender: TObject);
begin
...
end;
Это что касается "двухсот обработчиков"...
Если не будет лень, немного позже напишу про Sender и Tag...
Можно например сделать так. Объявляете 2 массива - пути к картинкам и значения vb:
paths: array [0..200] of string;
vbvalues: array [0..200] of string;
При создании каждого Image задаете ему свойство Tag, а в обработчике вместо vb пишете vbvalues[(Sender as TImage).Tag], а вместо пути paths[(Sender as TImage).Tag]. Тогда нужные vb и нужные пути будут браться из ваших массивов. Если же пути однотипны и отличаются только цифрами в конце, то можно обойтись и без массива путей, а коструировать строку пути прямо в обработчике.
Не нужно код копировать в каждую картинку. Назначьте всем картинкам один обработчик типа того, что написан. А если обработка все-таки разная в зависимости от вызывающей картинки, используйте параметр Sender, чтобы например по (Sender as TImage).Tag отличать картинки.
Код будет один и тот же для всех, только меняеться путь к картинке и меняеться переменная vb. Как можно в этом случае написать программу? Только очень прошу если можно с кодом, я в делфи очень слабенький
Не нужно код копировать в каждую картинку. Назначьте всем картинкам один обработчик типа того, что написан. А если обработка все-таки разная в зависимости от вызывающей картинки, используйте параметр Sender, чтобы например по (Sender as TImage).Tag отличать картинки.
Тут описан вариант сработки события только на одной картинке. А у меня их 200 прийдеться данный код копировать в нажатие на каждую картинку!!! А если прийдеться подправить код, там вообще под стол можно залезть.
Хотелось бы что в обработчике была одна строка которая передает процедуре параметры, а процедура уже все делает что нужно, там ведь намного проще!
Код делает почти тоже. Но в итоге всервоно код будет очень большой. У меня около 200-300 картинок будет и в каждой нуна этот код, не очень удобно получаеться :(
Хотелось бы как то с функцие связать.
Что бы обработка происходила в функцие, а функции передавать только параметры. Что бы в каждом дабл клик рисунка была одна две строки.
procedure TForm1.Image10DblClick(Sender: TObject);
begin
if vb='б' then begin
Images[pos].Picture.LoadFromFile('б/б1.bmp');
Shape20.Visible:=false;
Timer2.Enabled:=false;
Shapes[pos].Visible:=true;
pos:=pos+1;
if pos=4 then begin
GroupBox2.Enabled:=false;
Timer1.Enabled:=true;
end;
end
else begin
Shape20.Visible:=true;
Timer2.Enabled:=true;
end;
end;
Как это все можно сделать на порядок проще, я знаю это можно сделать функцией, но поковырял малость инет, ничего вразумительного не нашел.
В даном примере меняеться значение переменной vb и пос, а также ссылка на рисунок, все остальное идентичное во всех остальных процедурах.
Если вы заметили орфографическую ошибку на этой странице, просто выделите ошибку мышью и нажмите Ctrl+Enter. Функция может не работать в некоторых версиях броузеров.