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.
Запуск программно созданного таймера не работает!
При запуске таймера (TimerWater.Enabled:=true;) из процедуры TGmVanna.Button2Click происходит ошибка чтения памяти, таймер не запускается... почему?
Код:
@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);
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);
Хм... запишется то что записываю
Хм... А что записываешь?
Чтобы заработало надо
Код:
tmp := Button1Click;
tmp := Button2Click;
tmp := Button3Click;
tmp := Button4Click;
tmp := Button2Click;
tmp := Button3Click;
tmp := Button4Click;
как минимум, это там где makbeth указал. Ну а вообще не удивлюсь если потом еще куча глюков вылезет. Мне страшно.
Ну по счастливому стечению обстоятельств мусор в стеке оказался равен адресу (ссылке) на нужную форму :) Хотя нет, значение не в стеке, а в регистре, Delphi вроде использует регистровую модель передачи параметров?
Цитата: makbeth
Ну по счастливому стечению обстоятельств мусор в стеке оказался равен адресу (ссылке) на нужную форму :) Хотя нет, значение не в стеке, а в регистре, Delphi вроде использует регистровую модель передачи параметров?
Все верно сказал, хотя все-таки в стеке т.к. переменная tmp там расположена. И ее последний dword удачно оказался Self. Поставив tmp := nil перед этой свистопляской мы и получим AV как ожидается при обращении к Timer.
И что Вы уважаемые господа предлагаете сделать?
Цитата: Grom2025
И что Вы уважаемые господа предлагаете сделать?
С чем именно?
Код:
CreateButton(mBut1,'Сброс режима',5,20,Button1Click);
http://forum.codenet.ru/showpost.php?p=267063&postcount=1 никто не возмущался по поводу @a:=@b
И если для батона прокатила запись вида
то почему та же форма не применима к TTimer????????
При попытке таймера сработать возникает AV!
Кстати замечу что в теме
И если для батона прокатила запись вида
Код:
CreateButton(mBut2,'Наполнение ванны',5,45,Button2Click);
Код:
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;
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;
По поводу твоей ошибки - ты теряешь ссылки на объекты, созданные в функциях CreateXXX. У тебя после вызова ссылка TimerWater остается nil (как, впрочем, и mBut1, mBut2 и т.д.). Правильно будет:
Код:
procedure TGmVanna.CreateTimer(var theTimer:TTimer; Event:TNotifyEvent; interval:Integer);
PPS: Блин, ну в отладчике же это стразу видно.. :)
Спасибо makbeth! Тяжело перелезать с си++ на делфи все-таки разница есть большая между ними да и не привык я еще к отладчику на BDS2007 хоть вроде и удобен он