Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Почтовая рассылка

Подписчиков: -1
Последний выпуск: 19.06.2015

Запуск программно созданного таймера не работает!

1.6K
11 июня 2009 года
Grom2025
82 / / 20.03.2003
При запуске таймера (TimerWater.Enabled:=true;) из процедуры TGmVanna.Button2Click происходит ошибка чтения памяти, таймер не запускается... почему?

Код:
unit VannaM;
interface

uses
     Dialogs, Forms, Windows, Messages,  Variants, Classes, Graphics, SysUtils, Controls, StdCtrls, ExtCtrls,Math,RzButton,RzPrgres;

type
  TGmVanna = class(TPanel)


  private

    { Private declarations }
  protected




    procedure CreateButton(theButton:TRzBitBtn; Caption:String; X:Integer; Y:Integer; Event:TNotifyEvent);

    { Protected declarations }
  public
     TimerWater: TTimer;
     ID:String;
    Image:TImage;
    mLabel:TLabel;
    mBut1:TRzBitBtn;
    mBut2:TRzBitBtn;
    mBut3:TRzBitBtn;
    mBut4:TRzBitBtn;
    mBut5:TRzBitBtn;
    //var DataMap1: TDataMap;

    procedure SetPosition();{ Public declarations }
    procedure HelpME();
    Constructor Create(AOwner: TComponent); override;
      procedure Button1Click(Sender: TObject);
      procedure Button2Click(Sender: TObject);
      procedure Button3Click(Sender: TObject);
      procedure Button4Click(Sender: TObject);
      procedure Button5Click(Sender: TObject);

    procedure twInterval(Sender: TObject);
    //Constructor Show(AOwner: TComponent); override;
  published

    { Published declarations }
  end;

procedure Register;

implementation
uses frmMain;

procedure Register;
begin
  RegisterComponents('Samples', [TGmVanna]);
end;

constructor TGmVanna.Create;
begin
  inherited Create(AOwner);
  Width := 180;
  Height := 320;
  //Picture.LoadFromFile('bath.bmp');
  //Hint := ''+Name;
  //ShowHint:=true;
  //Some Do

  Image :=TImage.Create(Self);
  Image.Parent := Self;
  Image.Top:=0;
  Image.Left:=0;

  Image.Width:=180;
  Image.Height:=320;
  Image.Picture.LoadFromFile('bath.bmp');
  //Image.Visible:=true;
end;

procedure TGmVanna.twInterval(Sender: TObject);
begin
  //Button3Click(mBut3);
  ShowMessage('Timer GOGO');
  //(FindComponent('TimerWater'+IntToStr(Tag)) as TTimer).Enabled:=false;
end;

procedure TGmVanna.Button1Click(Sender: TObject);
var tID:String;
    I:integer;
begin
  I:=(Sender as TRzBitBtn).Tag;
  if I>9 then
    begin tID:=IntToStr(I); end
    else begin  tID:='0'+IntToStr(I); end;
  frmMainm.ComPort1.WriteStr('N'+tID+'S0'+#13) ;
end;

procedure TGmVanna.Button2Click(Sender: TObject);
var tID:String;
    I:integer;
begin

  I:=(Sender as TRzBitBtn).Tag;
  if I>9 then
    begin tID:=IntToStr(I); end
    else begin  tID:='0'+IntToStr(I); end;
  frmMainm.ComPort1.WriteStr('N'+tID+'S1'+#13);

  //ShowMessage((FindComponent('TW0')).ClassName);
  TimerWater.Enabled:=true;
end;

procedure TGmVanna.Button3Click(Sender: TObject);
var tID:String;
    I:integer;
begin
  I:=(Sender as TRzBitBtn).Tag;
  if I>9 then
    begin tID:=IntToStr(I); end
    else begin  tID:='0'+IntToStr(I); end;
  frmMainm.ComPort1.WriteStr('N'+tID+'S2'+#13) ;
end;

procedure TGmVanna.Button4Click(Sender: TObject);
var tID:String;
    I:integer;
begin
  I:=(Sender as TRzBitBtn).Tag;
  if I>9 then
    begin tID:=IntToStr(I); end
    else begin  tID:='0'+IntToStr(I); end;
  frmMainm.ComPort1.WriteStr('N'+tID+'S5'+#13) ;
end;

procedure TGmVanna.Button5Click(Sender: TObject);
var tID:String;
    I:integer;
begin
  I:=(Sender as TRzBitBtn).Tag;
  if I>9 then
    begin tID:=IntToStr(I); end
    else begin  tID:='0'+IntToStr(I); end;
  frmMainm.ComPort1.WriteStr('N'+tID+'S6'+#13) ;
end;

procedure TGmVanna.CreateButton(theButton:TRzBitBtn; Caption:String; X:Integer; Y:Integer; Event:TNotifyEvent);
begin
  theButton := TRzBitBtn.Create(Self);
  theButton.Parent := Self;
  theButton.Left:=X;
  theButton.Top:=Y;
  theButton.Tag:=StrToInt(ID);
  theButton.HotTrack:=true;
  theButton.Color:=$00F0F4F4;
  theButton.Width:=170;
  theButton.Caption:= Caption ;
  theButton.OnClick := Event;
end;

procedure TGmVanna.SetPosition();
var
 tmp : TNotifyEvent;
 twEvent:TNotifyEvent;
begin

  if Tag>9 then
    begin
      ID := IntToStr(Tag);
    end
  else
    begin
      ID := '0'+IntToStr(Tag);
    end;
  TimerWater:= TTimer.Create(Self);
  TimerWater.Enabled:=false;
  //TimerWater.Name:='TW'+IntToStr(Tag);
  TimerWater.Interval:=(5000);
  @twEvent:=@TGmVanna.twInterval;
  TimerWater.OnTimer:=twEvent;

 
  mLabel := TLabel.Create(Self);
  mLabel.Left:=5;
  mLabel.Top:=5;
  mLabel.Parent := Self;
  mLabel.Transparent:=true;
  mLabel.Caption:='Ванна №' +ID;
  mLabel.BringToFront;
  Hint := Name;


  @tmp := @TGmVanna.Button1Click;
  CreateButton(mBut1,'Сброс режима',5,20,tmp);
  @tmp := @TGmVanna.Button2Click;
  CreateButton(mBut2,'Залив воды',5,45,tmp);
  @tmp := @TGmVanna.Button3Click;
  CreateButton(mBut3,'Ожидание погружения',5,70,tmp);
  @tmp := @TGmVanna.Button4Click;
  CreateButton(mBut4,'Слив воды',5,95,tmp);
end;

procedure TGmVanna.HelpMe();
begin
  Image.Picture.LoadFromFile('bathh.bmp');
end;

end.
303
11 июня 2009 года
makbeth
1.0K / / 25.11.2004
 
Код:
@tmp := @TGmVanna.Button1Click;
CreateButton(mBut1,'Сброс режима',5,20,tmp);
@tmp := @TGmVanna.Button2Click;
CreateButton(mBut2,'Залив воды',5,45,tmp);
@tmp := @TGmVanna.Button3Click;
CreateButton(mBut3,'Ожидание погружения',5,70,tmp);
@tmp := @TGmVanna.Button4Click;
CreateButton(mBut4,'Слив воды',5,95,tmp);
Это вообще как понимать? Что у тебя в итоге запишется в обработчик события нажатия кнопки?
1.6K
11 июня 2009 года
Grom2025
82 / / 20.03.2003
Хм... запишется то что записываю
303
11 июня 2009 года
makbeth
1.0K / / 25.11.2004
Хм... А что записываешь?
14
11 июня 2009 года
Phodopus
3.3K / / 19.06.2008
Ну если отвечать на вопрос "почему?" - то потому, что вы совершенно не понимаете что программируете. Указатель Self получается не определен. Кстати таймер работает, ага, через раз. В первый раз он у меня заработал и я даже страшно удивился. Потом оказалось счастливый случай :)
Чтобы заработало надо
 
Код:
tmp := Button1Click;
tmp := Button2Click;
tmp := Button3Click;
tmp := Button4Click;

как минимум, это там где makbeth указал. Ну а вообще не удивлюсь если потом еще куча глюков вылезет. Мне страшно.
303
11 июня 2009 года
makbeth
1.0K / / 25.11.2004
Ну по счастливому стечению обстоятельств мусор в стеке оказался равен адресу (ссылке) на нужную форму :) Хотя нет, значение не в стеке, а в регистре, Delphi вроде использует регистровую модель передачи параметров?
14
11 июня 2009 года
Phodopus
3.3K / / 19.06.2008
Цитата: makbeth
Ну по счастливому стечению обстоятельств мусор в стеке оказался равен адресу (ссылке) на нужную форму :) Хотя нет, значение не в стеке, а в регистре, Delphi вроде использует регистровую модель передачи параметров?


Все верно сказал, хотя все-таки в стеке т.к. переменная tmp там расположена. И ее последний dword удачно оказался Self. Поставив tmp := nil перед этой свистопляской мы и получим AV как ожидается при обращении к Timer.

1.6K
12 июня 2009 года
Grom2025
82 / / 20.03.2003
И что Вы уважаемые господа предлагаете сделать?
14
12 июня 2009 года
Phodopus
3.3K / / 19.06.2008
Цитата: Grom2025
И что Вы уважаемые господа предлагаете сделать?


С чем именно?

303
12 июня 2009 года
makbeth
1.0K / / 25.11.2004
 
Код:
CreateButton(mBut1,'Сброс режима',5,20,Button1Click);
ы?
1.6K
15 июня 2009 года
Grom2025
82 / / 20.03.2003
Кстати замечу что в теме http://forum.codenet.ru/showpost.php?p=267063&postcount=1 никто не возмущался по поводу @a:=@b

И если для батона прокатила запись вида
 
Код:
CreateButton(mBut2,'Наполнение ванны',5,45,Button2Click);
то почему та же форма не применима к TTimer????????

Код:
procedure TGmVanna.CreateTimer(theTimer:TTimer; Event:TNotifyEvent; interval:Integer);
begin
  theTimer := TTimer.Create(Self);
  //theTimer. := Self;
  theTimer.Enabled:=false;
  //TimerWater.Name:='TW'+IntToStr(Tag);
  theTimer.Interval:=(interval);
  //@twEvent:=@TGmVanna.twInterval;
  theTimer.OnTimer:=Event;
end;

procedure TGmVanna.twInterval(Sender: TObject);
begin
  Button3Click(mBut3);
  //ShowMessage('Timer GOGO');
  //TimerWater.Enabled:=false;
end;

constructor TGmVanna.Create;
begin
  inherited Create(AOwner);
  CreateTimer(TimerWater,twInterval,6000);
  //Image.Visible:=true;
end;
При попытке таймера сработать возникает AV!
303
15 июня 2009 года
makbeth
1.0K / / 25.11.2004
А ты обрати внимание, как там записано @a:=@b, и как у тебя ;)
По поводу твоей ошибки - ты теряешь ссылки на объекты, созданные в функциях CreateXXX. У тебя после вызова ссылка TimerWater остается nil (как, впрочем, и mBut1, mBut2 и т.д.). Правильно будет:
 
Код:
procedure TGmVanna.CreateTimer(var theTimer:TTimer; Event:TNotifyEvent; interval:Integer);
PS: Хорошо хоть память не теряется за счет Create(Self)...
PPS: Блин, ну в отладчике же это стразу видно.. :)
1.6K
15 июня 2009 года
Grom2025
82 / / 20.03.2003
Спасибо makbeth! Тяжело перелезать с си++ на делфи все-таки разница есть большая между ними да и не привык я еще к отладчику на BDS2007 хоть вроде и удобен он
Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог