Модераторы: Snowy, MetalFan, bems, Poseidon
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Удалить кнопку после нажатия на неё 
V
    Опции темы
CrazyPiggy
  Дата 23.11.2009, 01:28 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 47
Регистрация: 4.6.2008

Репутация: нет
Всего: нет



Доброй ночи! У меня тут возникла следующая проблема. В базе хранятся Наименования меню. По ним я на панели TPanel динамически создаю кнопки TButton, каждой кнопке присваиваю Tag для привязки к определенному ID меню. После нажатия какой либо Button необходимо удалить все кнопки на панели которые я создал ранее и продолжить выполнение программы. Но уменя проблема
Делаю следующее   

Код

procedure TForm1.LoadButton;
var
 But:TBitBtn;
 i, j, k, colstr:integer;
begin
  i:=1;
  if not FMenu.IsEmpty then
      begin
      while (i<=FSYSTEMROWCOUNT.AsInteger) and (not FMenu.Eof) do
       begin
        j:=1;
        while (j<=FSYSTEMCOLCOUNT.AsInteger) and (not FMenu.Eof) do
          begin
            But:=TBitBtn.Create(Self);
            But.Caption:=FMenuNAME.AsString;
            But.Left:=(j)*IntervalWidth+(j-1)*ButtonWidth;
            But.Top:=(i)*IntervalHeight+(i-1)*ButtonHeight;
            But.Width:=ButtonWidth;
            But.Height:=ButtonHeight;
            But.Tag:=FMenuID.AsInteger;
            But.OnClick:=ButtonMenuClick;
            But.Parent:=sPanel3;
            j:=j+1;
            fMenu.Next;
           end;
        i:=i+1;
       end;
end;

procedure TForm1.ButtonMenuClick(Sender:TObject);
var
 k:integer
begin
 Logo.Picture.Bitmap:=(Sender as TBitBtn).Glyph;
 CaptionLab.Caption:=(Sender as TBitBtn).Caption;
 Panel3.Tag:=(Sender as TBitBtn).Tag;
   for k:=0 to Panel3.ControlCount-1
      do  Panel3.Controls[0].Free;
end;


вылетает ошибка. Я так понимаю что кнопка сама себя не может удалить. Как же мне быть. Ведь мне нужно очистить память от неё. Может чтото посоветуете? Заранее спасибо.


M
THandle
Модератор: используйте подсветку кода!

PM MAIL   Вверх
Демо
Дата 23.11.2009, 01:44 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1278
Регистрация: 3.11.2005

Репутация: 7
Всего: 50



Цитата(CrazyPiggy @  23.11.2009,  01:28 Найти цитируемый пост)
Как же мне быть. Ведь мне нужно очистить память от неё. Может чтото посоветуете? Заранее спасибо.


При нажатии на кнопку отправляй окну(форме) сообщение PostMessage, в обработчике удаляй кнопку.


Код

type
  TForm1 = class(TForm)
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
  private
    procedure WMUser1(var M: TMessage); message WM_USER+1;
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
begin
  PostMessage(Form1.Handle,WM_USER+1,Integer(Button1),0);
end;

procedure TForm1.WMUser1(var M: TMessage);
begin
  TButton(m.wParam).Free;
end;



--------------------
    
PM MAIL ICQ Skype   Вверх
CrazyPiggy
Дата 23.11.2009, 12:51 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 47
Регистрация: 4.6.2008

Репутация: нет
Всего: нет



Чтото у меня не получается. Все равно дает ошибку. Может вы мне подскажете как правильно сделать.
Дело в том что мне необходимо на панели создавать различные кнопки или писать тескт взависимости от данных в базе. в примере выше я пытаюсь их создать динамически, но потом мне, после нажатия кнопки необходимо опять освободить панель и на ней заново перерисовать или кнопки или текст. Может подскажете алгоритм, вроде я все правильно делаю. Создал обработчик нажатия, при создании кнопки на клик присваиваю этот обработчик
Код

while not FIBdataset.Eof do begin
            But:=TBitBtn.Create(Self);
            But.Tag:=FMenuID.AsInteger;
            But.OnClick:=ButtonMenuClick;
            But.Parent:=Panel3;
            FIBDataset.Next;
            end;

Затем в обработчике 
Код

procedure TForm1.ButtonMenuClick(Sender:TObject);
var
 k:integer
begin
 Logo.Picture.Bitmap:=(Sender as TBitBtn).Glyph;
 CaptionLab.Caption:=(Sender as TBitBtn).Caption;
 Panel3.Tag:=(Sender as TBitBtn).Tag;
 ClearPanel;
end;


присваиваю панели Tag кнопки и из базы выбираю по этому tag данные. А вот удалить предыдущие не могу. Все время вываливается ошибка Abstract Error. Удалить кнопки пытаюсь след. образом
Код

procedure TForm1.ClearPanel;
var
 k:integer;
begin
  for k:=0 to Panel3.ControlCount-1 do
                    do  Panel3.Controls[0].Free;
 end;


Просто на панели у меня могут быть не только кнопки, но и Мемо или Edit;

Это сообщение отредактировал(а) CrazyPiggy - 23.11.2009, 13:09
PM MAIL   Вверх
Данкинг
Дата 23.11.2009, 13:08 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Yersinia pestis
****


Профиль
Группа: Завсегдатай
Сообщений: 8302
Регистрация: 7.11.2006
Где: მოსკოვი

Репутация: 11
Всего: 130



Надо проверять, кнопка ли данный контрол. Попробуй так:
Код

if (Panel3.Controls[0] is TBitBtn) then...



--------------------
There's nothing left but silent epitaphs.
PM MAIL WWW   Вверх
CrazyPiggy
Дата 23.11.2009, 13:14 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 47
Регистрация: 4.6.2008

Репутация: нет
Всего: нет



 Смысл не в том кнопка ли это или нет. Просто не могу очистить панель от всех контролов. Попытался метод ClearPanel реализовать через PostMessage, таже ошибка.
PM MAIL   Вверх
Демо
Дата 23.11.2009, 13:31 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1278
Регистрация: 3.11.2005

Репутация: 7
Всего: 50



Цитата(CrazyPiggy @  23.11.2009,  12:51 Найти цитируемый пост)
Panel3.Controls[0].Free;


Всегда 0?


--------------------
    
PM MAIL ICQ Skype   Вверх
CrazyPiggy
Дата 23.11.2009, 13:35 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 47
Регистрация: 4.6.2008

Репутация: нет
Всего: нет



Цитата

Всегда 0?

Да, всегда 0. А иначе все не удалятся. Пробовал ставить k  вместо ноля удаляет через одну.
Но все это 
Код

 for k:=0 to Panel3.ControlCount-1
      do  Panel3.Controls[0].Free;
 
прекрасно работает если поставить в обработчик нажатия на саму панель, т.к. я её не удаляю, а вот при попытки кнопки удалить саму себя не выходит. Можеь есть другой выход?

Это сообщение отредактировал(а) CrazyPiggy - 23.11.2009, 13:38
PM MAIL   Вверх
kami
Дата 23.11.2009, 13:46 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1806
Регистрация: 25.8.2007
Где: Санкт-Петербург

Репутация: 22
Всего: 72



Если удалять в цикле for, то желательно бы использовать downto, тогда с индексами все будет нормально.

При нажатии на кнопку (из вашего кода) получается, что в обработчике OnClick кнопки вы пытаетесь удалить эту самую кнопку (вкупе с другими компонентами). Забыв о том, что после обработки назначенного вами OnClick выполняются и другие действия, непосредственно затрагивающие поля УЖЕ УДАЛЕННОЙ кнопки. Отсюда и исключение.

Выход - вызывать ClearPanel через событие, как и сказал (более того - показал, как) Демо. Адаптировать его код из уничтожения кнопки под ваши нужды (т.е. вызову ClearPanel) - imho, труда не представляет.

Это сообщение отредактировал(а) kami - 23.11.2009, 13:47
PM MAIL WWW   Вверх
Демо
Дата 23.11.2009, 13:57 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1278
Регистрация: 3.11.2005

Репутация: 7
Всего: 50



Код

procedure TForm1.Button1Click(Sender: TObject);
var
  Btn: TBitBtn;
  pz: Integer;
  i: Integer;
begin
  for i := 0 to 3 do
  begin
    Btn := TBitBtn.Create(Self);
    Btn.Caption := IntToStr(i);
    Btn.Left := Panel1.Left + i*80;
    Btn.Top := Panel1.Top+10;
    Btn.Parent := Panel1;
    Btn.Visible := True;
  end;



Код

procedure TForm1.Button2Click(Sender: TObject);
begin
  while Panel1.ControlCount>0 do
  begin
    Panel1.Controls[0].Free;
  end;


Прекрасно работает.
Значит проблема в другом. Поставь точку останова и пройдись отладчиком. В каком месте кода происходиь ошибка?

Добавлено через 5 минут и 20 секунд
Цитата(CrazyPiggy @  23.11.2009,  13:14 Найти цитируемый пост)
Смысл не в том кнопка ли это или нет. Просто не могу очистить панель от всех контролов. Попытался метод ClearPanel реализовать через PostMessage, таже ошибка.


И даже так всё работает:

Код

procedure TForm1.WMUser1(var M: TMessage);
begin
  TObject(m.wParam).Free;
end;

procedure TForm1.Button1Click(Sender: TObject);
var
  Btn: TBitBtn;
  i: Integer;
begin
  for i := 0 to 3 do
  begin
    Btn := TBitBtn.Create(Self);
    Btn.Caption := IntToStr(i);
    Btn.Left := Panel1.Left + i*80;
    Btn.Top := Panel1.Top+10;
    Btn.Parent := Panel1;
    Btn.Visible := True;
    Btn.OnClick := Button2Click;
  end;
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
  while Panel1.ControlCount>0 do
  begin
    SendMessage(Form1.Handle,WM_USER+1,Integer(Panel1.Controls[0]),0);
  end;
end;



Это сообщение отредактировал(а) Демо - 23.11.2009, 13:58


--------------------
    
PM MAIL ICQ Skype   Вверх
CrazyPiggy
Дата 23.11.2009, 14:22 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 47
Регистрация: 4.6.2008

Репутация: нет
Всего: нет



Цитата

И даже так всё работает:

Код

procedure TForm1.WMUser1(var M: TMessage);
begin
  TObject(m.wParam).Free;
end;

procedure TForm1.Button1Click(Sender: TObject);
var
  Btn: TBitBtn;
  i: Integer;
begin
  for i := 0 to 3 do
  begin
    Btn := TBitBtn.Create(Self);
    Btn.Caption := IntToStr(i);
    Btn.Left := Panel1.Left + i*80;
    Btn.Top := Panel1.Top+10;
    Btn.Parent := Panel1;
    Btn.Visible := True;
    Btn.OnClick := Button2Click;
  end;
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
  while Panel1.ControlCount>0 do
  begin
    SendMessage(Form1.Handle,WM_USER+1,Integer(Panel1.Controls[0]),0);
  end;
end;

Извините, может я "туплю", но я создал заново программу только по вашему примеру. Все нормально, но как доходит очередь до удаления самой кнопки опять вылетает ошибка. Не понимаю что я делаю не так. У вас этот пример работает? Да ещё заметил, если нажать на 1 и 3  все прекрасно работает а вот 0 и 2 выдают ошибку

Это сообщение отредактировал(а) CrazyPiggy - 23.11.2009, 14:26
PM MAIL   Вверх
Демо
Дата 23.11.2009, 14:33 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1278
Регистрация: 3.11.2005

Репутация: 7
Всего: 50



Действительно. Не учёл всего.
Вот должна работать такая процедура:
Код

procedure TForm1.Button2Click(Sender: TObject);
var
  i: Integer;
begin
  for i := Panel1.ControlCount-1 downto 0 do
  begin
    if (Sender=Panel1.Controls[i]) then Continue;
    SendMessage(Form1.Handle,WM_USER+1,Integer(Panel1.Controls[i]),0);
  end;
  PostMessage(Form1.Handle,WM_USER+1,Integer(Sender),0);
end;



Добавлено через 1 минуту и 39 секунд
И даже вот так:

 smile 

Код

procedure TForm1.Button2Click(Sender: TObject);
var
  i: Integer;
begin
  for i := Panel1.ControlCount-1 downto 0 do
    if (Sender<>Panel1.Controls[i]) then Panel1.Controls[i].Free;
  PostMessage(Form1.Handle,WM_USER+1,Integer(Sender),0);
end;




--------------------
    
PM MAIL ICQ Skype   Вверх
CrazyPiggy
Дата 23.11.2009, 14:41 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 47
Регистрация: 4.6.2008

Репутация: нет
Всего: нет



Демо большое спасибо. Все вроде работает
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Delphi: Для новичков"
SnowyMetalFan
bemsPoseidon
Rrader

Запрещается!

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делиться вскрытыми компонентами

  • Литературу по Дельфи обсуждаем здесь
  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Вопросы по реализации алгоритмов рассматриваются здесь
  • 90% ответов на свои вопросы можно найти в DRKB (Delphi Russian Knowledge Base) - крупнейшем в рунете сборнике материалов по Дельфи


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Snowy, MetalFan, bems, Poseidon, Rrader.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Delphi: Для новичков | Следующая тема »


 




[ Время генерации скрипта: 0.0546 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.