知道Onclick事件被解雇了

时间:2013-01-15 07:26:11

标签: delphi events onclick

我使用服务器客户端组件,当在此组件的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;

但“如果Alert.OnAlertClick那么”是错误的

procedure TfrmReadFile.AlertAlertClick(Sender: TObject);
begin

end;

请帮我解决这些问题。

AlertMessage是TMS组件之一,它没有ShowModal,但它有我使用的Alert.Show程序。我想暂停正在执行的代码,直到警报显示时间结束,如果用户没有点击警报执行代码中止并且没有保存文件。

1 个答案:

答案 0 :(得分:3)

从您的代码中可以明显看出,当您显示警报时,文件传输已经发生:这只是“我保存到文件”的问题“我是否丢弃了我已收到的内容”。我在使用TMemoryStream.Write()时推断这个信息 - 该函数将缓冲区作为参数,因此我假设Content[1]给出了缓冲区。这也意味着Content已经填充了您需要的数据。为了不转移它太晚了,它已经在内存中,你所能做的只是将它保存到磁盘或丢弃它。

我也不知道TMS的警报是如何工作的,但是我假设在任何给定的时间都只能显示一个警报,我会假设你将Alert放在一个组件上(即:整个计划中只有一个警报。)

您应首先更改“已接收事件”的代码,以立即将内容移至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;

您正尝试在Alert.OnAlertClick上执行if - 所以我假设您的Alert组件中有一个名为OnAlertClick的事件。把它写在它的事件处理程序中:

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)是simle:将其添加到表单的OnDestroy

FLastContentRecevid;Free;

处理超时可能会有点困难。如果Alert有一个事件在警报超时且气球消失而没有被点击时被调用,那么使用该事件处理程序来执行此操作:

FreeAndNil(FLastContentRecevid);

如果它没有提供这样的东西,你可以设置一个TTimer的间隔等于警报的超时(或者稍微长一些是安全的),在显示警报之前启用它并从它{{ {1}}:

OnTimer