Rambler's Top100
"Knowledge itself is power"
F.Bacon
Поиск | Карта сайта | Помощь | О проекте | ТТХ  
 Круглый стол
  
Правила КС
>> Настройки

Фильтр вопросов
>> Новые вопросы
отслеживать по
>> Новые ответы

Избранное

Страница вопросов
Поиск по КС


Специальные проекты:
>> К л ю к в а
>> Г о л о в о л о м к и

Вопрос №

Задать вопрос
Off-topic вопросы

Помощь

 
 К н и г и
 
Книжная полка
 
 
Библиотека
 
  
  
 


Поиск
 
Поиск по КС
Поиск в статьях
Яndex© + Google©
Поиск книг

 
  
Тематический каталог
Все манускрипты

 
  
Карта VCL
ОШИБКИ
Сообщения системы

 
Форумы
 
Круглый стол
Новые вопросы

 
  
Базарная площадь
Городская площадь

 
   
С Л С

 
Летопись
 
Королевские Хроники
Рыцарский Зал
Глас народа!

 
  
ТТХ
Конкурсы
Королевская клюква

 
Разделы
 
Hello, World!
Лицей

Квинтана

 
  
Сокровищница
Подземелье Магов
Подводные камни
Свитки

 
  
Школа ОБЕРОНА

 
  
Арсенальная башня
Фолианты
Полигон

 
  
Книга Песка
Дальние земли

 
  
АРХИВЫ

 
 

Сейчас на сайте присутствуют:
 
  
 
Во Флориде и в Королевстве сейчас  21:19[Войти] | [Зарегистрироваться]
Ответ на вопрос № 50218

16-03-2007 06:43
Добрый день.

Вопрос:

Есть форма на которой куча картинок, на которые нужно нажимать и в зависимости от этого происходят разные действия.

Вот код:

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 и пос, а также ссылка на рисунок, все остальное идентичное во всех остальных процедурах.

Помогите пожалуйста :)

[+] Добавить в избранные вопросы

Отслеживать ответы на этот вопрос по RSS

Ответы:


Уважаемые авторы вопросов! Большая просьба сообщить о результатах решения проблемы на этой странице.
Иначе, следящие за обсуждением, возможно имеющие аналогичные проблемы, не получают ясного представления об их решении. А авторы ответов не получают обратной связи. Что можно расценивать, как проявление неуважения к отвечающим от автора вопроса.

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;


последнюю строчку следует читать так:

Image1.OnDblClick := Form1.Image1DblClick;


16-03-2007 22:40
>>> Если не будет лень, немного позже напишу про Sender и Tag...

Итак, в обработчик передается параметр Sender - это указатель на объект, от которого пришло событие, грубо говоря, это указатель на ту картинку, по которой кликнули. Только тип приведен к общему прародителю всех объектов, соответственно, преобразовав тип (указателя) вы получаете доступ к объекту, чъе событие вы обрабатываете.
Все компоненты имеют сойство Tag:

property Tag: Longint;

Это свойство никак не используется VCL и предназначено исключительно для использования программистом для своих нужд. В нем можно хранить все, что угодно, что помещается в 32 бита: Integer, Pointer, 2 Word, 4 Char.
Пример использования Sender и Tag смотрите в »вопрос КС №50227«

16-03-2007 14:49
Тут описан вариант сработки события только на одной картинке. А у меня их 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...

P.S. Присоединяюсь к просьбе Сергея Перовского

16-03-2007 12:41 | Вопрос к автору: запрос дополнительной информации
>>>я в делфи очень слабенький
А по русски объяснить, что должна делать программа Вы можете?

16-03-2007 09:48
Можно например сделать так. Объявляете 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 и нужные пути будут браться из ваших массивов. Если же пути однотипны и отличаются только цифрами в конце, то можно обойтись и без массива путей, а коструировать строку пути прямо в обработчике.

16-03-2007 09:18 | Сообщение от автора вопроса
Не нужно код копировать в каждую картинку. Назначьте всем картинкам один обработчик типа того, что написан. А если обработка все-таки разная в зависимости от вызывающей картинки, используйте параметр Sender, чтобы например по (Sender as TImage).Tag отличать картинки.

Код будет один и тот же для всех, только меняеться путь к картинке и меняеться переменная vb. Как можно в этом случае написать программу? Только очень прошу если можно с кодом, я в делфи очень слабенький

16-03-2007 09:10
Не нужно код копировать в каждую картинку. Назначьте всем картинкам один обработчик типа того, что написан. А если обработка все-таки разная в зависимости от вызывающей картинки, используйте параметр Sender, чтобы например по (Sender as TImage).Tag отличать картинки.

16-03-2007 08:34 | Сообщение от автора вопроса
Тут описан вариант сработки события только на одной картинке. А у меня их 200 прийдеться данный код копировать в нажатие на каждую картинку!!! А если прийдеться подправить код, там вообще под стол можно залезть.

Хотелось бы что в обработчике была одна строка которая передает процедуре параметры, а процедура уже все делает что нужно, там ведь намного проще!

Осталось найти ман по работе с процедурами.

16-03-2007 08:27
и в каждой нуна этот код
Зачем?

Хотелось бы как то с функцие связать.
Какая еще функция? Просто назначьте всем картинкам один и тот же обработчик. Это можно сделать и в run-time.

16-03-2007 08:27 | Комментарий к предыдущим ответам
А что мешает написать функцию используя пример Николая Белюченко
?

16-03-2007 08:18 | Сообщение от автора вопроса
Николай Белюченко

Код делает почти тоже. Но в итоге всервоно код будет очень большой. У меня около 200-300 картинок будет и в каждой нуна этот код, не очень удобно получаеться :(

Хотелось бы как то с функцие связать.
Что бы обработка происходила в функцие, а функции передавать только параметры. Что бы в каждом дабл клик рисунка была одна две строки.

16-03-2007 08:10
Кажется, следующий код будет делать то же, что и Ваш

var
Images: array[0..3] of TImage;
Shapes: array[0..3] of TShape;
// ...

procedure TForm1.Create(Sender: TObject);
begin
Images[0]:=image15;
Images[1]:=image16;
Images[2]:=image17;
Images[3]:=image18;
Shapes[0]:=Shape0;
Shapes[1]:=Shape1;
Shapes[2]:=Shape2;
Shapes[3]:=Shape3;
// ...
end;

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;


16-03-2007 07:51 | Сообщение от автора вопроса
Как это все можно сделать на порядок проще, я знаю это можно сделать функцией, но поковырял малость инет, ничего вразумительного не нашел.
В даном примере меняеться значение переменной vb и пос, а также ссылка на рисунок, все остальное идентичное во всех остальных процедурах.


Вот в этом вопрос! :)

16-03-2007 07:12
А в чем вопрос то, в чем помочь ???

если я верно догадался
вместо image18.Picture
можно использовать (Sender as TImage).Picture

Добавьте свое cообщение

Вашe имя:  [Войти]
Ваш адрес (e-mail):На Королевстве все адреса защищаются от спам-роботов
контрольный вопрос:
"Мы с тобой одной крови — ты и я!". Чьи это заветные слова?
в качестве ответа на вопрос или загадку следует давать только одно слово в именительном падеже и именно в такой форме, как оно используется в оригинале.
Надоело отвечать на странные вопросы? Зарегистрируйтесь на сайте.
Тип сообщения:
Текст:
Жирный шрифт  Наклонный шрифт  Подчеркнутый шрифт  Выравнивание по центру  Список  Заголовок  Разделительная линия  Код  Маленький шрифт  Крупный шрифт  Цитирование блока текста  Строчное цитирование
  • вопрос Круглого стола № XXX

  • вопрос № YYY в тесте № XXX Рыцарской Квинтаны

  • сообщение № YYY в теме № XXX Базарной площади
  • обсуждение темы № YYY Базарной площади
  •  
     Правила оформления сообщений на Королевстве

    Страница избранных вопросов Круглого стола.
      
    Время на сайте: GMT минус 5 часов

    Если вы заметили орфографическую ошибку на этой странице, просто выделите ошибку мышью и нажмите Ctrl+Enter.
    Функция может не работать в некоторых версиях броузеров.

    Web hosting for this web site provided by DotNetPark (ASP.NET, SharePoint, MS SQL hosting)  
    Software for IIS, Hyper-V, MS SQL. Tools for Windows server administrators. Server migration utilities  

     
    © При использовании любых материалов «Королевства Delphi» необходимо указывать источник информации. Перепечатка авторских статей возможна только при согласии всех авторов и администрации сайта.
    Все используемые на сайте торговые марки являются собственностью их производителей.

    Яндекс цитирования