IdHttpServer表单标题未更新

时间:2012-03-20 09:34:04

标签: delphi indy

我知道我之前发过一个类似的问题,但我无法让它工作我有这个简单的代码:

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;
 frmMain.caption := S;
 Memo1.Lines.Add(S);
end;

备忘录中的字符串显示正常,但标题未更新

2 个答案:

答案 0 :(得分:3)

TIdHTTPServer是一个多线程组件。 TIdContext在自己的工作线程中运行。您无法从主线程外部安全地更新表单的Caption(或使用UI执行任何其他操作)。您需要与主线程同步,例如与TIdSyncTIdNotify类同步。

另外,在循环中调用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; 

答案 1 :(得分: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上的第一行不是空行,因为表单的标题不会显示包含换行符的字符串。