從你的代碼很明顯,到時候你到顯示警報,文件傳輸已經發生:這只是問題「難道我保存到文件」或「難道我丟棄內容我已經收到「。我從你使用TMemoryStream.Write()
推斷這個信息 - 該函數將緩衝區作爲參數,所以我假設Content[1]
給你的緩衝區。這也意味着Content
已準備好您所需的數據。爲了不傳輸它,它已經在內存中,你只能將它保存到磁盤或丟棄它。
我也不知道TMS的警報是如何工作的,但我會假設在任何給定的時間只有一個警報可以顯示,並且我會假設你丟棄了你的Alert
一個組件(即:有整個程序中只有一個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
- 所以我想有一個在你的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的),當窗體被關閉的笑着:添加到您的窗體的OnDestroy
:
FLastContentRecevid;Free;
處理超時可能有點難度。如果Alert
有這就是所謂的事件時,警報超時,氣球消失,而不被點擊然後使用該事件處理程序來做到這一點:
FreeAndNil(FLastContentRecevid);
如果它提供你可以建立一個TTimer
爲沒有這樣的事情等於警報的超時時間間隔(或稍長是安全的),顯示警報之前啓用它,並做到這一點從它的OnTimer
:
procedure TFrmReadFile.Timer1Timer(Sender: TObject);
begin
Timer1.Enabled := False;
FreeAndNil(FLastContentRecevid);
end;
你需要告訴我們這個報警組件是什麼。對話框顯示時是否要繼續執行TCP代碼?對話框模式?這個問題仍然很難理解。您必須對其進行編輯以使其更清晰。 –
Alert.ShowModal;如果Alert.Modalresult = mrOk,那麼...將會是你的意圖,但ReceiveEvent會隨時發生。之前設置的標誌將是更好的解決方案。 – bummi
你需要一個狀態機來實現你的程序邏輯。你使用的組件的事件應該調用一個方法來改變狀態機的狀態,所有的實際工作都應該作爲狀態機方法來實現。 – kludg