1

サーバー クライアント コンポーネントを使用し、このコンポーネントの TransferFile イベントでファイルが受信されたときに、アラート メッセージ コンポーネントを使用します。したがって、ユーザーが警告メッセージをクリックした場合、ボタンがクリックされた場合は TransferFile イベントでコードを実行し続け、ボタンがクリックされた場合はファイル転送を受け入れるか、そうでない場合は手順を終了するプログラムが必要です。次のコードを参照してください。

procedure TfrmReadFile.ServerReceiveEvent(Sender: TObject;
  Client: TSimpleTCPClient; Event: TTOOCSEvent);
begin
  if (Event is TTOOCSEventFileTransfert) then
  begin
    Alert.Show;
      if Alert.OnAlertClick then
      begin
        with (Event as TTOOCSEventFileTransfert) do
        if (dlgSaveFile.Execute) then
          with TMemoryStream.Create do
            try
              Write(Content[1], Length(Content));
              SaveToFile(dlgSaveFile.FileName);
            finally
              Free;
            end;
      end;
  end;
end;

しかし、「if Alert.OnAlertClick then」は間違っています

procedure TfrmReadFile.AlertAlertClick(Sender: TObject);
begin

end;

これらのコードについて私を助けてください。

AlertMessage は TMS コンポーネントの 1 つで、ShowModal はありませんが、私が使用する Alert.Show プロシージャがあります。アラートの表示時間が終了するまで実行中のコードを一時停止したいのですが、ユーザーがアラートの実行をクリックしないと、コードは中止され、ファイルは保存されません。

4

1 に答える 1

3

あなたのコードから、アラートを表示するまでに、ファイル転送がすでに発生していることは明らかです。「ファイルに保存しますか」または「既に受信したコンテンツを破棄しますか」だけの問題です。私はあなたの使用からこの情報を推測していますTMemoryStream.Write()-その関数はパラメーターとしてバッファーを取るので、Content[1]があなたにバッファーを与えると思います。これは、Content必要なデータがすでに読み込まれていることも意味します。転送しないには遅すぎます。既にメモリ内にあります。できることは、ディスクに保存するか、破棄することだけです。

また、TMS の Alert がどのように機能するかはわかりませんが、一度に表示できる Alert は 1 つだけでAlertあり、コンポーネントにドロップしたと仮定します (つまり、アラートは 1 つだけです)。プログラム全体)。

最初に「受信イベント」のコードを変更して、コンテンツをすぐにTMemoryStream. また、再帰的な再入で問題が発生しないようにしてください。フォームにプライベート フィールドを追加し、それを呼び出しますFLastContentReceived: TMemoryStream。コードを次のように変更します。

procedure TfrmReadFile.ServerReceiveEvent(Sender: TObject;
  Client: TSimpleTCPClient; Event: TTOOCSEvent);
begin
  if (Event is TTOOCSEventFileTransfert) then
  begin
    // Re-entry before we managed to handle the previous received file?
    if Assigned(FLastContentReceived) then
      raise Exception.Create('Recursive re-entry not supported.');

    // No re-entry, let's save the content we received so we can save it to file
    // if the user clicks the Alert button.
    FLastContentReceived := TMemoryStream.Create;

    // I don't know what Content is, but you've got that in your code so I
    // assume this will work:
    FLastContentReceived.Write(Content[1], Length(Content); 

    // Show the alert; If the OnAlertClick event fires we'll have the received file content
    // in the FLastContentRecevied and we'll use that to save the file.
    Alert.Show;
  end;
end;

if on を実行しようとしているので、コンポーネントに と呼ばれるAlert.OnAlertClickイベントがあると思います。これをイベント ハンドラに記述します。AlertOnAlertClick

procedure TfrmReadFile.AlertAlertClick(Sender: TObject);
begin
  if not Assigned(FLastContentReceived) then raise Exception.Create('Bug');
  try
    if dlgSaveFile.Execute then
      FLastContentReceived.SaveToFile(dlgSaveFile.FileName);
  finally FreeAndNil(FLastContentReceived);
  end;
end;

FLastContentReceivedまた、[アラート] ボタンがクリックされる前にフォームが閉じられた場合、またはタイムアウトが発生した場合 (ユーザーがクリックせずにアラートが消える)を破棄する方法も必要です。フォームが閉じられたときの最初の仕事 (FLastContentReceived を取り除く) は単純です: これをフォームの に追加しますOnDestroy:

FLastContentRecevid;Free;

タイムアウトの処理は少し難しいかもしれません。Alertアラートがタイムアウトし、バルーンがクリックされずに消えたときに呼び出されるイベントが にある場合は、そのイベント ハンドラを使用してこれを行います。

FreeAndNil(FLastContentRecevid);

TTimerアラートのタイムアウトに等しい間隔(または安全のために少し長く)を設定できるようなものが提供されない場合は、アラートを表示する前に有効にし、次のようにしOnTimerます。

procedure TFrmReadFile.Timer1Timer(Sender: TObject);
begin
  Timer1.Enabled := False;
  FreeAndNil(FLastContentRecevid);
end;
于 2013-01-15T10:30:30.870 に答える