使用TMessageManager和TThread.Queue处理Firemonkey消息

时间:2014-10-03 09:31:07

标签: delphi firemonkey delphi-xe6

与许多其他Firemonkey开发人员一样,我需要一个通用的多平台解决方案来将消息从线程发送到主线程(以替换PostMessage)。我需要它也适用于iOS。

FrançoisPiette有一个针对Android和Windows实现的解决方案,但不适用于iOS: TMessagingSystem

但是,我认为通过将“new”TMessageManager与TThread.Queue()结合使用可以更加简单。但是没有人使用这种方法发布实际有效的代码(例如this one is not complete)。

您是否有想要与社区分享的经过测试的实施(或者只是建议如何正确实施)?

1 个答案:

答案 0 :(得分:0)

好的,这是我的实施。我没有使用TMessagingSystem,因为它似乎只是增加了复杂性(至少对我的情况而言)。它到目前为止有效,但如果有人提出改进建议,我将很乐意改进它。

我通过Uwe Raabe查看了解决方案,但我希望在我转换为FMX的大型代码库中使其更简单易行。 使用下面的解决方案,我可以简单地用gMessageHandler.PostMessage替换所有PostMessage()(删除win handle参数),并将表单中的消息函数添加到tMainForm.MessageCallBack。

我创建了一个小单元,我可以在任何需要PostMessage功能的地方包含它。那些地方不需要知道形式:

unit MessageHandler
interface
tAllOSMessage = procedure(aMessageID, aData1, aData2: integer) of object;
tAllOSMessageHandler = class
private
  fOnMessage : tAllOSMessage;
public
  constructor Create(aMessageCallBack: tAllOSMessage);
  procedure PostMessage(aMessageID, aData1, aData2: integer; aSourceThread: TThread = nil);
end;

var
  gMessageHandler: tAllOSMessageHandler;

implementation

constructor tAllOSMessageHandler.Create(aMessageCallBack: tAllOSMessage);
begin
  fOnMessage := aMessageCallBack;
end;

procedure tAllOSMessageHandler.PostMessage(aMessageID, aData1, aData2: integer; aSourceThread: TThread);
begin
  if aSourceThread=nil then
    aSourceThread := TThread.CurrentThread;
  aSourceThread.Queue(nil, procedure
                           begin
                             if Assigned(fOnMessage) then
                               fOnMessage(aMessageID, aData1, aData2);
                           end  );
end;
end.

然后我将这些行添加到主表单单元:

//Added to main form:
tMainForm = class(TForm)
...
procedure MessageCallBack(aMessageID, aData1, aData2: integer);

//Added to MainFormCreate
gMessageHandler := tAllOSMessageHandler.Create(MessageCallBack);

//Added to MainFormDestroy
FreeAndNil(gMessageHandler)

procedure tMainForm.MessageCallBack(aMessageID, aData1, aData2: integer);
begin
  case aMessageID of
    MyMessage1 :  MyFunction1(aData1,aData2);
    ...
  end;
end;