|
Вопрос # 1 655/ вопрос открыт / |
|
Здравствуйте, эксперты!Мне в программе по клику мыши по пункту меню надо создавать кнопку на форме, притом каждый раз при следующем новую.Кроме того в каждой новой кнопке должны должны быть зашиты одни и те же обработчики событий,которые уже описаны.Подскажите как это сделать.
 |
Вопрос задал: GAZ (статус: Посетитель)
Вопрос отправлен: 4 июня 2008, 17:46
Состояние вопроса: открыт, ответов: 1.
|
Ответ #1. Отвечает эксперт: ANBsoft
Здравствуйте, GAZ!
Делается примерно так:
Var AButton:TButton;
Begin
AButton:=TButton.Create(Nil);
AButton.Parent:=Form1;
AButton.Top:=100;
AButton.Left:=100;
AButton.Height:=20;
AButton.Width:=100;
AButton.ShowHint:=False
AButton.OnClick:=MyButtonClick; //Обработчик нажатия
AButton.Tag:=0
 |
Ответ отправил: ANBsoft (статус: Студент)
Время отправки: 4 июня 2008, 18:08
|
Мини-форум вопроса
Всего сообщений: 20; последнее сообщение — 4 июня 2008, 22:20; участников в обсуждении: 3.
|
GAZ (статус: Посетитель), 4 июня 2008, 18:16 [#1]:
Как создавать одну кнопку я знаю,а как создавать всё новые и новые кнопки при каждом клике.
|
|
ANBsoft (статус: Студент), 4 июня 2008, 18:51 [#2]:
Точно также, только менять Top и Left чтобы они в разных местах находились и назначать разный Tag чтобы потом в обработчике их различать.
|
|
GAZ (статус: Посетитель), 4 июня 2008, 18:57 [#3]:
Var AButton:TButton;
BButton:TButton;
CButton:TButton;
..........
Я заранее не знаю сколько буду кнопок создавать.
|
|
Dron (статус: Студент), 4 июня 2008, 18:57 [#4]:
И ещё не забывать менять Name у кнопок...
С уважением.
|
|
GAZ (статус: Посетитель), 4 июня 2008, 19:03 [#5]:
Вы пример можете привести,я так подозреваю тут типа динамического массива надо создавать.Вот только не соображу как.
|
|
Dron (статус: Студент), 4 июня 2008, 19:21 [#6]:
Если вы будете давать кнопкам имена по шаблону вроде MyButton1, MyButton2, MyButton3, то проблем быть не должно - просто в одной челочисленной переменной храните последний номер и всё. Если кнопки могут удаляться (уничтожаться), тогда массив чисел. Т.е. без массива кнопок вполне можно обойтись.
С уважением.
|
|
ANBsoft (статус: Студент), 4 июня 2008, 19:22 [#7]:
просто кусок из своего проекта, где кнопки загружаются по заданным настройкам загружаемым в стринглист SL
Var AButton:Array[1..10000] of TSpeedButton;
for f:=0 to SL.Count-1 do begin
if Copy(SL[f],1,12)='FormMainSize' then begin
Left:=ValIntANB(Copy(SL[f],14,6));
Top:=ValIntANB(Copy(SL[f],20,6));
Width:=ValIntANB(Copy(SL[f],26,6));
Height:=ValIntANB(Copy(SL[f],32,6));
if ValIntANB(Copy(SL[f],38,1))=1 then WindowState:=wsMaximized
else WindowState:=wsNormal;
end;
if Copy(SL[f],1,12)='FormMainIcon' then begin
LW:=ValIntANB(Copy(SL[f],14,3));
LH:=ValIntANB(Copy(SL[f],18,3));
s:=Copy(SL[f],22,6);
if TMenuItem(FormMain.FindComponent('N'+s)).Visible then begin
AIcon[n]:=s;
AButton[n]:=TSpeedButton.Create(Nil);
AButton[n].Parent:=FormMain;
AButton[n].Top:=LH*MainStepGrid-MainStepGrid+MainTop;
AButton[n].Left:=LW*MainStepGrid-MainStepGrid+MainLeft;
AButton[n].Height:=MainIcon;
AButton[n].Width:=MainIcon;
AButton[n].ShowHint:=True;
AButton[n].Glyph.LoadFromResourceName(HInstance,'N'+s);
s:=TMenuItem(FormMain.FindComponent('N'+s)).Caption;
while Pos('&',s)>0 do Delete(s,Pos('&',s),1);
AButton[n].Hint:=s;
AButton[n].OnClick:=SpeedButtonClick;
AButton[n].Tag:=n;
Inc(n);
end;
end;
end;
|
|
GAZ (статус: Посетитель), 4 июня 2008, 19:45 [#8]:
procedure TForm1.SpeedButton1Click(Sender: TObject);
Var AButton:Array[1..10000] of TSpeedButton;
n:integer;
begin
AButton[n]:=TSpeedButton.Create(Nil);
AButton[n].Parent:=Form1;
AButton[n].Top:=100;
AButton[n].Left:=100;
AButton[n].Height:=20;
AButton[n].Width:=40;
AButton[n].OnClick:=SpeedButton1Click;
AButton[n].Tag:=n;
Inc(n);
end;
не могу понять при выполнении вылетает какая та ошибка
|
|
ANBsoft (статус: Студент), 4 июня 2008, 19:50 [#9]:
Какая ошибка и в какой строке?
Скорее всего в начале добавить
n:=1;
|
|
ANBsoft (статус: Студент), 4 июня 2008, 19:54 [#10]:
Приведенный выше кусок выдран из большей процедуры чтобы показать, а инициализация переменных была в начале не попала в иллюстрацию.
|
|
GAZ (статус: Посетитель), 4 июня 2008, 20:47 [#11]:
Dron
а не могли бы вы показать как создавать по шаблону MyButton1, MyButton2, MyButton3 а то с массивом возникают кое какие проблемы
|
|
GAZ (статус: Посетитель), 4 июня 2008, 20:54 [#12]:
Dron
особенно меня интересует как тогда описывать переменную MyButton
не так же
var MyButton1, MyButton2, MyButton3.......
|
|
Dron (статус: Студент), 4 июня 2008, 21:04 [#13]:
Вы для каждой кнопки отдельную переменную заводите? При таком подходе, конечно, без массива не обойтись. Используйте одну переменную: при создании заполняйте свойство Name по шаблону. А затем, чтобы найти нужную кнопку:
(Form1.FindComponent('MyButton3') as TButton).Caption:='Button 3';
С уважением.
|
|
GAZ (статус: Посетитель), 4 июня 2008, 21:19 [#14]:
Dron
Напишите пожалуйста всю процедуру создания,не допанимаю я
...просто в одной челочисленной переменной храните последний номер и всё. Если кнопки могут удаляться (уничтожаться), тогда массив чисел...
procedure TForm1.SpeedButton1Click(Sender: TObject);
|
|
ANBsoft (статус: Студент), 4 июня 2008, 21:31 [#15]:
Логика примерно такая:
Var N:Integer; //число созданных кнопок
B:TButton;
Begin
N:=1;
B:=TButton.Create(Nil);
B.Name:='MyButton'+IntToStr(N);
.....Далее также как при работе с массивом.
Обращение к нужной кнопке:
(Form1.FindComponent('MyButton'+IntToStr(N)) as TButton).
Проблема в том, что если какие-либо из ранее созданных кнопок удалить, то неизвестно существует ли кнопка с заданным именем, если нет, то FindComponent выдаст ошибку.
В таком случае нужно или хранить массив кнопок или создавать связанный список.
А какие проблемы с массивом?
|
|
Dron (статус: Студент), 4 июня 2008, 21:36 [#16]:
var
Form1: TForm1;
Btn: TButton;
BtnCount: Integer = 0;
implementation
{$R *.dfm}
procedure TForm1.Button1Click(Sender: TObject);
begin
Inc(BtnCount);
Btn:=TButton.Create(Self);
Btn.Parent:=Self;
Btn.Top:=Random(Self.ClientHeight);
Btn.Left:=Random(Self.ClientWidth);
Btn.Width:=75;
Btn.Height:=22;
Btn.Name:='MyButton'+IntToStr(BtnCount);
end;
procedure TForm1.Button2Click(Sender: TObject);
begin
(Self.FindComponent('MyButton'+Edit1.Text) as TButton).Caption:='New caption';
end;
При нажатии на Button1 создаётся ещё одна кнопка. Далее в Edit1 вводится номер кнопки и при нажатии на Button2 текст на этой кнопке меняется.
С уважением.
|
|
GAZ (статус: Посетитель), 4 июня 2008, 21:43 [#17]:
После создания кнопки её я перетаскиваю в нужное мне место
....
AButton[n].OnMouseDown:=Button1MouseDown;
....
следующей процедурой
procedure TForm1.Button1MouseDown(Sender: TObject; Button:
TMouseButton; Shift: TShiftState; X, Y: Integer);
{$IFNDEF WIN32}
var
pt: TPoint;
{$ENDIF}
begin
if ssCtrl in Shift then
begin
ReleaseCapture;
SendMessage(Button1.Handle, WM_SYSCOMMAND, 61458, 0);
{$IFNDEF WIN32}
GetCursorPos(pt);
SendMessage(Button1.Handle,
WM_LBUTTONUP,
MK_CONTROL,
Longint(pt));
{$ENDIF}
end;
end;
так вот если описать Var AButton:Array[1..10000] of TButton; то возникает ошибка
|
|
Dron (статус: Студент), 4 июня 2008, 22:04 [#18]:
А вы заранее знаете, что у вас будет 10к кнопок?
С уважением.
|
|
GAZ (статус: Посетитель), 4 июня 2008, 22:14 [#19]:
Dron спасибо я добился того чего хотел.
|
|
Dron (статус: Студент), 4 июня 2008, 22:20 [#20]:
Хорошо. Удачи! 
P.S. Не забивайте память 10 тысячами пустых указателей.
С уважением.
|
Чтобы оставлять сообщения в мини-форумах, Вы должны авторизироваться на сайте.
|