InternetExplorerをCOMを使って操作する

簡易Webクライアントを作るプログラムを書いていたのですが、COMを使ってInternetExplorerを少し操作できるように なったので、ソースプログラムと私が調べたマニュアルや書籍について紹介しようと思います。内容に関しては Winsock同様とても説明できるほど理解しておりませんのでご了承ください。ただこの手の話は私が調べた限りでは ほとんどなかったので同じ事を考えている人には参考になると思っています。
老婆心ながら付け加えておきますと、スクリプトでもいいから操作したいと考えている人にはWSHを調べた 方がいいのでしょう。

それでは行きましょう。最初にCOMを理解して簡単なIE操作プログラムを書くためには、翔泳社が出版している Visual C++プログラマのためのCOM入門がお勧めです、値段も2600(+税)円とプログラム関係の本の中では安いほうなので 買っても損はしないと思います。
ただしこの本は「戻る」とか指定したURLに飛ぶとかいった基本的な処理しか書いていないので、指定したフォームに 文字を入れてsubmitボタンを押すなどの込み入った処理はかいてありません。
そこで、次にVC++のマニュアルを調べますIHTMLDocument2IHTMLElementなどの キーワードを指定して調べてみましょう。なんかそれらしいのがありましたよね。後はそのマニュアルと格闘です。頑張りましょう。

最後に指定したURLのページへジャンプしその<BODY>タグ内の内容を出力するコンソールプログラムを載せておきます
開発環境: Visual C++6.0 Windows95,InternetExplorer 4.72.311 0.8

エラー処理は一応やっているつもりなんですが、うまく行かずメモリリークを起こすかもしれないので その辺は調整してください。



#include <iostream.h>
#include <docobj.h> 

#import "c:\windows\system\shdocvw.dll" rename_namespace("CLASS1") named_guids
#import "c:\windows\system\mshtml.dll" rename_namespace("CLASS2") named_guids


int main(int argc, char* argv[])
{

	cout << "プログラムスタート" << endl;

	if ( FAILED( CoInitialize( NULL )))
        {
		cout << "CoInitialize 失敗";
		return -1;
        }

   //使用するインターフェイスを決めます。
   CLASS1::IWebBrowser2Ptr            window;
   CLASS2::IHTMLDocument2Ptr          document;
   CLASS2::IHTMLElementPtr            body;
   
   try
   {
	   HRESULT hr;
	   hr=window.CreateInstance(CLASS1::CLSID_InternetExplorer);
	   if(FAILED(hr))
	   {
		   cout<<"CreateInstance 失敗";
		   CoUninitialize();
	   }	  
   }
   catch(_com_error& e)
   {
	   cout<<"例外発生 "<< e.ErrorMessage();
   }
	
   try
   {
	  _variant_t strURL ("d:\\bbs.html");

	  long pt = 200;
	  long pl = 200;
	  long ph = 600;
	  long pw = 400;

	  window->PutTop(pt);
	  window->PutLeft(pl);
	  window->PutHeight(ph);
	  window->PutWidth(pw);
	  window->PutVisible(VARIANT_TRUE);
	  
	  window->Navigate2(&strURL);
	  while(window->GetBusy()) 
		  Sleep(100);
	 
	  document=window->GetDocument();
	  body=document->Getbody();	  
	  cout <<body->GetouterHTML();
	  window->Quit();
	  }
   catch(_com_error& e)
   {
	   cout <<"例外発生 "<<e.ErrorMessage();
   }
  
  //解放
  body=0;
  document=0;
  window = 0;
  cout << "\n終了しました";
  CoUninitialize();
  return 0;
}

#import "c:\windows\system\mshtml.dll" rename_namespace("CLASS2") named_guidsの部分が滅茶苦茶重いので、コードを編集するときは コメントアウトしたほうがいいでしょう。それだけでだいぶ速度が違います。またビルドするとき何かのファイルが開けませんとエラーが出るのですが リビルドを繰り返すと実行できます。これは原因不明です。
最後になりましたがこのトピックに関しては、アンケート用のフォームで連載の希望がでるまでは面倒くさいので このままにしておきます。連載希望の方はフォームに書きこんでください。

追記(5/2)ヘッダファイルを作って#importの部分をそこに置くようにすればコーディング時に重くなることは防げるみたいです。


戻る