首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >有没有办法在组件方法上添加参数?

有没有办法在组件方法上添加参数?
EN

Stack Overflow用户
提问于 2020-07-20 21:21:42
回答 1查看 104关注 0票数 1

我使用的是Delphi10.3,这是一个从手机上读取短信的组件。此组件的工作方式如下:

代码语言:javascript
复制
cmp.ReadSms;

在此之后,将为每条消息调用一个事件onReadSMS

我需要将每条消息保存在数据库中,但是数据库对象在我的main过程中。我无法从活动中访问我的数据库。

我想知道是否有一种方法可以将我的数据库对象传递给事件,这样我就可以在那里进行插入。

编辑:

下面是一些代码:

代码语言:javascript
复制
unit myUnit;
    
TEventHandlers = class
  procedure ReadMessage(Sender: TObject; MessageText: WideString; PhoneNumber, CenterNumber: AnsiString; TimeStamp: TDateTime; TimeZone, Status, Index: Integer);
end;
    
var myEvents: TEventHandlers; 
    
function SMSReceive(dbMain: TFDConnection): Boolean;
var cSMS: TGSMObj;
begin
  cSMS: TGSMObj.create(nil);
  cSMS.OnReadMessage := myEvents.ReadMessage;
  cSMS.ReadSms;
end;
    
procedure TEventHandlers.ReadMessage(Sender: TObject; MessageText: WideString; PhoneNumber, CenterNumber: AnsiString; TimeStamp: TDateTime; TimeZone, Status, Index: Integer);
begin
  // Here I can read the SMS.
  // I would like to do:
  // dbMain.ExecSQL('INSERT INTO ...')
  // But dbMain is unknown here.
end;

我还要补充一点,这个单元是从某个外部线程调用的,所以我不能有一个全局数据库对象,但我需要在调用SMSReceive函数时传递它。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2020-07-21 03:00:20

您无法将自定义参数添加到预先存在的事件中(而不更改组件的源代码)。但是,有一些选项可以尝试操作事件处理程序的操作方式。

最简单的解决方案是从TGSMObj派生一个新类,并在其中添加一个TFDConnection字段,例如:

代码语言:javascript
复制
type
  TMyGSMObj = class(TGSMObj)
    DB: TFDConnection;
  end;

  // 'class' methods can be used as event handlers, so you don't
  // need to create a global object instance of this class...
  TEventHandlers = class
    class procedure ReadMessage(Sender: TObject; MessageText: WideString; PhoneNumber, CenterNumber: AnsiString; TimeStamp: TDateTime; TimeZone, Status, Index: Integer);
  end;

function SMSReceive(dbMain: TFDConnection): Boolean;
var
  cSMS: TMyGSMObj;
begin
  cSMS := TMyGSMObj.Create(nil);
  cSMS.DB := dbMain;
  cSMS.OnReadMessage := TEventHandlers.ReadMessage;
  cSMS.ReadSms;
end;
    
class procedure TEventHandlers.ReadMessage(Sender: TObject; MessageText: WideString; PhoneNumber, CenterNumber: AnsiString; TimeStamp: TDateTime; TimeZone, Status, Index: Integer);
begin
  TMyGSMObj(Sender).DB.ExecSQL('INSERT INTO ...');
end;

或者,如果TGSMObjTComponent的后代,您可以使用其Tag属性来保存TFDConnection指针,例如:

代码语言:javascript
复制
type
  TEventHandlers = class
    class procedure ReadMessage(Sender: TObject; MessageText: WideString; PhoneNumber, CenterNumber: AnsiString; TimeStamp: TDateTime; TimeZone, Status, Index: Integer);
  end;

function SMSReceive(dbMain: TFDConnection): Boolean;
var
  cSMS: TGSMObj;
begin
  cSMS := TGSMObj.Create(nil);
  cSMS.Tag := NativeInt(dbMain);
  cSMS.OnReadMessage := TEventHandlers.ReadMessage;
  cSMS.ReadSms;
end;
    
class procedure TEventHandlers.ReadMessage(Sender: TObject; MessageText: WideString; PhoneNumber, CenterNumber: AnsiString; TimeStamp: TDateTime; TimeZone, Status, Index: Integer);
begin
  TFDConnection(TGSMObj(Sender).Tag).ExecSQL('INSERT INTO ...');
end;

或者,您可以使用TMethod记录来强制事件处理程序的Self参数指向您想要的任何内容,例如:

代码语言:javascript
复制
type
  TEventHandlers = class
    class procedure ReadMessage(Sender: TObject; MessageText: WideString; PhoneNumber, CenterNumber: AnsiString; TimeStamp: TDateTime; TimeZone, Status, Index: Integer);
  end;

function SMSReceive(dbMain: TFDConnection): Boolean;
var
  cSMS: TGSMObj;
  Handler: TWhateverTypeOnReadMessageUses;
begin
  Handler := TEventHandlers.ReadMessage;
  TMethod(Handler).Data := dbMain;

  cSMS := TGSMObj.Create(nil);
  cSMS.OnReadMessage := Handler;
  cSMS.ReadSms;
end;
    
class procedure TEventHandlers.ReadMessage(Sender: TObject; MessageText: WideString; PhoneNumber, CenterNumber: AnsiString; TimeStamp: TDateTime; TimeZone, Status, Index: Integer);
begin
  TFDConnection(Self).ExecSQL('INSERT INTO ...');
end;

或者,无论如何都要使用TMethod,您可以使用独立的过程而不是类方法,例如:

代码语言:javascript
复制
procedure ReadMessage(Self: Pointer; Sender: TObject; MessageText: WideString; PhoneNumber, CenterNumber: AnsiString; TimeStamp: TDateTime; TimeZone, Status, Index: Integer);
begin
  TFDConnection(Self).ExecSQL('INSERT INTO ...');
end;

function SMSReceive(dbMain: TFDConnection): Boolean;
var
  cSMS: TGSMObj;
  Handler: TWhateverTypeOnReadMessageUses;
begin
  TMethod(Handler).Data := dbMain;
  TMethod(Handler).Code := @ReadMessage;

  cSMS := TGSMObj.Create(nil);
  cSMS.OnReadMessage := Handler;
  cSMS.ReadSms;
end;

或者,class helper可能会起作用(我自己还没有试过这个),例如:

代码语言:javascript
复制
type
  TFDConnectionHelper = class helper for TFDConnection
  public
    procedure ReadMessage(Sender: TObject; MessageText: WideString; PhoneNumber, CenterNumber: AnsiString; TimeStamp: TDateTime; TimeZone, Status, Index: Integer);
  end;

function SMSReceive(dbMain: TFDConnection): Boolean;
var
  cSMS: TGSMObj;
begin
  cSMS := TGSMObj.Create(nil);
  cSMS.OnReadMessage := dbMain.ReadMessage;
  cSMS.ReadSms;
end;
    
procedure TFDConnectionHelper.ReadMessage(Sender: TObject; MessageText: WideString; PhoneNumber, CenterNumber: AnsiString; TimeStamp: TDateTime; TimeZone, Status, Index: Integer);
begin
  Self.ExecSQL('INSERT INTO ...');
end;
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/62996352

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档