IDownloadManager
メソッドを使用してインターフェイスをWeb ブラウザー コントロールに実装するとDownload
、必要なものを簡単に制御できます。このDownload
メソッドは、ファイルをダウンロードするときはいつでも呼び出されます (名前を付けて保存ダイアログがポップアップする場合のみ)。
1. 組み込み Web ブラウザ
Embedded Web Browser
このインターフェイスがすでに実装されていてOnFileDownload
、 の同じ名前のイベントとは異なるを起動するコントロールを使用できますTWebBrowser
。たとえばthis thread
、それを使用する方法を参照してください。
2.自分でやる
別のオプションは、自分で実装できることですTWebBrowser
。次の例では、原則を示すためだけに挿入クラスを使用しましたが、コンポーネントとしてラップするのは非常に簡単です (これが、OnBeforeFileDownload
公開した理由です)。
2.1. OnBeforeFileDownload イベント
TWebBrowser
この挿入されたクラスの唯一の拡張機能はOnBeforeFileDownload
、ファイルがダウンロードされるときに発生するイベントです ([名前を付けて保存] ダイアログがポップアップする前ですがOnFileDownload
、ドキュメント自体がダウンロードされたときではなく、イベントの代わりに発生します)。イベント ハンドラーを記述しない場合、Web ブラウザー コントロールは以前と同じように動作します (名前を付けて保存ダイアログを表示します)。イベント ハンドラを記述し、Allowed
宣言されたパラメータに False を返すと、ファイルの保存がキャンセルされます。パラメータに True を返すとAllowed
(既定値)、名前を付けて保存ダイアログが表示されます。Allowed
False に設定してダウンロードをキャンセルした場合は、自分でファイルをダウンロードする必要があることに注意してください (この例では Indy を使用して同期的に行ったように)。この目的のために、FileSource
ダウンロードしたファイルの URL を含む定数パラメーター。イベント パラメータの概要は次のとおりです。
- Sender (TObject) - イベントの送信者
- FileSource (WideString) - ソース ファイルの URL
- Allowed (ブール値) - ファイルのダウンロードを許可するかどうかを決定する、宣言されたブール値パラメーター (デフォルト値は True)
2.2. IDownloadManager の実装
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
StdCtrls, OleServer, OleCtrls, Dialogs, ActiveX, MSHTML, UrlMon, SHDocVw,
IdHTTP;
const
IID_IDownloadManager: TGUID = '{988934A4-064B-11D3-BB80-00104B35E7F9}';
SID_SDownloadManager: TGUID = '{988934A4-064B-11D3-BB80-00104B35E7F9}';
type
IDownloadManager = interface(IUnknown)
['{988934A4-064B-11D3-BB80-00104B35E7F9}']
function Download(pmk: IMoniker; pbc: IBindCtx; dwBindVerb: DWORD;
grfBINDF: DWORD; pBindInfo: PBindInfo; pszHeaders: PWideChar;
pszRedir: PWideChar; uiCP: UINT): HRESULT; stdcall;
end;
TBeforeFileDownloadEvent = procedure(Sender: TObject; const FileSource: WideString;
var Allowed: Boolean) of object;
TWebBrowser = class(SHDocVw.TWebBrowser, IServiceProvider, IDownloadManager)
private
FFileSource: WideString;
FOnBeforeFileDownload: TBeforeFileDownloadEvent;
function QueryService(const rsid, iid: TGUID; out Obj): HRESULT; stdcall;
function Download(pmk: IMoniker; pbc: IBindCtx; dwBindVerb: DWORD;
grfBINDF: DWORD; pBindInfo: PBindInfo; pszHeaders: PWideChar;
pszRedir: PWideChar; uiCP: UINT): HRESULT; stdcall;
protected
procedure InvokeEvent(ADispID: TDispID; var AParams: TDispParams); override;
published
property OnBeforeFileDownload: TBeforeFileDownloadEvent read FOnBeforeFileDownload write FOnBeforeFileDownload;
end;
type
TForm1 = class(TForm)
Button1: TButton;
WebBrowser1: TWebBrowser;
FileSourceLabel: TLabel;
FileSourceEdit: TEdit;
ShowDialogCheckBox: TCheckBox;
procedure Button1Click(Sender: TObject);
procedure FormCreate(Sender: TObject);
private
procedure BeforeFileDownload(Sender: TObject; const FileSource: WideString;
var Allowed: Boolean);
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
{ TWebBrowser }
function TWebBrowser.Download(pmk: IMoniker; pbc: IBindCtx; dwBindVerb,
grfBINDF: DWORD; pBindInfo: PBindInfo; pszHeaders, pszRedir: PWideChar;
uiCP: UINT): HRESULT;
var
Allowed: Boolean;
begin
Result := E_NOTIMPL;
if Assigned(FOnBeforeFileDownload) then
begin
Allowed := True;
if pszRedir <> '' then
FFileSource := pszRedir;
FOnBeforeFileDownload(Self, FFileSource, Allowed);
if not Allowed then
Result := S_OK;
end;
end;
procedure TWebBrowser.InvokeEvent(ADispID: TDispID; var AParams: TDispParams);
begin
inherited;
// DispID 250 is the BeforeNavigate2 dispinterface and to the FFileSource here
// is stored the URL parameter (for cases, when the IDownloadManager::Download
// won't redirect the URL and pass empty string to the pszRedir)
if ADispID = 250 then
FFileSource := OleVariant(AParams.rgvarg^[5]);
end;
function TWebBrowser.QueryService(const rsid, iid: TGUID; out Obj): HRESULT;
begin
Result := E_NOINTERFACE;
Pointer(Obj) := nil;
if Assigned(FOnBeforeFileDownload) and IsEqualCLSID(rsid, SID_SDownloadManager) and
IsEqualIID(iid, IID_IDownloadManager) then
begin
if Succeeded(QueryInterface(IID_IDownloadManager, Obj)) and
Assigned(Pointer(Obj))
then
Result := S_OK;
end;
end;
{ TForm1 }
procedure TForm1.Button1Click(Sender: TObject);
var
HTMLWindow: IHTMLWindow2;
HTMLDocument: IHTMLDocument2;
begin
WebBrowser1.Navigate('http://financials.morningstar.com/income-statement/is.html?t=AAPL&ops=clear');
while WebBrowser1.ReadyState <> READYSTATE_COMPLETE do
Application.ProcessMessages;
HTMLDocument := WebBrowser1.Document as IHTMLDocument2;
if not Assigned(HTMLDocument) then
Exit;
HTMLWindow := HTMLDocument.parentWindow;
if Assigned(HTMLWindow) then
try
HTMLWindow.execScript('SRT_stocFund.Export()', 'JavaScript');
except
on E: Exception do
ShowMessage(E.Message);
end;
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
ReportMemoryLeaksOnShutdown := True;
WebBrowser1.OnBeforeFileDownload := BeforeFileDownload;
end;
procedure TForm1.BeforeFileDownload(Sender: TObject; const FileSource: WideString;
var Allowed: Boolean);
var
IdHTTP: TIdHTTP;
FileTarget: string;
FileStream: TMemoryStream;
begin
FileSourceEdit.Text := FileSource;
Allowed := ShowDialogCheckBox.Checked;
if not Allowed then
try
IdHTTP := TIdHTTP.Create(nil);
try
FileStream := TMemoryStream.Create;
try
IdHTTP.HandleRedirects := True;
IdHTTP.Get(FileSource, FileStream);
FileTarget := IdHTTP.URL.Document;
if FileTarget = '' then
FileTarget := 'File';
FileTarget := ExtractFilePath(ParamStr(0)) + FileTarget;
FileStream.SaveToFile(FileTarget);
finally
FileStream.Free;
end;
finally
IdHTTP.Free;
end;
ShowMessage('Downloading finished! File has been saved as:' + sLineBreak +
FileTarget);
except
on E: Exception do
ShowMessage(E.Message);
end;
end;
end.
2.3. IDownloadManager プロジェクト
上記のコード (Delphi 2009 で記述) は、完全なプロジェクトとしてダウンロードできますfrom here
。