2012-03-20 3 views
1

を更新しません更新されませんIdHttpServerフォームのキャプションは、私は私が前に同様の質問を掲載している知っているが、私はそれは私がこの単純なコードを持って取り組んで取得することはできないのです

+1

IIRC IdHTTPServerのは、読み取り/書き込みので、何が必要か、サーバーによって作成されたスレッド内の要求/応答を処理するTIdContextのサブクラスを作成することであり、それから、あなたが行うことができ、コンテキスト内で場所を取る必要がありますあなたがする必要があるものは、私が少し前に書いた小さなデモです。http://www.delphigeist.com/2010/12/dynamic-web-pages-with-dwscript-and.html – ComputerSaysNo

答えて

3

TIdHTTPServerはマルチスレッドコンポーネントです。 TIdContextは、それ自身のワーカースレッドで実行されます。フォームのCaptionを安全に更新することはできません(またはUIで他の操作を行う)ことは、メインスレッドの外部から行うことはできません。 TIdSyncまたはTIdNotifyクラスなど、メインスレッドと同期する必要があります。

ループでReadChar()を呼び出すのは非常に効率が悪く、代理ペアのデータを返すことができないため、Delphi 2009+を使用している場合はエラーが発生しやすくなります。

代わりにこのようなものを使用してください。

type 
    TDataNotify = class(TIdNotify) 
    protected 
    Data: String; 
    procedure DoNotify; override; 
    public 
    constructor Create(const S: String); 
    class procedure DataAvailable(const S: String); 
    end; 

constructor TDataNotify.Create(const S: String); 
begin 
    inherited Create; 
    Data := S; 
end; 

procedure TDataNotify.DoNotify; 
begin 
    frmMain.Caption := Data; 
    frmMain.Memo1.Lines.Add(Data); 
end; 

class procedure TDataNotify.DataAvailable(const S: String); 
begin 
    Create(S).Notify; 
end; 

procedure TfrmMain.srvrConnect(AContext: TIdContext); //idhttpserver on connect event 
var 
    S: String; 
begin 
    AContext.Connection.IOHandler.CheckForDataOnSource(IdTimeoutDefault); 
    if not AContext.Connection.IOHandler.InputBufferIsEmpty then 
    begin 
    S := AContext.Connection.IOHandler.InputBufferAsString; 
    TDataNotify.DataAvailable(S); 
    end; 
end; 
+0

wierdしかし、私はAContext.Connection.IOHandler.InputBufferAsStringで何も受け取りません。私が書いたものを使用すれば、それはうまく動作します...何故なのでしょう? – opc0de

+0

'InputBufferAsString'は、現在' InputBuffer'にあるものをすべて取り出し、それを 'String'に変換します。 D2009 +では、バイトをUnicodeにデコードする必要があります。バイトに不完全な文字列が含まれているなど、そのデコードが失敗した場合、空の 'String'が返される可能性があります。内部的には、デコーディングはEmbarcaderoの 'TEncoding'クラスに基づいており、これらのクラスはデコードエラーで例外を発生させません。だから本当の疑問は、あなたが最初に受けようとしているデータの種類と、一度に1文字ずつ読もうとした理由です。 –

+0

私はgpsからデータを受信して​​いますので、文字列はasciiのようにエンコードされていません – opc0de

1

まず、正しい変数に書き込んでいることを確認してください。 frmMainはキャプションを変更するフォームですか?

また、あなたが試みることができる:

procedure TfrmMain.srvrConnect(AContext: TIdContext); //idhttpserver on connect event 
var 
    S,C : String; 
begin 
repeat 
    s := s + AContext.Connection.Socket.ReadChar; 
until AContext.Connection.Socket.InputBufferIsEmpty = True; 
oCaption := S; 
TThread.Synchronize(nil, Self.ChangeCaption); 
end; 

procedure TfrmMain.ChangeCaption; 
begin 
Self.Caption := oCaption; 
Memo1.Lines.Add(oCaption); 
end; 

そして最後に、フォームのキャプションは、改行が含まれている文字列が表示されませんのでS上の最初の行は、空白行でないことを確認してください。

+0

UIを安全に更新することはできません(TIdContext'が実行される)ワーカースレッド、および 'Application.ProcessMessages()'はワーカースレッドから呼び出されたときにメインUIを更新しません。 –

+0

@RemyLebeau、そうです。私はそれを変更するつもりです。 –

+0

'TForm'は' Synchronize() 'メソッドを持たず、' ChangeCaption() 'は' TfrmMain'クラスのメンバではありません。私はあなたの答えを更新しました。 –

関連する問題