在dll中怎样用Ttimer定期执行过程(50分)

  • 主题发起人 主题发起人 jsyzzdj
  • 开始时间 开始时间
J

jsyzzdj

Unregistered / Unconfirmed
GUEST, unregistred user!
需要代码
 
以下是一个在控制台程序里使用TTIMER的程序,供你参考:

1. 可以使用非可视控件,只要 uses 相应的 Unit 即可。
关于在 Console Application 里面使用 TTimer 控件,需要说明几点:
(1) Console Application 没有消息处理能力,所以我们要自行处理;
(2) TTimer 的 OnTimer 事件必须为某个类的成员函数,因此要动态的给 OnTimer 时间赋值就需要把 OnTimer 事件的处理函数包装在某个类中(详见代码)
(3) 相较而言,使用 SetTimer/KillTimer API 来做定时器更为简单(因为可以直接设置回调函数)
下面是一个简单的例子:
//-- ConsoleTimerDemo by Plzw ----------------------------------------------------------------------
program ConsoleTimerDemo;

{$APPTYPE CONSOLE}

uses
SysUtils, ExtCtrls, Windows;

type
TMyTimer = class
private
FTimer: TTimer;
procedure TimerProc(Sender: TObject);
public
constructor Create;
destructor Destroy; override;
end;

constructor TMyTimer.Create;
begin
FTimer := TTimer.Create(nil);
FTimer.Interval := 1000;
FTimer.OnTimer := TimerProc;
end;

destructor TMyTimer.Destroy;
begin
FTimer.Free;
inherited;
end;

procedure TMyTimer.TimerProc(Sender: TObject);
begin
WriteLn('Timer Trigger!');
end;

var
Msg: TMsg;
Timer: TMyTimer;
begin
Timer := TMyTimer.Create;
try
while Windows.GetMessage(Msg, 0, 0, 0) do
begin
TranslateMessage(Msg);
DispatchMessage(Msg);
end;
finally
Timer.Free;
end;
end.
 
我需要在dll被加载时定期执行函数或过程,不需要在控制台
 
一、先写一个TMyTimer类吧
unit U_MyTimer;

interface
uses Classes,ExtCtrls,SysUtils;

type
TMyTimer=class(TTimer)
private
FFileName,FPrefix:String;
procedure FOnTimer(Sender:TObject);
public
constructor Create(AOwner:TComponent;AInterval:Integer;AFileName,APrefix:string);
destructor Destroy;override;
//WriteDebugInfo 只是演示 MyTimer 一直在调用的过程
class procedure WriteDebugInfo(strFileName,strMsg: string);
end;

implementation
{ TMyTimer }

constructor TMyTimer.Create(AOwner: TComponent; AInterval:Integer;AFileName,APrefix:string);
begin
inherited Create(AOwner);
Interval:=AInterval;
OnTimer:=FOnTimer;
//以下两个参数只是为了看演示效果
FFileName:=AFileName;
FPrefix:=APrefix;
end;

destructor TMyTimer.Destroy;
begin
OnTimer:=nil;
inherited;
end;

procedure TMyTimer.FOnTimer(Sender: TObject);
begin
WriteDebugInfo(FFileName,FPrefix);
end;

class procedure TMyTimer.WriteDebugInfo(strFileName,strMsg: string);
var
f: textfile;
strLogFile, strLogDir: string;
begin
AssignFile(f, strFileName);
if not fileexists(strFileName) then
Rewrite(f)
else
Append(f);
try
Writeln(f, TimeToStr(now) + ' ' + strMsg);
finally
CloseFile(f);
end;
end;

end.

二、写dll
library MyTimerDll;
uses
SysUtils,
Classes,
U_MyTimer in 'U_MyTimer.pas';

{$R *.res}
//创建一个返回TMyTimer类型的函数
function MyTimerObj(AOnwer:TComponent;AInterval:Integer;AFileName,APrefix:String):TMyTimer;
begin
Result:=TMyTimer.create(AOnwer,AInterval,AFileName,APrefix);
end;

exports
MyTimerObj;
begin
end.

三、测试程式
unit U_Main;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls,
U_MyTimer;
//use u_MyTimer单元
//不然找不到 MyTimerObj函数的返回类型

type
TForm1 = class(TForm)
Button1: TButton;
Button2: TButton;
btnTestMyTimer: TButton;
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
procedure btnTestMyTimerClick(Sender: TObject);
private
{ Private declarations }
FTimer1,FTimer2,FMyTimer:TMyTimer;
public
{ Public declarations }
end;

var
Form1: TForm1;
//声明Dll
function MyTimerObj(AOnwer:TComponent;AInterval:Integer;AFileName,APrefix:String):TMyTimer;external 'MyTimerDll.dll';
implementation

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
begin
if not Assigned(FTimer1) then
FTimer1:=TMyTimer.Create(Self,1000,'c:/Timer1.txt','TestTimer1');
FTimer1.Enabled:=not FTimer1.Enabled;
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
if not Assigned(FTimer2) then
FTimer2:=TMyTimer.Create(Self,333,'c:/Timer2.txt','TestTimer2');
FTimer2.Enabled:=not FTimer2.Enabled;
end;

procedure TForm1.btnTestMyTimerClick(Sender: TObject);
begin
//这里是真正调用dll中的函数哦,上面两个ButtonClick事件是为了和此函数比较调用方法
if not Assigned(FMyTimer) then
FMyTimer:=MyTimerObj(Self,250,'c:/MyTimerDll.txt','MyTimerDll');
FMyTimer.Enabled:=not FMyTimer.Enabled;
end;

end.
 
建议看一下刘艺的《Delphi面向对象编程思想》第七章 研究封装
用Dll封装对象
用Dll封装对象(接口)
 
多人接受答案了。
 
后退
顶部