2013-01-15 45 views
1

我使用服務器客戶端組件,並且當在此組件的TransferFile事件中接收到文件時,我使用警報消息組件。所以我想,如果用戶點擊警報消息,程序繼續在TransferFile事件中執行代碼,以便在單擊按鈕時接受文件傳輸,或者在沒有按鈕時退出該過程。 請參見下文代碼:知道Onclick導致的事件

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

你需要告訴我們這個報警組件是什麼。對話框顯示時是否要繼續執行TCP代碼?對話框模式?這個問題仍然很難理解。您必須對其進行編輯以使其更清晰。 –

+1

Alert.ShowModal;如果Alert.Modalresult = mrOk,那麼...將會是你的意圖,但ReceiveEvent會隨時發生。之前設置的標誌將是更好的解決方案。 – bummi

+0

你需要一個狀態機來實現你的程序邏輯。你使用的組件的事件應該調用一個方法來改變狀態機的狀態,所有的實際工作都應該作爲狀態機方法來實現。 – kludg

回答

3

從你的代碼很明顯,到時候你到顯示警報,文件傳輸已經發生:這只是問題「難道我保存到文件」「難道我丟棄內容我已經收到「。我從你使用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; 
+0

親愛的科斯明,我不會檢查我想要的內容,如果用戶點擊alertmessage文件傳輸完成否則拒絕傳輸文件。 – Poorhoseini

+1

我不完全明白你在說什麼,但我想它圍繞「拒絕轉移文件」。那麼,看看你的代碼:當你的ServerReceiveEvent事件被調用時,你已經*已經*接收到該文件了:你的內容已經在本地可用。你不能接收它,你只能將它保存到文件或放棄它。 –

+1

我編輯了答案,以澄清爲什麼我假定文件傳輸已經發生在你的'ServerReceiveEvent'被調用的時候。如果拒絕拒絕它,你所能做的就是丟棄它。 –