IPB
ЛогинПароль:

> ВНИМАНИЕ!

Прежде чем задать вопрос, смотрите FAQ.
Рекомендуем загрузить DRKB.

Наладить общение поможет, если вы подпишитесь по почте на новые темы в этом форуме.

2 страниц V  1 2 >  
 Ответить  Открыть новую тему 
> Вызов события, OnDrawCell
сообщение
Сообщение #1


Бывалый
***

Группа: Пользователи
Сообщений: 195
Пол: Мужской
Реальное имя: Сергей

Репутация: -  2  +


В общем я хочу чтобы у меня после какого-то действия вызывалась процедура OnDrawCell для StringGrid'a.
procedure TForm1.StringGrid1DrawCell(Sender: TObject; ACol, ARow: Integer;
Rect: TRect; State: TGridDrawState);

Подскажите пожалуйста как можно эту процедуру вызвать из какого-либо участка кода?


--------------------
♣♣♣
"Себя великим не считай, гордясь величьем предков,
Величья не добудешь ты и золота ценою!
Хоть светит на небе луна, но отраженным светом -
Чужою славой не живи, не будь второй луною!!!"
♣♣♣
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #2


mea culpa
*****

Группа: Пользователи
Сообщений: 1 372
Пол: Мужской
Реальное имя: Николай

Репутация: -  24  +


Ну так и вызываешь, form1.StringGrid1DrawCell(Sender: TObject; ACol, ARow: Integer; Rect: TRect; State: TGridDrawState);


--------------------
"Знаешь, стыдно - когда не видно, что услышал всё, что слушал.."
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #3


Бывалый
***

Группа: Пользователи
Сообщений: 195
Пол: Мужской
Реальное имя: Сергей

Репутация: -  2  +


Так ему Sender не нравится...
Пишет следующее
Цитата(Delphi)
[Error] Unit1.pas(79): Undeclared identifier: 'Sender'


--------------------
♣♣♣
"Себя великим не считай, гордясь величьем предков,
Величья не добудешь ты и золота ценою!
Хоть светит на небе луна, но отраженным светом -
Чужою славой не живи, не будь второй луною!!!"
♣♣♣
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #4


Гость






Цитата
я хочу чтобы у меня после какого-то действия вызывалась процедура OnDrawCell для StringGrid'a.
Налицо ошибка проектирования. Событие не должно вызываться, оно должно происходить. Как только событие произойдет - будет вызван и обработчик события.

Можно посмотреть код, зачем тебе понадобилось вызывать OnDrawCell вручную? А если в это время ячейка, для которой будет вызван OnDrawCell, невидима (не находится на экране, а прокручена, например, вверх)?
 К началу страницы 
+ Ответить 
сообщение
Сообщение #5


Бывалый
***

Группа: Пользователи
Сообщений: 195
Пол: Мужской
Реальное имя: Сергей

Репутация: -  2  +


Что касается видимости ячеек, то этого у меня не произойдет. Поле небольшое и всё размещено на форме под нужные размеры.
Я просто хочу сделать так, чтобы у меня сначала нарисовались в каких-либо ячейках изображения. А потом также продолжать их рисовать при определенных действиях.
Как я понял OnDrawCell для этого лучше не использовать? И можно ли каким-либо другим способом рисовать в ячейках StringGrid?
  For i := 1 to 5 do begin
XR := Random (9);
YR := Random (9);
BallR := Random (7);
While Field [XR, YR] = 1 do begin
XR := Random (9);
YR := Random (9);
end;
Field [XR, YR] := 1;
Rect := Form1.StringGrid1.CellRect(XR, YR);
Case BallR of
0 : Form1.StringGrid1.Canvas.Brush.Bitmap := Pink;
1 : Form1.StringGrid1.Canvas.Brush.Bitmap := Green;
2 : Form1.StringGrid1.Canvas.Brush.Bitmap := Yellow;
3 : Form1.StringGrid1.Canvas.Brush.Bitmap := Red;
4 : Form1.StringGrid1.Canvas.Brush.Bitmap := Blue;
5 : Form1.StringGrid1.Canvas.Brush.Bitmap := LightBlue;
6 : Form1.StringGrid1.Canvas.Brush.Bitmap := Brown;
end;
form1.StringGrid1DrawCell(Sender: TObject; XR, YR: Integer; Rect: TRect; State: TGridDrawState);
end;


--------------------
♣♣♣
"Себя великим не считай, гордясь величьем предков,
Величья не добудешь ты и золота ценою!
Хоть светит на небе луна, но отраженным светом -
Чужою славой не живи, не будь второй луною!!!"
♣♣♣
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #6


Гость






Цитата
Как я понял OnDrawCell для этого лучше не использовать? И можно ли каким-либо другим способом рисовать в ячейках StringGrid?
Похоже, ты не понимаешь основ событийного программирования.

Смотри: для того, чтобы рисовать в ячейке Грида, нужно определить обработчик события OnDrawCell. Но вот когда это событие произойдет - не от тебя зависит. Оно произойдет тогда, когда система должна будет перерисовать ячейку. То есть, провел ты над своей программой окно блокнота, когда твое окно снова стало видимым - ячейки должны перерисоваться. Тогда происходит событие, которое вызывает обработчик, написанный тобой. Понимаешь? Не ты вызываешь что-то, а операционная система, зная, что участок окна был невидимым, а потом опять стал видимым, решает: "чтобы не потерять содержимое окна, надо его перерисовать", и делает то, что нужно для этого. Среди прочих действий системы вызывается и определенное тобой в OnDrawCell действие.

То есть, для того, чтобы инициировать перерисовку ячеек, тебе надо действовать другими методами, а не прямым вызовом обработчика OnDrawCell...

Еще раз: Что именно ты хочешь рисовать, и при каких именно (слово "определенных" меня не устраивает, чтобы дать тебе ответ, я просто не смогу ничего посоветовать) условиях ячейки должны перерисовываться, и как именно перерисовываться?
 К началу страницы 
+ Ответить 
сообщение
Сообщение #7


Бывалый
***

Группа: Пользователи
Сообщений: 195
Пол: Мужской
Реальное имя: Сергей

Репутация: -  2  +


Хорошо объясню ситуацию по конкретнее. Спасибо что рассказали про OnDrawCell, просто в интернете мало информации про это и у меня сложилось не правильное мнение о событие.

Когда-то я писал, что делаю небольшую игру.
В общем для начала мне нужно вывести несколько изображений в СтрингГрид - это при начальных условиях. А потом после выделения ячейки с изображением передвинуть его в свободное место. После этого действия может произойти две вещи:
1) Добавятся новые изображения на поле (рандом).
2) Часть изображений исчезнут.

Как мне лучше это осуществить?


--------------------
♣♣♣
"Себя великим не считай, гордясь величьем предков,
Величья не добудешь ты и золота ценою!
Хоть светит на небе луна, но отраженным светом -
Чужою славой не живи, не будь второй луною!!!"
♣♣♣
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #8


Гость






Цитата
Как мне лучше это осуществить?
Не использовать StringGrid для работы с изображениями - это во-первых.

Я бы сделал проще: сгенерировал бы (автоматически, разумеется, тебе же известны размеры изображений, раз у тебя "всё размещено на форме под нужные размеры") нужное количество панелей (TPanel), на каждую из которых опять же автоматически положил бы TImage. Вот и все, собственно. TImage приспособлен для работы с изображениями, вот и пусть работает. В любую секунду можно обратиться к любому изображению напрямую, и перенести его с одного места в другое. И не надо извращаться с событиями...
 К началу страницы 
+ Ответить 
сообщение
Сообщение #9


Бывалый
***

Группа: Пользователи
Сообщений: 195
Пол: Мужской
Реальное имя: Сергей

Репутация: -  2  +


Вы везде употребляете слово "автоматически". А как это сделать? Просто опыта пока, что маловато smile.gif


--------------------
♣♣♣
"Себя великим не считай, гордясь величьем предков,
Величья не добудешь ты и золота ценою!
Хоть светит на небе луна, но отраженным светом -
Чужою славой не живи, не будь второй луною!!!"
♣♣♣
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #10


mea culpa
*****

Группа: Пользователи
Сообщений: 1 372
Пол: Мужской
Реальное имя: Николай

Репутация: -  24  +


Ну наверное имелось в виду при запуске программы создать нужное количество панелей и на них закинуть картинки. Если количество картинок заранее известно, можешь создать панели при проектировании вручную, если неизвестно - динамически.


--------------------
"Знаешь, стыдно - когда не видно, что услышал всё, что слушал.."
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #11


Гость






Когда я говорю "автоматически" - подразумевается, конечно, "во время работы программы". То есть, я не стал бы бросать все эти панели и изображения в режиме редактирования формы, потом с ними замучаешься разбираться, что где. А сделал бы вот так:

Тут код (Показать/Скрыть)


Вот чего получается на форме после того, как я сначала нажал кнопку "Создать", а потом - "Изменить":
Прикрепленное изображение

К тому же, как ты заметил я показал еще и как обрабатывать клик по панельке (или по изображению), если понадобится...

По-моему, этот способ гораздо проще, чем кидать компоненты на форму, выравнивать их, да еще и запоминать, какой компонент как называется, или пользоваться неподходящими компонентами типа StringGrid-а.

Добавлено через 3 мин.
Цитата
Если количество картинок заранее известно, можешь создать панели при проектировании вручную
И ты туда же... Ну, брошу я эти 100 картинок вручную. А как потом к ним обращаться? Мне вот надо перенести первую картинку во втором ряду на 4 ряда ниже. Я что, должен помнить, как пронумерованы картинки? А оно мне надо, если можно обращаться к любому изображению, как к обычному элементу массива?
 К началу страницы 
+ Ответить 
сообщение
Сообщение #12


Бывалый
***

Группа: Пользователи
Сообщений: 195
Пол: Мужской
Реальное имя: Сергей

Репутация: -  2  +


Действительно, оказывается всё настолько просто smile.gif Спасибо за код, но у меня есть ещё пара вопросов по данному коду.
Во-первых, что такое SetLength? И для чего он нужен?
  img := (ArrPanels[2, 2].Components[0] as TImage);
if img <> nil then img.Picture := nil;

Зачем мы пишем Components[0]? И что мы делаем во второй строке?
И ещё, вот в процедурах myPanelClick и myImageClick, что мы в них делаем?
В myPanelClick, как я понял, мы меняем рамку панели, или я не прав?

Сообщение отредактировано: Сергей Меркурьев -


--------------------
♣♣♣
"Себя великим не считай, гордясь величьем предков,
Величья не добудешь ты и золота ценою!
Хоть светит на небе луна, но отраженным светом -
Чужою славой не живи, не будь второй луною!!!"
♣♣♣
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #13


Профи
****

Группа: Пользователи
Сообщений: 865
Пол: Мужской
Реальное имя: Вячеслав

Репутация: -  20  +


Цитата
И ещё, вот в процедурах myPanelClick и myImageClick, что мы в них делаем?
Думаю, что этот обработчик надо установить для всех форм и имеджей на щелчок
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #14


Гость






Цитата
Зачем мы пишем Components[0]?
Комментарии к коду читал? Там все написано.

А во второй строке - если у нас уже есть изображение в TImage, то перед тем, как заносить новую картинку, надо прежнюю-то удалить (для этого в img.Picture присваивается nil.)

Цитата
И ещё, вот в процедурах myPanelClick и myImageClick, что мы в них делаем?
Это пример того, как обрабатывать события. Если ты положил на форму панель, то там все просто, заходишь в список обработчиков, щелкаешь на нужный тебе, и вписываешь нужное действие. А если делаешь все во время выполнения? Как назначить обработчик? Выбрать-то не из чего, форма - пустая в дизайнере... Вот я и показал, как назначить обработку событий. Попробуй, запусти мой код и щелкни мышью на какой-нибудь картинке. Увидишь, что событие обработается...

Цитата
этот обработчик надо установить для всех форм и имеджей на щелчок
Не форм, а панелей.
 К началу страницы 
+ Ответить 
сообщение
Сообщение #15


Бывалый
***

Группа: Пользователи
Сообщений: 195
Пол: Мужской
Реальное имя: Сергей

Репутация: -  2  +


Спасибо!


--------------------
♣♣♣
"Себя великим не считай, гордясь величьем предков,
Величья не добудешь ты и золота ценою!
Хоть светит на небе луна, но отраженным светом -
Чужою славой не живи, не будь второй луною!!!"
♣♣♣
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #16


Бывалый
***

Группа: Пользователи
Сообщений: 195
Пол: Мужской
Реальное имя: Сергей

Репутация: -  2  +


А вот еще один вопрос по поводу первых процедур - Допустим, я нажал на определенный компонент TImage, и как в этих процедурах узнать какие координаты имеет TImage (в массиве ArrPanels)?


--------------------
♣♣♣
"Себя великим не считай, гордясь величьем предков,
Величья не добудешь ты и золота ценою!
Хоть светит на небе луна, но отраженным светом -
Чужою славой не живи, не будь второй луною!!!"
♣♣♣
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #17


Гость






Ну, например, написать вот такую вот функцию:

// В классе формы:
private
{ Private declarations }
function GetIndexes(AImage: TImage; var ALine, ACol: Integer): Boolean;

// ...

// Реализация: пробегаем по всей матрице Panel-ей, и проверяем
// хранящееся в каждой из них изображение (выше мы уже выяснили,
// что Image хранится в списке дочерних компонентов под нулевым номером)
// на равенство тому изображению, по которому щелкнули мышью.

// Если такое изображение найдено - немедленно возвращаем
// его координаты (Line/Col) и выходим. Если ни одно изображение
// не соответствует - функция вернет False, как признак неудачи.
function TForm1.GetIndexes(AImage: TImage;
var ALine, ACol: Integer): Boolean;
var i, j: integer;
begin
result := True;
for i := 0 to Length(arrPanels) - 1 do
for j := 0 to Length(arrPanels[0]) - 1 do
if (arrPanels[i, j].Components[0] as TImage) = AImage then
begin
ALine := i; ACol := j;
Exit;
end;
result := False;
end;

// Вызывать - вот так:
procedure TForm1.myImageClick(Sender: TObject);
var
myParent: TPanel;
Line, Col: integer;
begin
myParent := (Sender as TImage).Parent as TPanel;

// Вызываем функцию с учетом того, что может быть неудача - это нужно делать
// всегда, даже если тебе это кажется невероятным. Мало ли что может произойти,
// лучше добавить if ... then, чем потом сидеть и думать, где ошибка.

// Теперь о том, что передается первым параметром. Как известно, в обработчик
// OnClick передается указатель на тот объект, на котором произошел щелчок мышью.
// Соответственно, и в myImageClick тоже будет передан адрес того объекта (а точнее -
// того изображения), на котором пользователь щелкнул мышью. Вот именно потому, что
// я уверен: "Объект - это именно изображение, и ничего кроме него" (почему я уверен
// в этом - попробуй догадаться и рассказать мне), я и передаю в GetIndexes адрес
// объекта, приведенный к типу TImage... Что произойдет, если вдруг Sender будет
// другого типа - это тоже ты мне расскажешь, договорились?

if GetIndexes(Sender as TImage, Line, Col) then
Memo1.Lines.Add(Format('i = %d, j = %d', [Line, Col])); // Для теста - вывожу в мемо

myParent.OnClick(myParent);
end;

Читай комментарии внимательно. Там есть два вопроса для тебя smile.gif Я очень хотел бы, чтобы ты на них ответил. Это важно.
 К началу страницы 
+ Ответить 
сообщение
Сообщение #18


Бывалый
***

Группа: Пользователи
Сообщений: 195
Пол: Мужской
Реальное имя: Сергей

Репутация: -  2  +


А как сделать обмен таких изображений, зная координаты обоих TImage?

И как Sender может быть другого типа в данном случае? blink.gif Мы же ведь обращаемся конкретно по клику на изображение. И мне кажется, что он не может быть другим smile.gif

Сообщение отредактировано: Сергей Меркурьев -


--------------------
♣♣♣
"Себя великим не считай, гордясь величьем предков,
Величья не добудешь ты и золота ценою!
Хоть светит на небе луна, но отраженным светом -
Чужою славой не живи, не будь второй луною!!!"
♣♣♣
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #19


Профи
****

Группа: Пользователи
Сообщений: 865
Пол: Мужской
Реальное имя: Вячеслав

Репутация: -  20  +


Цитата
А как сделать обмен таких изображений, зная координаты обоих TImage?
А что ты делаешь если надо поменять 2 переменные целого типа? добавляешь 3 переменную того же типа и с ее помощью меняешь первые две. В данном случае - TImage smile.gif
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #20


Бывалый
***

Группа: Пользователи
Сообщений: 195
Пол: Мужской
Реальное имя: Сергей

Репутация: -  2  +


b1 := arrPanels[x,y].Components[0] as TImage;    
arrPanels[x,y].Components[0] as TImage := arrPanels[i, j].Components[0] as TImage;
arrPanels[i, j].Components[0] as TImage := b1;

пытался сделать что-то типа этого... не вышло в итоге smile.gif


--------------------
♣♣♣
"Себя великим не считай, гордясь величьем предков,
Величья не добудешь ты и золота ценою!
Хоть светит на небе луна, но отраженным светом -
Чужою славой не живи, не будь второй луною!!!"
♣♣♣
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 

2 страниц V  1 2 >
 Ответить  Открыть новую тему 
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 





- Текстовая версия 29.03.2024 4:13
500Gb HDD, 6Gb RAM, 2 Cores, 7 EUR в месяц — такие хостинги правда бывают
Связь с администрацией: bu_gen в домене octagram.name