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 gkittelson on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Create and use timer within a DLL 1

Status
Not open for further replies.

majlumbo

Programmer
Jul 13, 2010
295
US
Does anyone know how to implement and use a timer within a DLL?

I tried using the Windows API SetTimer call to create a timer, but couldn't figure out how to get the application handle, I then tried creating a TTimer, but couldn't figure out how to set the ontimer event since it needs a TObject passed as a parameter (Sender).
 
I don't think it really requires a TObject to be passed, just an empty nil should do it. Of course I've never tried, never had to, but I don't think this is a requirement to have something there in the parameter. This TObject is so that you can make your code in that event's procedure see where this call came from.

JD Solutions
 
I did try nil, but I got an error (I'll post tomorrow when I get back at the office, the exact error).

Following the advice in this article

This is what I have so far:

Code:
uses
  ExtCtrls;

{$R *.res}
type
   TimerEventHandler = class
      Procedure DoTimer;
   end;
var
   tm: TTimer;

Procedure TimerEventHandler.DoTimer;
begin
   //This should be my ontimer event
end;

procedure open;
begin
   tm := TTimer.Create(nil);
   tm.Interval := 5000;
   tm.OnTimer := @TimerEventHandler.DoTimer;
   tm.Enabled := True;
end;
begin
end.

I get this error:

E2010 Incompatible types: 'TNotifyEvent' and 'Pointer'

If I change
@TimerEventHandler.DoTimer;
to
TimerEventHandler.DoTimer;

Then my error is

E2009 Incompatible types: 'method pointer and regular procedure'
 
Remember the TTimer is actually a TComponent (drop-in) which has published even properties. In this case, your procedure must match the "OnTimer" event. In other words, your definition of the procedure DoTimer needs to have the object...

Code:
Procedure TMyClass.DoTimer(Sender: TObject);
begin
  //Code executed when timer is executed
end;

constructor TMyClass.Create;
begin
   tm := TTimer.Create(nil);
   tm.Interval := 5000;
   tm.OnTimer := DoTimer;
   tm.Enabled := True;
end;


JD Solutions
 
Code:
  type
    TimerEventHandler = class
      procedure DoTimer(Sender: TObject);
    end;
  var
    myEvent: TimerEventHandler;
    myTimer: TTimer;

  procedure TimerEventHandler.DoTimer(Sender: TObject);
    begin
...
    end;
...
      MyTimer.OnTimer := myEvent.DoTimer;
      MyTimer.Interval := 500;
      MyTimer.Enabled := true;
...

Though given a similar situation, I would probably just descend an object from the other and add my event method to it.

Code:
TimerEventHandler = class(TTimer)
  procedure DoTimer(Sender: TObject);
end;

var
  myTimer: TimerEventHandler;

procedure TimerEventHandler.DoTimer(Sender: TObject);
  begin
...
  end;
...
MyTimer.OnTimer := myTimer.DoTimer;
MyTimer.Interval := 500;
MyTimer.Enabled := true;

It is not possible for anyone to acknowledge truth when their salary depends on them not doing it.
 
why not wrap the whole thing up in one sealed class??

Code:
type
 TimerClass = class(TObject)
 private
   Timer : TTimer;
   FObject : TObject;
   procedure OnTimer(Sender : TObject);
 public
   constructor Create;
   destructor Destroy; override;
 end;

...
implementation

...
{ TimerClass }

constructor TimerClass.Create(AObject : Tobject);
begin
 FObject := AObject;
 Timer := TTimer.Create(nil);
 Timer.Interval := 1000;
 Timer.Enabled := True;
end;

destructor TimerClass.Destroy;
begin
 FreeAndNil(Timer);
 inherited;
end;

procedure TimerClass.OnTimer(Sender: TObject);
begin
 DoSomethingWithObject(FObject);
end;

using it like this you can make your class testable.
Always think about separation of concerns (
/Daddy

-----------------------------------------------------
What You See Is What You Get
Never underestimate tha powah of tha google!
 
forgot a small part in the code

Code:
...
Timer := TTimer.Create(nil);
[b]Timer.OnTimer := OnTimer[/b]
Timer.Interval := 1000;
...

-----------------------------------------------------
What You See Is What You Get
Never underestimate tha powah of tha google!
 
we really need an edit function in this forum :(

/Daddy

-----------------------------------------------------
What You See Is What You Get
Never underestimate tha powah of tha google!
 
Daddy,

Had to move

Timer.OnTimer := OnTimer

inside the constructor, otherwise, the compiler complained that OnTimer was an undeclared variable even though I had the OnTimer method declared. Since it was now part of the object, I had to prepend it with TimerClass.OnTimer...

It did compile that way, but my dll failed to load.

Glenn

Your suggestion allowed the DLL to compile, but it also failed to load.

I created the timer object in DLLMain when DLL_PROCESS_ATTACH is the reason, and I Freed the Timer on DLL_PROCESS_DETACH.
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top