簡體   English   中英

Delphi系統錯誤代碼5訪問被拒絕

[英]Delphi system error code 5 access denied

我創建了一個線程,當Preview=false時工作良好,但是當我設置Preview=true我總是收到錯誤消息(系統錯誤代碼5訪問被拒絕)。

我想對報告進行處理,因為生成報告需要10秒鍾以上。

有人可以解釋發生了什么嗎?

procedure TReportThread1.Execute;
begin       
    if ReportBUFFER = 1 then begin
        dm.rmvFarm.Filename := reportpath + 'aoc.rep';
        dm.rmvFarm.Report.Params.Items[0].Value := Thread_StartOfTheDayR1;
        dm.rmvFarm.Report.Params.Items[1].Value := Thread_EndOfTheDayR1;
        dm.rmvFarm.Report.Params.Items[2].Value := currentusr;
        dm.rmvFarm.Preview := true;
        dm.rmvFarm.Execute;

        ReportThread1.free;
    end;                                                 
end.

如果查看TVCLReport的源代碼, TVCLReportPreview=True時,其Execute()方法將顯示基於VCL的UI:

type
  TVCLReport=class(TCBaseReport)
  private
    prcontrol:TRpPreviewControl;
    ...
  end;

function TVCLReport.Execute:boolean;
var
 ...
begin
 inherited Execute;
 ...
 try
 if Preview then
 begin
  prcontrol:=TRpPreviewControl.Create(nil);
  try
   prcontrol.Report:=Report;
   Result:=ShowPreview(prcontrol,Title);
  finally
   prcontrol.free;
  end;
 end
 else
 begin
  ...
end;

TRpPreviewControl派生自TScrollBox ShowPreview()是一個輔助函數, TRpPreviewControl對象放置在與ShowModal()一起顯示的自定義TForm對象( TFRpPreview )上。 基於VCL的用戶界面不是線程安全的,因此不能在主用戶界面線程的上下文之外使用。 如您所見, TVCLReport.Execute()不會為您提供任何與主UI線程同步的機會,因此Preview=True在工作線程中使用並不安全。

如果要在工作線程中調用TVCLReport.Execute() ,但以線程安全的方式顯示其預覽,則一種可能的解決方案是更改TVCLReport的源代碼,以允許您使用的方式公開預覽功能。使用TThread.Synchronize()調用它,例如:

type
  TVCLReportPreviewEvent = procedure(Sender: TObject; var VResult: Boolean) of object;

  TVCLReport=class(TCBaseReport)
  private
    prcontrol:TRpPreviewControl;
    ...
  public
    OnPreview: TVCLReportPreviewEvent;
    function DisplayPreview: Boolean;
  end;

function TVCLReport.Execute:boolean;
var
 ...
begin
  inherited Execute;
  ...
  try
  if Preview then
  begin
    if Assigned(OnPreview) then
      OnPreview(Self, Result)
    else
      Result := DisplayPreview;
  end
  else
  begin
    ...
end;

function TVCLReport.DisplayPreview: Boolean;
begin
  prcontrol:=TRpPreviewControl.Create(nil);
  try
    prcontrol.Report:=Report;
    Result := ShowPreview(prcontrol, Title);
  finally
    prcontrol.free;
  end;
end;

procedure TReportThread1.Execute;
begin       
  if ReportBUFFER = 1 then begin
    dm.rmvFarm.Filename := reportpath + 'aoc.rep';
    dm.rmvFarm.Report.Params.Items[0].Value := Thread_StartOfTheDayR1;
    dm.rmvFarm.Report.Params.Items[1].Value := Thread_EndOfTheDayR1;
    dm.rmvFarm.Report.Params.Items[2].Value := currentusr;
    dm.rmvFarm.Preview := true;
    dm.rmvFarm.OnPreview := DisplayPreviewInMainThread;
    dm.rmvFarm.Execute;
    ReportThread1.free;
  end;                                                 
end;

procedure TReportThread1.DisplayPreviewInMainThread(Sender: TObject; var VResult: Boolean);
begin
  TThread.Synchronize(nil,
    procedure
    begin
      VResult := dm.rmvFarm.DisplayPreview;
    end
  );
end;

雖然,如果您的報告確實需要很長時間才能生成,那么預覽也可能會花費很長時間。 如果是這樣,此解決方案將不會為您帶來任何幫助。 TVCLReport在主UI線程中,並在忙於生成報告時向用戶顯示一條消息可能會更容易。

您只需要嘗試一下,看看會發生什么。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM