1

Delphi XE でIPreviewHandlerインターフェイスを使用して、Adobe PDF ファイルのリストを表示しています。最初のビューが閉じられたとき (インターフェイスが破棄されているとき) に約 20 秒の長い遅延があることを除いて、すべてが機能します。もちろん、アプリケーションを再起動するまで、後続のすべてのビューはそのような遅延なしに正常に進行します。

そのような奇妙な行動を経験した人はいますか?その理由は何ですか?

問題は、別のマシン上の別の開発者で再現可能です。OSはWindows 7 Ultimate、Adobe Reader XIはv11.0.3です。

CLSID='{DC6EFB56-9CFA-464D-8880-44885D7DC193}'. コードスニペット:

TqdPreviewControl = class(TCustomControl)
  private
    FResult   : HRESULT;
    FFileName : string;
    FLastError: string;
    FComPreviewHandler : IPreviewHandler;
    function IsOk(Ret : HRESULT) : boolean;
    function UpdatePreviewSize :boolean;
    class function GetCLSIDForFileName(AFileName: string): string; static;
    function PreviewFile :boolean;
    procedure SetFileName(const Value: string);
  protected
    procedure Resize; override;
  public
    constructor Create(AOwner :TComponent); override;
    destructor Destroy; override;
    property FileName: string read FFileName write SetFileName;
    property LastError: string read FLastError;
  end;

destructor TqdPreviewControl.Destroy;
begin
  if FComPreviewHandler <> nil then
    FComPreviewHandler.Unload;   // this helps to reduce first delay to 5 sec
  FComPreviewHandler := nil;     //! only on first destroy spends here 20 sec
  inherited Destroy;
end;

function TqdPreviewControl.PreviewFile :boolean;
var
  ACLSID: string;
  AGUID: TGUID;
  AInit: IInitializeWithStream;
  AFile: PWideChar;
  StreamAdapter : IStream;
  Stream : TMemoryStream;
  Size : TRect;
begin
  Result := false;
  FLastError := '';
  ACLSID := GetCLSIDForFileName(FFileName);
  if (ACLSID = '') then begin
    FLastError := 'No CLSID';
    Exit;
  end;

  AGUID := StringToGUID(ACLSID);
  FComPreviewHandler := CreateComObject(AGUID) as IPreviewHandler;
  if (FComPreviewHandler = nil) then
  begin
    FLastError := 'No Handler';
    Exit;
  end;

  AInit := FComPreviewHandler as IInitializeWithStream;
  Stream := TMemoryStream.Create;
  Stream.LoadFromFile(FFileName);
  StreamAdapter := TStreamAdapter.Create(Stream, soOwned);
  FResult := AInit.Initialize(StreamAdapter as IStream, STGM_READ);
  StreamAdapter := nil;

  Size := Rect(0, 0, Width, Height);
  if not IsOk(FComPreviewHandler.SetWindow(Handle, Size)) then
    Exit;
  if not UpdatePreviewSize then
    Exit;

  if IsOk(FComPreviewHandler.DoPreview) then
    Result := true;
end;

更新: 便利な方法が見つかりました - アンロード、これにより遅延が 20 秒から 5 秒に短縮されます。

更新: さらにマッサージすると、Application.ProcessMessages がデストラクタに配置されます。これにより、所有しているフォームを遅延なく閉じることができますが、遅延は親フォームに転送され、5 秒間フリーズします。半分更新された状態で閉じたビューを見る必要があるよりも、視覚的にはまだわずかに優れています.

更新: Foxit プレビュー ハンドラーを使用すると、実際に遅延が Adob​​e のアーティファクトであり、Delphi コードとはまったく関係がないことが確認されました

4

0 に答える 0