いつもお世話になります。
表題の通りなのですが、IEを非表示で起動できず悩んでいます。
環境は、Delphi XE4, IE Ver.10, Windows7 です。
そのときのコードです。
ShellExecute(Handle, 'open', PChar('IEXPLORE.EXE'), PChar(URL), nil, SW_HIDE);
メモ帳の notepad.exe だと非表示で起動できたのですが・・・。
どうして出来ないのでしょうか?
同じ環境がないのと、こちらでは再現しなかったので、参考程度で。
…と、その前に。「IEを非表示で起動」というのは、タスクバーにも表示されない状態ですよね。
なぜそのような動作を必要としているのですか?気になります。
回答にはなってませんが、違うアプローチを。
COMのIEオブジェクトを使って、ゆるーくコントロールするのはどうでしょうか。
動かなかったらゴメンナサイ。
uses
ComObj;
function WaitIEBusy(IE: OleVariant; Wait: Cardinal): Boolean;
var
ST: DWORD;
begin
Result:=False;
ST:=GetTickCount();
repeat
Sleep(100);
if not IE.Busy then Exit;
until GetTickCount()-ST>Wait*1000;
Result:=True;
end;
procedure QuitIE(var IE: OleVariant);
begin
if VarIsEmpty(IE) then Exit;
try
IE.Quit;
except
on EOleSysError do; // 多分ユーザーによってIEが閉じられてると判断してスルー
end;
IE:=Unassigned;
end;
var
MyIE: OleVariant;
procedure TForm1.Button1Click(Sender: TObject);
begin
if not VarIsEmpty(MyIE) then Exit;
MyIE:=CreateOleObject('InternetExplorer.Application');
// MyIE.Width:=600;
// MyIE.Height:=400;
// MyIE.Toolbar:=False;
// MyIE.StatusBar:=False;
MyIE.Visible:=True; // Falseで非表示
MyIE.Navigate('http://www.google.co.jp/');
if WaitIEBusy(MyIE, 10) then QuitIE(MyIE); // ナビゲート待ち、10秒でタイムアウト終了
end;
procedure TForm1.Button2Click(Sender: TObject);
begin
QuitIE(MyIE);
end;
procedure TForm1.FormDestroy(Sender: TObject);
begin
QuitIE(MyIE);
end;
win7,D6では非表示で起動しましたが・・・
では、こういうのはどうでしょうか?
H: HWND;
ShellExecute(Handle, 'open', PChar('IEXPLORE.EXE'), PChar(URL), nil, SW_HIDE);
H := FindWindow('IEFrame', nil);
if H <> 0 then ShowWindow(H, SW_HIDE);
Harry 様、deldel 様、回答して頂きありがとうございます。
お二方のやり方は初めてだったので勉強になりました。ありがとうございました。・・・ただ、今回は起動直後から非表示になってくれる方法を知りたかったのです・・・。
今更ですが目的は、現在、某サイトのHTMLページからデータを取得してデータベースに保存する、というものを作成していて、IEを操作して自動的に次のページに進むようにしているのですが、そのときIEが表示されるとちょっとカッコ悪いなと思ったので(IE のページが連続で切り替わるのが見えてしまう・・・)、このような質問をさせて頂きました。
一応ですが、あくまでローカルに表示させたHTML形式のデータを、ソースからそのままローカルのDBに保存するだけなので特に違法行為ではない、・・・と思っています。そのページも、ごく一般に公開しているものですし。それにデータベースとHTMLの勉強ついでに作成しているだけなので・・・。
ShellExecuteだと、確かに起動はできますが、特定のページへのナビゲートも
うまくできませんし、ナビゲート終了のタイミングを捉えることもできません。
今回のケースでは、Harryさんの提示された手法が適切だと思います。
ちなみに、提示されたコード例に倣うと、MyIE.Visible := Trueを入れない限りは、
望みの動作になるのではないかと思いますが、実際に試されましたか?
下記でも可?
uses
ComObj;
procedure TForm1.Button1Click(Sender: TObject);
var
IExp: Olevariant;
begin
IExp := CreateOleObject('InternetExplorer.Application');
IExp.Height := 800;
IExp.Width := 600;
IExp.top := 0;
IExp.Left := 0; // -800にすれば見えなくなります
IExp.Visible := true;
IExp.Navigate('http://news.livedoor.com/category/vender/80/');
end;
上記で、前にkamaさん希望の動作で株価を取得した記憶が...。
「どうしてもIEを使わなくてはいけない」というのではないなら
TWebBrowserを使うというのはいかがでしょう。
やろうと思えばIndyコンポでも何とかなるのではと思います。
面倒でしょうけど(^^;
>今回は起動直後から非表示になってくれる方法を知りたかったのです
うーん、コメントの書き方で誤解させちゃいましたかね?
あ さんがフォローしてくれてる通り MyIE.Visible:=True; を削除するか、明示的にFalseにすれば最初から非表示ですよ。
>HTMLページからデータを取得してデータベースに保存する、というものを作成していて、
>IEを操作して自動的に次のページに進むようにしているのですが、そのときIEが表示されると
これは逐次ShellExecuteすることで新しいページに移動させているということですか?
その後どのようにデータを取得しているのでしょうか。まさかキャッシュからソースを取得?
そのようなやり方なら、IEを使わずにUrlMonのURLDownloadToFileというAPI一発で出来てしまいます。
またWinInetには様々なAPIがあり、ファイルに落とさずにダウンロードすることも可能です。
で…、いくつかの案が出ましたが、私はTWebBrowserを非表示で使うことをおすすめします。
IEオブジェクトと違いOnQuitなどのイベントによる支援も受けられ(※1)、型チェックやコード補完も効きます(※2)。
何より、ソースの取得はもちろんのこと、DOM操作によって自在にHTML要素の内容を取得できます(※3)ので。
例:
・ ソースを取得 … VarToStr(Document.documentElement.outerHTML)
・ I番目のAタグリンクを取得 … VarToStr(Document.getElementsByTagName('a').item(I).href)
・ JavaScriptを実行 … Document.parentWindow.execScript('alert("Hello!")')
上記の方法は、JavaScriptやVBScriptのコードが工夫次第でほぼそのまま使えるという利点があります。
ただし、スクリプト的に操作をしているので、タイプミス等があっても実行されるまでエラーは出ません。
※1 →IEオブジェクトでもIEEventsという外部のコンポーネントで一応可能。
※2 →IEオブジェクトもSHDocVwのInternetExplorer(IWebBrowser2)でキャストして使えば可能。
※3 →もちろんIEオブジェクトでも可能ですが。
アドバイスを下さった皆様、ありがとうございます。
メールを確認できず返信が遅れてしまいました。
TWebBrowser を使用してIE非表示は実現できました。
3K 様のような単純に見えなくしてしまうという方法も気づきませんでした。
Visible = False にすれば読込み時間も短くなるのかと思いコーディングしてみましたが、私の環境だとなぜか Visible = False が効かず表示されっぱなしになってしまいます。なので、Hideプロパティ を使用して非表示にしました。
アドバイス頂きありがとうございました。
ツイート | ![]() |