Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

Самодельный Button, событие Click [D6, WinXP]


Pavelkq ©   (2005-10-11 13:41:00) 

Здравствуйте! Создаю в программе форму ( create, show. Затем создаю на этой форме кнопку  HelpBut:=TButton.Create(HelpFrm);
 with HelpBut do
 begin
   parent:=HelpFrm;
   Width:=120;
   Height:=20;
   Left:=150;
   Top:=340;
   Caption:=('Название');
 end;

Что надо написать, чтобы можно было сделать подпрограмму обработки события onClick?


jack128   (2005-10-11 15:03:00) [1]

Ega23 ©   (11.10.05 14:47) [5]
procedure BtnClearClick(Sender:TObject);

Ega23 ©   (11.10.05 14:47) [5]
 With TButton.Create(aPanel) do
  begin
   OnClearClick.Code:=@BtnClearClick;
   OnClearClick.Data:=aForm;
   OnClick:=TNotifyEvent(OnClearClick);


А это работает??  я к тому, что вроде процедура должна быть объявлена как procedure BtnClearClick(Self, Sender: TObject); // это же процедура, а не метод, значит Self нужно явно указывать umbra ©
> Sender.HelpRich.Lines.Clear;


(Sender as THelpFrm).HelpRich.Lines.Clear;

THelpFrm - тип Вашей формы umbra ©
> (Sender as THelpFrm).HelpRich.Lines.Clear;


Пардон. Точнее

(Sender.Parent as THelpFrm).HelpRich.Lines.Clear; Pavelkq Спасибо, конечно, но можно сказать для непродвинутых, куда это писать?
Если прямо в обработчик, то пишет, что Parent неизвестный идентификатор.

 Ega23, если задать имя, то в обработчике это имя все равно не опознается.

Может начать с того, куда писать код обработчика? Я написал сразу после implementation. Пробовал и внутри процедуры динамического создания объектов, то тогда не проходит onClick:=MyButtonClickHandler;
Так же совершенно не идет код onClick.code:=MyButtonClickHandler; Amoeba © Читай вот эту статью:
http://www.delphikingdom.com/asp/viewitem.asp?catalogid=342 umbra ©
> для непродвинутых


да я сам продвинутый не очень. два поста - две ошибки.
на cамом деле в обработчике нажатия кнопки надо написать


procedure THelpFrm.MyButtonClickHandler(Sender:TObject);
begin
  Self.HelpRich.Lines.Clear;
end;


Здесь Self - объект, в котором вызывается метод, то есть сама форма. Pavelkq Не понпмает он что такое HelpRich.
Короче, вот весь код:

unit Unit1;

interface

uses
 Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
 Dialogs, StdCtrls, ComCtrls;

type
 TForm1 = class(TForm)
   Button1: TButton;
   procedure Button1Click(Sender: TObject);
 private
 procedure MyButtonClickHandler(Sender:TObject);
   { Private declarations }
 public
   { Public declarations }
 end;

var
 Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.MyButtonClickHandler(Sender:TObject);
begin
ShowMessage('Button clicked!!!');
Self.HelpRich.Lines.Clear;
end;

procedure TForm1.Button1Click(Sender: TObject);
 {Procedure MyButtonClickHandler(Sender:TObject);
 begin
 ShowMessage('Button clicked!!!');
 end;}
var HelpFrm:TForm;
   HelpRich: TRichEdit;
   HelpBut: TButton;
   HelpSet: byte;
begin
HelpSet:=1;
HelpFrm:=TForm.CreateNew(Application);
with HelpFrm do
 begin
 Width:=450;
 Height:=410;
 Caption:='Î ïðîãðàììå';
 Position:=poDesktopCenter;
 BorderIcons:=HelpFrm.BorderIcons-[biMinimize];
 BorderIcons:=HelpFrm.BorderIcons-[biMaximize];
 BorderIcons:=HelpFrm.BorderIcons-[biHelp];
 end;

HelpRich:=TRichEdit.Create(HelpFrm);
with HelpRich do
 begin
 parent:=HelpFrm;
 Width:=445;
 Height:=400;
 Align:=alCustom;
 Color:=clInfoBk;
 Enabled:=true;
 TabOrder:=1;
 ScrollBars:=ssVertical;
 ReadOnly:=true;
 Color:=clRed;
 Color:=clInfoBk;
 BorderWidth:=14;
 Font.Name:='Times New Roman';
 Font.Size:=11;
 if HelpSet=1 then
   begin
   SelAttributes.Height:=SelAttributes.Height+5;
   SelAttributes.Style:=[fsBold];
   Lines.Add('          Ïðîãðàììà "Ôîðìèðîâàíèå áàçû".');
   SelAttributes.Style:=[];
   Lines.Add('');
   Lines.Add(' Ï.À.');
   end;
 end;
if HelpSet=1 then
 begin
 HelpBut:=TButton.Create(HelpFrm);
 with HelpBut do
   begin
   parent:=HelpFrm;
   Width:=120;
   Height:=20;
   Left:=150;
   Top:=340;
   Caption:=('Êàê ïîëüçîâàòüñÿ');
   onClick:=MyButtonClickHandler;
   end;
 end;
HelpFrm.Show;
end;

end.
Ega23 ©
> А это работает??  я к тому, что вроде процедура должна быть
> объявлена как procedure BtnClearClick(Self, Sender: TObject);
>


OnClearClick:TMethod;

? Ega23 ©
> procedure TForm1.Button1Click(Sender: TObject);
>  {Procedure MyButtonClickHandler(Sender:TObject);
>  begin
>  ShowMessage('Button clicked!!!');
>  end;}
> var HelpFrm:TForm;


У тебя не TForm, а TForm1.
Конечно, TForm1 является наследником TForm, но при обращении к TForm1 как к TForm ты не узнаешь ничего о, например, Button1. jack128 © Ega23 ©   (11.10.05 15:55) [15]
OnClearClick:TMethod;


И ??

вообще то процедура должна была быть объявлена так:
procedure BtnClearClick(Self {в этот параметр передается то что ты записал в OnClearClick.Data, то есть форма}, Sender{а вот сюда передется тот контрол, которому собствено кликнули мышой - кнопка}: TObject);

А работает это у тя только потому, что оба этих параметра передаются через регистры проца.  Вот если бы событие использовало модель вызова stdcall(передача параметров через стек) или напрмер событие принемало бы больше 3 параметров, то ты бы схватил AV. Ega23 ©
> А работает это у тя только потому, что оба этих параметра
> передаются через регистры проца.  Вот если бы событие использовало
> модель вызова stdcall(передача параметров через стек) или
> напрмер событие принемало бы больше 3 параметров, то ты
> бы схватил AV.


Спасибо, учту. umbra ©
> Не понпмает он что такое HelpRich.

да и не поймет. в коде после выхода из Button1Click нигде не сохраняются указатели на созданные объекты. А поскольку у них нет имен, то и найти их невозможно. Если чуть чуть Ваш код поправить, то будет работать


procedure TForm1.Button1Click(Sender: TObject);
{........................................}
 with HelpRich do
   begin
    {...........................}
    name := 'hr';    //ВОТ ДОПОЛНЕНИЕ!!!!!
    {....................................}
  end;

procedure TForm1.MyButtonClickHandler(Sender:TObject);
var
 par: TWinControl;
 cont: TComponent;

begin
ShowMessage('Button clicked!!!');
par := (Sender as TControl).Parent;
cont := par.FindComponent('hr');
if Assigned(cont) then
 (cont as TRichEdit).Lines.Clear;
end;

Ega23 © 2 umbra ©   (11.10.05 18:27) [19]
par := (Sender as TControl).Parent;
cont := par.FindComponent('hr');
if Assigned(cont) then
(cont as TRichEdit).Lines.Clear;


А теперь прикинь: форма, на ней панель с Align:=alBottom, на панели искомая кнопка. А RichEdit лежит на самой форме с обтеканием Align:=alClient.

Вопрос: чему будет равен cont? umbra ©
> Вопрос: чему будет равен cont?
>


NIL конечно. Но в представленном автором коде ничего такого нет. Я ж просто пытаюсь дать пример, как можно искать контролы в указанном случае. Если динамически много форм создавать, я бы лично сохранял указатели на них Pavelkq [19] Уже лучше, если считать, что компилятор не ругается. Но все равно не работает. Вот какие значения получаются:
par=(FcomponentStyle:[csInheritable];FDoubleBuffered:False;FInImeComposition:False;FDesignSize:(X:0; Y:0))
cont=(FcomponentStyle:[csInheritable])
После выполнения (cont as TRichEdit).Lines.Clear;выводится ошибка Invalid class typecast. Pavelkq Извеняюсь, друзья! По невнимательности присвоил имя не тому экземпляру. В действительности все заработало идеально! Огромное спасибо!
С удовольствием читаю статью предложенную Amoeba[12]


Ega23   (2005-10-11 14:54:00) [2]


> Но в таком виде это почему-то не работает, поскольку данная
> процедура ничего не знает об объекте ричэдит.


Задавай ему Name и потом по нему обращайся.


Pavelkq   (2005-10-11 14:51:00) [3]

Sender, по моему представлению, будет или сама HelpBut (кнопка) или HelpFrm (динамическая форма). У кнопки родитель форма. Ясно, что ричэдит тоже имеет родителем эту форму. По логике надо писать что-то типа:
procedure TForm1.MyButtonClickHandler(Sender:TObject);
begin
Sender.HelpRich.Lines.Clear;
end;

 Но в таком виде это почему-то не работает, поскольку данная процедура ничего не знает об объекте ричэдит.


Ega23   (2005-10-11 14:47:00) [4]

Вот, посмотри пример:
function ShowTexLogFile(const aFileName:String):Boolean;
           procedure BtnClearClick(Sender:TObject);
           var
            i:Integer;
            _memo:TMemo;
           begin
            if (Sender is TForm) then
             begin
              With TForm(Sender) do
               begin
                for i:=0 to ComponentCount-1 do
                 if (Components[i] is TMemo) then
                  if UpperCase(TMemo(Components[i]).Name)=UpperCase('memSQLLogMonitor') then
                   begin
                    _memo:=TMemo(Components[i]);
                    _memo.Lines.Clear;
                    _memo.Lines.Add(' ');
                    _memo.Lines.SaveToFile(_memo.Hint);
                    Break;
                   end;
               end;//With TForm(Sender) do
             end;//if (Sender is TForm) then
           end;//procedure BtnClearClick(
var
aForm:TForm;
aPanel:TPanel;
OnClearClick:TMethod;
List:TStringList;
i:Integer;
begin
Result:=False;
//if not FileExists(aFileName) then Exit;
try
 Application.CreateForm(TForm, aForm);
 try
  With aForm do
   begin
    Caption:=aFileName;
    BorderStyle:=bsSingle;
    Height:=500;
    Width:=750;
    Position:=poScreenCenter;
   end;
  With TMemo.Create(aForm) do
   begin
    Parent:=aForm;
    Name:='memSQLLogMonitor';
    Align:=alClient;
    ScrollBars:=ssBoth;
    //Height:=440;
    Clear;
    Hint:=aFileName;
    List:=TStringList.Create;
    if FileExists(aFileName) then
     begin
      List.LoadFromFile(aFileName);
      for i:=List.Count-1 downto 0 do Lines.Add(List.Strings[i]);
     end;
    List.Free;
   end;
  aPanel:=TPanel.Create(aForm);
  With aPanel do
   begin
    Parent:=aForm;
    Height:=45;
    Align:=alBottom;
   end;
  With TButton.Create(aPanel) do
   begin
    Parent:=aPanel;
    Cancel:=True;
    Height:=25;
    Width:=100;
    Font.Size:=10;
    Top:=10; //aPanel.ClientHeight-10;
    Left:=aPanel.Width-110;
    Anchors:=[akTop, akRight];
    Caption:='Закрыть';
    ModalResult:=mrOK;
   end;
  With TButton.Create(aPanel) do
   begin
    Parent:=aPanel;
    Height:=25;
    Width:=100;
    Font.Size:=10;
    Top:=10; //aPanel.ClientHeight-30;
    Left:=aPanel.Width-220;
    Anchors:=[akTop, akRight];
    Caption:='Очистить';
    OnClearClick.Code:=@BtnClearClick;
    OnClearClick.Data:=aForm;
    OnClick:=TNotifyEvent(OnClearClick);
   end;
  aForm.ShowModal;
 finally
  aForm.Free;
 end;
except on E:Exception do
 raise Exception.Create('ShowTexLogFile '+E.Message);
end;
end;


Здесь всё в динамике создаётся.


Desdechado   (2005-10-11 14:43:00) [5]

у тебя есть Sender, у которого есть Parent
намек ясен?


Pavelkq   (2005-10-11 14:32:00) [6]

Отлично! Работает, т.е. сообщение успешно выскакивает. Но теперь из обработчика не могу достучаться до динамически созданной формы. На динамической форме есть динамически созданный TRichEditи я бы хотел его очистить по нажатию кнопки. Форма создана: HelpFrm:=TForm.CreateNew(Application);
а TRichEdit:
HelpRich:=TRichEdit.Create(HelpFrm);


Ega23   (2005-10-11 13:51:00) [7]

Ну и метод формы
procedure MyButtonClickHandler(Sender:TObject);

procedure TForm1.MyButtonClickHandler(Sender:TObject);
begin
ShowMessage('Button clicked!!!');

end;


Ega23   (2005-10-11 13:49:00) [8]

onClick:=MyButtonClickHandler;


Наверх

Титульная страница Поиск, карта сайта Написать письмо