Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations Chris Miller on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

how to get TTimer to trigger in a custom Component 1

Status
Not open for further replies.

john230873

Programmer
Oct 3, 2003
89
NZ
I have started to write a new component that I want to check its parents colour every 5 second to match it. Instead of having a timer in the main program I thought I would write it in the component. Question if I was to add a TTimer component to the main form I would double click on the TTimer for its trigger to be automactilly set up. BUT how do I get it to trigger if I have it create its self at runtime. Heres my code so far how would I go about actioning the TTimerTimer procedure at run time.


unit ImagePanel;

interface

uses
SysUtils, Classes, Controls, ExtCtrls;

type
TImagePanel = class(TPanel)
private
{ Private declarations }
constructor Create (AOwner : TComponent); override;
procedure CreateWnd ; override;
protected
{ Protected declarations }

public
{ Public declarations }
published
{ Published declarations }
end;

procedure Register;

implementation
var
PictureImage : TImage;
procedure Register;
begin
RegisterComponents('Samples', [TImagePanel]);
end;


constructor TImagePanel.Create (AOwner : TComponent);
begin
inherited Create (AOwner);
end;

procedure TImagePanel.CreateWnd;
begin
inherited CreateWnd;
Caption := '';

Timer1 :=TTimer.Create(self);
Timer1.Parent := self;
end;
 
I'm pretty new to Delphi, but I think all you have to do is set the following to start the timer:
Timer1.Enabled := True;
It will then generate a repeating Timer message with a separation of Timer1.Interval (in millisec).
To stop the TTimer at any time just set
Timer1.Enabled := False;

For what you are proposing I think you should add the following to your calling code:
OnTimer1 := Timer1Timer; //Declares response to Timer1 event
Timer1.Interval := 5000; //5 sec separation between events
Timer1.Enabled := True;

You will also need a new procedure declared and implemented for the response to the Timer event (assumed to be in Form1):
procedure TForm1.Timer1Timer(Sender: TObject)
begin
{ Your code }
end;

Hope this isn't too misleading (this is the first time I've responded to a plea for help!). Best of luck.
Bob
 
Thanks but you have missed the point, I don't want to create the timer in Form1 I want to create it in a non form base unit that is used as a component.
 
John
Please forgive a first timer (lol) for missing the point. The following should show you what to do. The trick is that the Timer is declared as a field of TImagePanel.
I have created and initialised the timer in the constructor (I haven't used the CreateWnd method before). For testing I used Beep() in place of { Your code }.
Hope this is what you wanted.
Bob

Code:
unit ImagePanel;

interface

uses
  SysUtils, Classes, Controls, ExtCtrls;

type
  TImagePanel = class(TPanel)
  private
    { Private declarations }
    Timer1: TTimer;
  protected
    { Protected declarations }
    procedure Timer1Timer(Sender: TObject);
  public
    { Public declarations }
    constructor Create(AOwner: TComponent); override;
    procedure CreateWnd; override;
    destructor Destroy; override;
  published
    { Published declarations }
  end;

procedure Register;

implementation
var
  PictureImage : TImage;
procedure Register;
begin
  RegisterComponents('Samples', [TImagePanel]);
end;

constructor TImagePanel.Create(AOwner: TComponent);
begin
  inherited Create(AOwner);
  Timer1 := TTimer.Create(self);
  Timer1.OnTimer := Timer1Timer;
  Timer1.Interval := 5000;
  Timer1.Enabled := True;
end;

procedure TImagePanel.CreateWnd;
begin
  inherited CreateWnd;
  Caption := '';
end;

destructor TImagePanel.Destroy;
begin
  Timer1.Free;
  inherited Destroy;
end;

procedure TImagePanel.Timer1Timer(Sender: TObject);
begin
  { Your code }
end;

end.
 
Thanks Great, this was what I was after. Now can you help on the next bit. The major problem I am having is the highlighting, any ideas (to do with finding location of button). What books or web sites are you using to find your infomation?

unit PanelImage;

interface

uses
SysUtils, Classes, Controls, ExtCtrls,StdCtrls,Graphics,forms;

type
TPanelImage = class(TPanel)
Timer1 :TTimer;
Image1 : TImage;
Mouse1 : TMouse;
private
{ Private declarations }
protected
{ Protected declarations }
public
{ Public declarations }
constructor Create (AOwner : TComponent); override;
procedure CreateWnd; override;
procedure Timer1Timer(AOwner : TObject);
procedure Image1Click(Sender: TObject);
published

{ Published declarations }
end;

procedure Register;

implementation

var
Picture1 : TPicture;

procedure Register;
begin
RegisterComponents('Standard', [TPanelImage]);
end;

constructor TPanelImage.Create(AOwner : TComponent);
begin
inherited Create (AOwner);

Timer1 := TTimer.Create(self);
Timer1.Interval := 100;
Timer1.OnTimer := Timer1Timer;

BevelOuter := bvNone;

Mouse := TMouse.Create;

Image1 := TImage.Create(self);
Image1.Align := alClient;
Image1.Parent := self;
Image1.OnClick := Image1Click;
Image1.Center := True;
Picture1 := TPicture.Create();
Picture1.LoadFromFile('C:\Documents and Settings\johnw\Desktop\New Folder (4)\eWorld 2000 Win\The icons\efolder.ico' );
Image1.Picture := Picture1;

end;

procedure TPanelImage.CreateWnd();
begin
inherited CreateWnd;
self.Caption := '';
end;

procedure TPanelImage.Timer1Timer(AOwner : TObject);
var
X,Y: integer;
MainForm_Top : Integer;
MainForm_Left : Integer;

begin
X := Mouse.CursorPos.X;
Y := Mouse.CursorPos.Y;

MainForm_Top := Application.MainForm.Top;
MainForm_Left := Application.MainForm.Left;

If (Y >= top + MainForm_Top + 30) and (Y <= MainForm_Top + Top + height + 30) and (X >= left + MainForm_Left) and (X <= MainForm_Left + left + Width)
then color := clskyblue
else
color := clbtnface;

end;

procedure TPanelImage.Image1Click(Sender: TObject);
begin
beep;
end;
 
John,
Not quite sure what you want to do, but I think you want to know when the mouse is inside the TImagePanel. There are 2 windows messages CM_MOUSEENTER and CM_MOUSELEAVE that will tell you when when you are entering or leaving the control. In Delphi 6 and 7 there are associated OnMouseEnter and OnMouseLeave events within TControl, but I'm not sure if these are available to you in TPanel.

The best way is probably to work directly with the windows messages. Add declarations of message handler routines to TImagePanel:

Code:
  procedure CMMouseEnter(var Message: TMessage); message CM_MOUSEENTER;
  procedure CMMouseLeave(var Message: TMessage); message CM_MOUSELEAVE;

Also add a boolean variable
Code:
IsInControl
to the private field of TImagePanel.

Then in the implementation add 2 routines as follows to set
Code:
IsInControl
:

Code:
  procedure TControl.CMMouseEnter(var Message: TMessage);
  begin
    IsInControl := True;
  end;

  procedure TControl.CMMouseLeave(var Message: TMessage);
  begin
    IsInControl := False;
  end;

Your Timer1Timer routine is then simplified to:
Code:
  if IsInControl then
    color := clskyblue
  else
    color := clbtnface;
  Repaint;  //Forces an immediate update of the control's display

HOWEVER, this will only change the look of the button if the mouse happens to be inside the panel at the instant the Timer1 event occurs (once every 5 sec). It would probably be better the change the colour directly in response to the CM_MOUSEENTER and CM_MOUSELEAVE messages as follows:

Code:
  procedure TControl.CMMouseEnter(var Message: TMessage);
  begin
    Color := clSkyBlue;
    Repaint;
  end;

  procedure TControl.CMMouseLeave(var Message: TMessage);
  begin
    Color := clBtnFace;
    Repaint;
  end;

I should point out that I know MUCH less about windows messages than I do about Delphi code (still beginner) AND I have not tested the above. I think Caveat Emptor is therefore very applicable.

As far as sources of info are concerned:
1) Trawling through the Delphi Help, particularly looking in detail at the Properties and Methods associated with different controls and at the Component Writers Guide.
2) I find many things can be answered by using searches in Google.
3) I also have electronic (pdf) copies of Mastering Delphi 6 by Marco Cantu (download free) and Object Pascal Language Guide (not sure where I got this from?). Looking up Marco Cantu on the web is a good start.
4) I find the 'Source' sub-directory is a great help in showing me how things are done in the Delphi components. I'm not sure which versions of Delphi include the 'Source' directory. I have access to Delphi 7 Enterprise at work.

Hope this helps
Bob


 
why not either create a new class with a new property. The set property method would update the two child classes encapsulated in the class.

or

create a new class of your parent object and override the colour property set method.



There are 10 types of people in the world. Those that understand binary and those that don't.
 
Thanks Bobbie, this has helped and I got rid of the timer and used the mouse messages. All I was doing was writing a image button that what change colour. I have the Delphi 5 book and will look for the delphi 6 pdf. I'm not that new to delphi but I haven't done much work with classes or components so that is an area I am very weak in. Thanks for your help

P.S. you haven't send a date component that allow you to click and select multiple dates on your travels, the standard one only allows single date or a range. I have been to the supperpage and a few others and haven't found one. Its my next project

 
John,
Glad to have been of help. Sorry, haven't seen anything with multiple dates.
Signing off now,
Bob
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top