与许多其他Firemonkey开发人员一样,我需要一个通用的多平台解决方案来将消息从线程发送到主线程(以替换PostMessage)。我需要它也适用于iOS。
FrançoisPiette有一个针对Android和Windows实现的解决方案,但不适用于iOS: TMessagingSystem
但是,我认为通过将“new”TMessageManager与TThread.Queue()结合使用可以更加简单。但是没有人使用这种方法发布实际有效的代码(例如this one is not complete)。
您是否有想要与社区分享的经过测试的实施(或者只是建议如何正确实施)?
答案 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;