2014-10-03 3 views
1

다른 많은 Firemonkey 개발자와 마찬가지로, 스레드에서 메인 스레드로 메시지를 보내려면 (PostMessage를 대체하기 위해) 일반적인 다중 플랫폼 솔루션이 필요합니다. iOS에서도 작동해야합니다.TMessageManager 및 TThread.Queue를 사용하는 Firemonkey 메시지 처리

Android 및 Windows 용으로 구현 된 François Piette의 해결책은 있지만 iOS 용은 없습니다. TMessagingSystem입니다.

그러나 TThread.Queue()와 함께 "새로운"TMessageManager를 사용하면 훨씬 간단해질 수 있다고 생각합니다. 그러나 아무도이 aproach를 사용하여 실제로 작동하는 코드를 게시하지 않았습니다 (예 : this one is not complete).

커뮤니티와 공유하고 싶은 테스트를 마친 구현이 있습니까 (아니면 구현 방법을 제안하는 것)?

+0

사용'TThread.Queue'와 클로저를. 둘 다 모든 플랫폼에서 작동합니다. http://www.uweraabe.de/Blog/2011/01/30/synchronize-and-queue-with-parameters/ –

+2

'TThread.Synchronize()'와'TThread.Queue()'가 * XE7 이전의 모든 FireMonkey 버전. 자세한 내용 및 해결 방법은 [QC# 123579] (http://qc.embarcadero.com/wc/qcmain.aspx?d=123579)를 참조하십시오. –

답변

0

여기 내 구현이 있습니다. TMessagingSystem을 사용하지 않았기 때문에 (적어도 제 상황에서는) 복잡성이 추가되는 것처럼 보입니다. 지금까지는 작동하지만 개선을위한 제안이있는 사람은 기꺼이 개선 할 것입니다.

나는 해결책을 Uwe Raabe으로 바라 보았으나 나는 FMX로 변환하는 큰 코드베이스에서 구현하기가 더 쉽고 간단하게 만들고 싶었다. 아래의 솔루션을 사용하면 모든 PostMessage()를 gMessageHandler.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; 
+1

왜 aSourceThread에 신경을 쓰시겠습니까? 단순히 TThread.Queue (nil, ...)를 사용하면 기본적으로 같은 것입니다. – ciuly

+0

@ciuly : 그렇다면 소스 코드가 훨씬 더 간단해질 수 있습니다 .- 왜 aSourceThread가 들어 왔는지 기억하지 못합니다. – Hans