概要

MSHTMLを使用して指定されたURLのファイルに含まれるリンク先の有無を確認しサイズと更新日時を取得します。
MSHTMLとは、インターネットエクスプローラーのhtmlファイルを解析するためのモジュールです。  ここでは、http://yamatyuu.net/computer/program/vc2013/htmlget6/htmlget6.htmlを呼び出しています。 リンク先の検索条件は、id又はクラス名が一致したdivタグの中に含まれるURLを対象としています。MSHTMLを使用してクラス名d2のdivタグの中身を取得(32/64bit)と違う点は、divが入れ子になっていても大丈夫な点です。

本プログラムの実行例


リンク先のtest5.htmlは実際には存在しないファイルなので日付は表示されません。

前回作成した、MSHTMLを使用してクラス名d2のdivタグの中身を取得(32/64bit)の実行例


前回の場合、divの中にdivが含まれている状態(いわゆる入れ子)になっているので、抽出結果が、<DIV><A id=id5 ~ </A><BR></DIV>となりリンク先が抽出されていない。

テスト環境

コンパイラ

Visual C++ 2008/2013 Express 32/64bit UNICODE

実行環境

Windows XP Professional Service Pack 3 32bit(Virtual Box上の仮想マシーン)
Windows 7 Enterprise Service Pack 1 64bit

プログラムソースの概要

htmlget6.html

WinMain

 CoInitialize APIによりCOMを初期化後、ダイアログボックスを呼び出します。
 ダイアログボックスが終了したらCoUninitialize APIによりCOMを解放します。

DlgProc

WM_INITDIALOG
 ダイアログボックスの初期化時に呼び出されます。
初期URLや検索条件を設定します。
 ダイアログボックスのサイズの変更に備えて各種コモンコントロールの位置や大きさを取得します。
WM_SIZE
 ダイアログボックスの大きさが変更された時に呼び出されます。
 ダイアログボックスの大きさに合わせて、ボタンはダイアログボックスの高さにあわせて移動させます。
 エディットボックスは、ダイアログボックスの大きさに合わせてサイズを変化させます。
WM_COMMAND
IDC_READ_BUTTON
 読み込みボタンがクリックされた時に呼び出されます。
 カーソルを処理中に変更し、URL及び検索条件を取得し、htmlRead関数を呼び出しエディットボックスにソースを表示させ、関数から戻ったときにカーソルを元に戻します。
IDCANCEL
 キャンセルボタンがクリックされた時に呼び出されます。
 EndDialog APIによりダイアログボックスを終了させます。

htmlRead

URLを読み込む元になるオブジェクトの作成
 MSHTML::IHTMLDocument4Pt doc4pをCreateInstanceメンバー関数により初期化します。
 指定したURLを呼び出すcreateDocumentFromUrlメンバー関数は、元になるオブジェクトが必要なため、<html></html>という内容を含んだSAFEARRAY型を作成し、writeメンバー関数によりIHTMLDocument2インターフェースに書き込みcloseメンバー関数により書き込みを終了させます。
URLの読み込み
 元になるオブジェクトを元にcreateDocumentFromUrlメンバー関数を読み出し、MSHTML::IHTMLDocument2Ptr doc2pに保存します。
 createDocumentFromUrlメンバー関数は読み込みが終了する前に呼び出し元に戻るので、MSHTML::IHTMLDocument2Ptr doc2p->readyState != cmpで読み込み終了をチェックしています。COMをSTAで初期化したので、PeekMessage~DispatchMessageによりメッセージループを設けてあげないとCOMと本プログラム間でメッセージが届かないのでプログラムが正常に動作しません。
タグを取得
 doc2pからMSHTML::IHTMLDocument3Ptr doc3へキャストします。
MSHTML::IHTMLDocument3Ptr getElementByTagNameによりdivタグを取得します。 doc3からタグ名がd2のエレメントを取得しMSHTML::IHTMLElementCollectionPtrに保存します。
divのうちクラス名またはidが一致するdivを抽出
divタグの個数をMSHTML::IHTMLElementCollectionPtr->lengthにより取得します。
MSHTML::IHTMLElementCollectionPtr->itemにより複数のdivタグの中から指定されたdivタグを取得しMSHTML::IHTMLElementPtrに保存します。
MSHTML::IHTMLElementPtr->getAttributeによりdivの属性のうちクラス名又はidを取得しVARIANT型に保存します。クラス名を取得するときは、属性名がClassではなくClassNameと指定しないと取得できませんので注意が必要です。
 VARIANT型から文字列を抽出し文字列d2と比較し一致すればdivタグのうちクラス名またはidが一致するが取得できたことになります。
divに含まれるタグの取得
 MSHTML::IHTMLElementPtr->QueryInterfaceにより MSHTML::IHTMLDOMNodePtrインターフェースを取得しnodepに保存します。
MSHTML::IHTMLDOMNodePtrのメンバー変数childNodesに子エレメントが含まれているのでMSHTML::IHTMLDOMChildrenCollectionPtr collpに保存します。
子エレメントを解析するchild関数を呼び出します。  作成された、doc4p,doc3p,doc2p,elementpに0を代入することにより解放されます。解放しないとエラーが発生して正常に動作しません。
 なお、MSHTMLとは、#importでmshtml.tlbを読み込むときに変更した名前であり、import.hの中で定義しています。ほかの人ではHTMLとかに定義している人もいます。気に入らなければ変更することができます。
MSHTML::IHTMLDocument2Ptr、MSHTML::IHTMLDocument3Ptr、MSHTML::IHTMLDocument4Ptrはメンバーが異なるのみでキャストすれば自由に使い分けできます。たとえばwriteメンバー関数を呼び出すためにMSHTML::IHTMLDocument4PtrをMSHTML::IHTMLDocument2Ptrにキャストしています。
 ソースに出てくるBSTR型、VARIANT型、SAFEARRAY型はCOMでよく使われるものです。

child

MSHTML::IHTMLDOMChildrenCollectionPtr->lengthにより子エレメントの個数を取得します。
MSHTML::IHTMLDOMNodePtr->itemにより任意の子エレメントを取得しMSHTML::IHTMLDOMNodePtrに保存します。
MSHTML::IHTMLDOMNodePtrをMSHTML::IHTMLElementPtrへキャストします。
MSHTML::IHTMLElementPtr->get_tagNameによりタグ名を取得しAタグであればa_tag_put関数によりリンク先の表示およびリンク先の更新日時の表示を行います。
 MSHTML::IHTMLElementPtr->QueryInterfaceにより MSHTML::IHTMLDOMNodePtrインターフェースを取得しcnodepに保存します。
MSHTML::IHTMLDOMNodePtrのメンバー変数childNodesに子エレメントが含まれているのでMSHTML::IHTMLDOMChildrenCollectionPtr ccollpに保存します。
MSHTML::IHTMLDOMChildrenCollectioにより孫エレメントの個数を取得します。
孫エレメントがあればchild関数を再帰呼び出しします。

a_tag_put

MSHTML::IHTMLElementPtr->getAttributeによりhref属性(リンク先)を取得します。
後でMSHTML::IHTMLElementPtr->innerHTMLを後で呼び出すとgetAttributeで取得したポインタが示す文字列がinnerHTMLの内容になってしまうので、getAttributeで取得した文字列をローカルの配列にコピーしておきます。
MSHTML::IHTMLElementPtr->innerHTMLでaタグに挟まれた文字列を取得します。
HtmlGet2関数によりリンク先の更新日時及びサイズを取得します。

HtmlGet2

InternetCrackUrl APIによりURLからサーバー名等を取得します。 インターネットのサービスをInternetOpen APIによりオープンします。 InetrnetConnect APIによりサーバーに接続します。 HttpOpenRequest APIによりサーバーリクエストを初期化し、HttpSendRequest APIによりリクエストします。 HttpQueryInfo APIによりリクエストに対するステータス(答え)を取得します。 この時、エラーステータスが返された場合、終了します。ここでいうエラーとはお馴染みの403等です。 HttpQueryInfo APIによりファイルサイズを取得します。 HttpQueryInfo APIによりファイルの更新日時を取得します。 更新日時は世界標準時なので日本時間に変換します。 各ハンドルをInternetCloseHandle APIにより閉じます。

ソースコード

htmlget6.cpp

//	htmlファイルのしてされたidまたはクラス名のdivタグに含まれるリンク(aタグ)を抽出しリンク先が存在するかチェックし結果を返す

#include <windows.h>
#include <tchar.h>
#include <docobj.h>
#include <wininet.h>
#include <commctrl.h>

#define SIZE_CHG 1 //	ダイアログボックスの大きさを変更した場合に各コントロールの大きさ位置を変更させる場合に定義してください

#include "resource.h"
#include "import.h"

#pragma comment(lib,"comctl32.lib")
#pragma comment(lib,"wininet.lib")

using namespace std;

int error_msg=0;

//	ダイアログボックスプロシージャー
LRESULT CALLBACK DlgProc(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam);


int WINAPI WinMain(HINSTANCE hCurInst, HINSTANCE hPrevInst,LPSTR lpsCmdLine, int nCmdShow){
	InitCommonControls();

	if( FAILED( CoInitialize(NULL) )){	//	COMの初期化 STA(シングルスレッドアパートメント)
		MessageBox(0,_TEXT("COMの初期化に失敗しました"),_TEXT("エラー"),MB_OK);
		return -1;
	}
//	ダイアログボックスの表示
	DialogBox(hCurInst, TEXT("DLG1"), 0, (DLGPROC)DlgProc);

	CoUninitialize();	//	COMの解放
	return (int)0;
}

//	Htmlファイルを読み込み<div class=""d2>タグの中に含まれるタグを表示
void htmlRead(TCHAR* url,TCHAR* name,TCHAR* attr,HWND hEdit);

//	子ノードを再帰的に解析する
void child(TCHAR* buf,int sz,HWND hEdit,MSHTML::IHTMLDOMChildrenCollectionPtr collp,int* level);

//	Aタグを出力する
void a_tag_put(TCHAR* edit,int edit_sz,MSHTML::IHTMLElementPtr celementp);

//	インターネット上のファイルの有無、サイズ、日時を取得する
bool HtmlGet2(TCHAR* url,DWORD* status_code,DWORD* sz,SYSTEMTIME* LocalTime);


//	ダイアログボックスプロシージャー

LRESULT CALLBACK DlgProc(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam){
	static HWND hEdit,hURL;
#ifdef SIZE_CHG	//	ダイアログボックスの大きさを変更した場合に各コントロールの大きさ位置を変更させる場合に必要
	static HWND hCANCLE,hBUTTON102;
	static int hEditx,hEdity,hEditWidth,hEditHeight;
	static int hCANCLEx,hCANCLEy,hCANCLEWidth,hCANCLEHeight;
	static int hBUTTON102x,hBUTTON102y,hBUTTON102Width,hBUTTON102Height;
	RECT hDlgrect;
	RECT rect;
	POINT point;
	TCHAR url[256];
	TCHAR name[256];
#endif
	static HCURSOR wait_icon=0;
	static HCURSOR org_icon=0;

	switch (msg) {
		case WM_INITDIALOG:{
			wait_icon=LoadCursor(NULL,IDC_WAIT);	//	処理中アイコンの取得

			hEdit=GetDlgItem(hDlg,IDC_EDIT);
			hURL=GetDlgItem(hDlg,IDC_URL_EDITBOX);
			SetWindowText(hURL,_TEXT("http://yamatyuu.net/computer/program/vc2013/htmlget6/htmlget6.html"));
			SetWindowText(GetDlgItem(hDlg, IDC_SRC_EDITBOX)	,_TEXT("d2"));
			SendMessage(GetDlgItem(hDlg,IDC_CLASS_RADIOBOX) , BM_SETCHECK,BST_CHECKED,0);
#ifdef SIZE_CHG	//	ダイアログボックスの大きさを変更した場合に各コントロールの大きさ位置を変更させる場合に必要
			hCANCLE=GetDlgItem(hDlg,IDCANCEL);
			hBUTTON102=GetDlgItem(hDlg,IDC_READ_BUTTON);
//	ダイアログボックスクライアント領域の大きさを取得
			GetClientRect(hDlg,&hDlgrect);
			int width=hDlgrect.right;
			int height=hDlgrect.bottom;
			GetWindowRect(hDlg,&hDlgrect);

//	エディットボックスのダイアログボックスのクライアント座標・大きさとダイアログボックスの大きさの差を取得
			GetWindowRect(hEdit,&rect);
			point.x=rect.left;
			point.y=rect.top;
			ScreenToClient(hDlg,&point);
			hEditx=point.x;
			hEdity=point.y;
			hEditWidth=(rect.right-rect.left)-width;
			hEditHeight=(rect.bottom-rect.top)-height;
//	ボタンコントロールのイアログボックスのクライアント座標(ダイアログbottomを基準)・大きさを取得
			GetWindowRect(hBUTTON102,&rect);
			point.x=rect.left;
			point.y=rect.top;
			ScreenToClient(hDlg,&point);
			hBUTTON102x=point.x - (width)/2;
			hBUTTON102y=point.y-height;
			hBUTTON102Width=(rect.right-rect.left);
			hBUTTON102Height=(rect.bottom-rect.top);

			GetWindowRect(hCANCLE,&rect);
			point.x=rect.left;
			point.y=rect.top;
			ScreenToClient(hDlg,&point);
			hCANCLEx= point.x -(width)/2;
			hCANCLEy=point.y-height;
			hCANCLEWidth=(rect.right-rect.left);
			hCANCLEHeight=(rect.bottom-rect.top);
#endif
			return TRUE;
		}
#ifdef SIZE_CHG
		case WM_SIZE:{	//	ウィンドウサイズが変更された

			RECT hDlgrect;
			GetWindowRect(hDlg,&hDlgrect);

			int width=LOWORD(lParam);
			int height=HIWORD(lParam);
			MoveWindow(hEdit , hEditx,hEdity, width + hEditWidth, height+hEditHeight,TRUE);
			MoveWindow(hBUTTON102 , width/2+hBUTTON102x,height+hBUTTON102y, hBUTTON102Width, hBUTTON102Height,TRUE);
			MoveWindow(hCANCLE , width/2+hCANCLEx,height+hCANCLEy,hCANCLEWidth, hCANCLEHeight,TRUE);
			return FALSE;
		}
#endif
		case WM_COMMAND:
			switch (LOWORD(wParam)) {
				case IDC_READ_BUTTON:{
					org_icon=GetCursor();
					SetCursor(wait_icon);
					::error_msg=0;
					GetWindowText(hURL,url,sizeof(url)/sizeof(TCHAR));
					GetWindowText(GetDlgItem(hDlg,  IDC_SRC_EDITBOX),name,sizeof(name)/sizeof(TCHAR));
					TCHAR* attr=_TEXT("id");
					if(IsDlgButtonChecked(hDlg,IDC_CLASS_RADIOBOX)==BST_CHECKED)
						attr=_TEXT("ClassName");
					htmlRead(url,name,attr,hEdit);
					SetCursor(org_icon);
					return FALSE;
				}
				case IDCANCEL:
					EndDialog(hDlg,TRUE);
					return TRUE;
				default:
					return FALSE;
			}
			default:
				return FALSE;
	}
	return TRUE;
}




//	Htmlファイルを読み込みエディットコントロールにbodyタグに含まれるソースを張り付ける

TCHAR edit[4096];

void htmlRead(TCHAR* urls,TCHAR* name,TCHAR* attr,HWND hEdit){
	MSHTML::IHTMLDocument2Ptr doc2p;
	MSHTML::IHTMLDocument4Ptr doc4p;
	HRESULT hr;

//	IHTMLDocument4Ptrの初期化
	hr=doc4p.CreateInstance( MSHTML::CLSID_HTMLDocument );
	if(	FAILED(hr) ){
		MessageBox(0,_TEXT("CreateInstance 失敗"),_TEXT("エラー"),MB_OK);	
		return;
	}

//	doc4に最低限のオブジェクトを作成
	VARIANT* param;
	SAFEARRAY* sfArray=NULL;
	BSTR bstr=NULL;
	bstr= ::SysAllocString(OLESTR("<html></html>"));
	if(bstr==NULL){
		return;
	}
	sfArray=::SafeArrayCreateVector(VT_VARIANT,0,1);
	if(sfArray==NULL){
		::SysFreeString(bstr);
		return;
	}
	hr=::SafeArrayAccessData(sfArray,(LPVOID*)&param);
	param->vt=VT_BSTR;
	param->bstrVal=bstr;
	hr=::SafeArrayUnaccessData(sfArray);
	hr=((MSHTML::IHTMLDocument2Ptr)doc4p)->write(sfArray);
	((MSHTML::IHTMLDocument2Ptr)doc4p)->close();

//	doc4を親オブジェクトとしてurlを読み込む。
	BSTR url=::SysAllocString(urls);
	BSTR obj=0;	//	表示対象をプリンターが以外に設定

	_bstr_t cmp=::SysAllocString(_TEXT("complete"));
	doc2p=doc4p->createDocumentFromUrl(url,obj);

	MSG msg;
	unsigned n=0;
	do{	//	COMをSTAで初期化したため、メッセージループを設けないと読み込み完了が検出できない
		if (PeekMessage(&msg, 0, 0 ,0, PM_REMOVE)){
			TranslateMessage (&msg) ;
			DispatchMessage (&msg) ;
		}
		++n;
		Sleep(100);
	}while( doc2p->readyState != cmp );	//	読み込み完了をチェック
	::SysFreeString(url);
	::SysFreeString(cmp);

	MSHTML::IHTMLDocument3Ptr doc3p=(MSHTML::IHTMLDocument3Ptr)doc2p;

	BSTR bstrId = SysAllocString(_TEXT("div"));
	MSHTML::IHTMLElementCollectionPtr	elementp;
	elementp=doc3p->getElementsByTagName(bstrId);
	if(elementp == NULL){
		MessageBox(0,bstrId,_TEXT("下記のTagが見つかりませんでした。"),MB_OK);
		::SysFreeString(bstrId);
		return;
	}
	
	int max=elementp->length;

	edit[0]=_T('\0');
	for(int i=0;i<max;++i){
		MSHTML::IHTMLElementPtr e=elementp->item( variant_t(i) );
		VARIANT var=e->getAttribute(attr,FALSE);
		TCHAR* c=_TEXT("");
		if(var.vt != VT_NULL && var.bstrVal!=(void*)NULL){
			c=var.bstrVal;
		}
		MSHTML::IHTMLDOMNodePtr nodep;
		MSHTML::IHTMLDOMChildrenCollectionPtr collp;

		int level=0;
		if(_tcscmp(c,name)==0){
			e->QueryInterface(IID_PPV_ARGS(&nodep));
			collp=(MSHTML::IHTMLDOMChildrenCollectionPtr)nodep->childNodes;
			child(edit,sizeof(edit)/sizeof(TCHAR),hEdit,collp,&level);
			nodep=0;
		}
		e = 0;
	}

	SetWindowText(hEdit, edit);	//	取得したオブジェクトのソースをエディットボックスに張り付ける
	
	::SysFreeString(bstr);	//	bstrの解放
	::SafeArrayDestroy(sfArray);	//	SAFEARRAYの解放

//	作成されたオブジェクトの解放
	elementp=0;
	doc3p=0;
	doc2p=0;
	doc4p=0;
}



//	子ノードを再帰的に解析する

void child(TCHAR* buf,int sz,HWND hEdit,MSHTML::IHTMLDOMChildrenCollectionPtr collp,int* level){
	int max;
	max=collp->length;	//	子ノードの個数
	MSHTML::IHTMLDOMNodePtr cnodep;
	for(int n=0;n<max;n++){
		cnodep=(MSHTML::IHTMLDOMNodePtr)collp->item(n);	//	n個目の子ノードを抽出
		MSHTML::IHTMLElementPtr celementp = (MSHTML::IHTMLElementPtr)cnodep;
		if(celementp){
			MSHTML::IHTMLDOMNodePtr ccnodep;
			MSHTML::IHTMLDOMChildrenCollectionPtr ccollp;

			BSTR bstr;
			celementp->get_tagName(&bstr);
			TCHAR* tag=bstr;
			TCHAR* href=0;
			if(_tcscmp(tag,_TEXT("A"))==0){	//	aタグのみ対象
				a_tag_put(buf,sz,celementp);
			}
			celementp->QueryInterface(IID_PPV_ARGS(&ccnodep));
			ccollp=(MSHTML::IHTMLDOMChildrenCollectionPtr)ccnodep->childNodes;
			int max2=ccollp->length;
			if( 0 < max2 ){	//	孫ノードが存在する
				int level2=*level+1;
				child(buf,sz,hEdit,ccollp,&level2);	//	孫ノードの解析をする
			}
			::SysFreeString(bstr);
			ccnodep=0;
		}
		cnodep=0;
	}
}


//	Aタグを出力する

void a_tag_put(TCHAR* edit,int edit_sz,MSHTML::IHTMLElementPtr celementp){
	TCHAR buf[512];
	TCHAR href_temp[256];
	TCHAR* href=0;
	VARIANT href_vt=celementp->getAttribute(_bstr_t(_TEXT("href")),FALSE);
	if(href_vt.vt != VT_NULL && href_vt.bstrVal!=(void*)NULL){
		href=href_vt.bstrVal;	//	リンク先の抽出
		_tcscpy_s(href_temp,sizeof(href_temp)/sizeof(TCHAR),href);
		TCHAR* in=celementp->innerHTML;	//	<a>~</a>の中身
		DWORD s,sz;
		SYSTEMTIME LocalTime;
		_stprintf_s(buf,sizeof(buf)/sizeof(TCHAR),_TEXT("%s %s "),in,href_temp);
		_tcscat_s(edit,edit_sz,buf);
		if(HtmlGet2(href,&s,&sz,&LocalTime)==true){
			_stprintf_s(buf,sizeof(buf)/sizeof(TCHAR),
				_TEXT("%.4i年%.2i月%.2i日 %.2i時%.2i分%.2i秒\r\n"),
				LocalTime.wYear , LocalTime.wMonth , LocalTime.wDay ,
				LocalTime.wHour , LocalTime.wMinute , LocalTime.wSecond);
			_tcscat_s(edit,edit_sz,buf);
		}else{
			_tcscat_s(edit,edit_sz,_TEXT("\r\n"));
		}
	}
}

//	インターネット上のファイルの有無、サイズ、日時を取得する
bool HtmlGet2(TCHAR* url,DWORD* status_code,DWORD* sz,SYSTEMTIME* LocalTime){
	URL_COMPONENTS uc;
	HINTERNET hiopen;
	HINTERNET hiconnect;
	HINTERNET hirequest;

	TCHAR host_name[64];
	TCHAR path[128];
	TCHAR buf[64];

	ZeroMemory(&uc , sizeof(URL_COMPONENTS));
	uc.dwStructSize=sizeof(URL_COMPONENTS);
	uc.lpszHostName=host_name;
	uc.lpszUrlPath=path;
	uc.dwHostNameLength=sizeof(host_name)/sizeof(TCHAR);
	uc.dwUrlPathLength=sizeof(path)/sizeof(TCHAR);

//	URLの解析

	unsigned url_len=(unsigned)_tcslen(url);
	if( InternetCrackUrl(url , url_len , ICU_ESCAPE , &uc )==FALSE){
		if(::error_msg==0){
			MessageBox(0,_TEXT("InternetCrackUrl:URLの解析に失敗しました。"),url,MB_OK);
			if(MessageBox(0,_TEXT("以降このエラーが発生した場合は、無視しますか。"),_TEXT("エラー"),MB_YESNO)==IDYES){
				::error_msg=1;
			}else{
				::error_msg=-1;
			}
		}
		return false;
	}

	DWORD flags=0;

	if(uc.nScheme==INTERNET_SCHEME_HTTP){
		flags= INTERNET_FLAG_RELOAD | INTERNET_FLAG_DONT_CACHE | INTERNET_FLAG_NO_AUTO_REDIRECT;
	}else if(uc.nScheme==INTERNET_SCHEME_HTTPS){
		flags=INTERNET_FLAG_RELOAD | INTERNET_FLAG_DONT_CACHE |  INTERNET_FLAG_NO_AUTO_REDIRECT
			| INTERNET_FLAG_SECURE | INTERNET_FLAG_IGNORE_CERT_DATE_INVALID
			| INTERNET_FLAG_IGNORE_CERT_CN_INVALID;
	}else{
		MessageBox(0,_TEXT("HTTPでもHTTPSでもありません"),_TEXT("エラー"),MB_OK);
		return false;
	}
	_stprintf_s(buf,sizeof(buf)/sizeof(TCHAR),_TEXT("%s"),uc.lpszUrlPath);

//	インターネットのサービスハンドルの取得(レジストリ内のIEの設定を使用)
	hiopen=InternetOpen(_TEXT("inetdemo"),INTERNET_OPEN_TYPE_PRECONFIG,	NULL, NULL, 0 );
	if(hiopen==NULL){
		MessageBox(0,_TEXT("InternetOpenで初期化に失敗しました"),_TEXT("エラー"),MB_OK);

		return false;
	}
//	HTTPサーバーへの接続
	hiconnect=InternetConnect(hiopen , uc.lpszHostName , uc.nPort , NULL , NULL , INTERNET_SERVICE_HTTP , 0 , 0);
	if(hiconnect==NULL){
		InternetCloseHandle(hiopen);
		MessageBox(0,_TEXT("InternetConnectでHTTP接続に失敗しました"),_TEXT("エラー"),MB_OK);
		return false;
	}

//	HTTPサーバーへのリクエストの初期化

	hirequest=HttpOpenRequest(hiconnect,_TEXT("GET"),buf,NULL,NULL,NULL,flags,NULL);
	if(hirequest==NULL){
		InternetCloseHandle(hiconnect);
		InternetCloseHandle(hiopen);
		MessageBox(0,_TEXT("HttpOpenRequestでHTTP接続に失敗しました"),_TEXT("エラー"),MB_OK);
		return false;
	}
	if(HttpSendRequest(hirequest , NULL , 0 , NULL , 0)==FALSE){
		InternetCloseHandle(hirequest);
		InternetCloseHandle(hiconnect);
		InternetCloseHandle(hiopen);
		MessageBox(0,_TEXT("HtpSendRequestでHTTP要求送信に失敗しました"),_TEXT("エラー"),MB_OK);
		return false;
	}

//	HTTPリクエストに関連する情報を取得する(ステータスコードを32ビットで返す)

	*status_code=0;
	DWORD len=sizeof(DWORD);
	if(HttpQueryInfo( hirequest , HTTP_QUERY_STATUS_CODE | HTTP_QUERY_FLAG_NUMBER,status_code,&len,0)==FALSE){
		InternetCloseHandle(hirequest);
		InternetCloseHandle(hiconnect);
		InternetCloseHandle(hiopen);
		*status_code=0xffffffff;
		return false;
	}
	if( *status_code != HTTP_STATUS_OK){	//	エラーがー発生した
		InternetCloseHandle(hirequest);
		InternetCloseHandle(hiconnect);
		InternetCloseHandle(hiopen);
		return false;
	}
	//	ファイルサイズの取得
	*sz=0;
	len=sizeof(*sz);
	if(HttpQueryInfo( hirequest , HTTP_QUERY_CONTENT_LENGTH | HTTP_QUERY_FLAG_NUMBER,sz,&len,0)==TRUE){

	}
	SYSTEMTIME UTCTime;
	len=sizeof(UTCTime);
	if(HttpQueryInfo( hirequest ,HTTP_QUERY_LAST_MODIFIED | HTTP_QUERY_FLAG_SYSTEMTIME ,&UTCTime,&len,0)==TRUE){
		FILETIME FileTime, LocalFileTime;

		SystemTimeToFileTime(&UTCTime,&FileTime);
		FileTimeToLocalFileTime(&FileTime, &LocalFileTime);
		FileTimeToSystemTime(&LocalFileTime, LocalTime);
	}

	InternetCloseHandle(hirequest);
	InternetCloseHandle(hiconnect);
	InternetCloseHandle(hiopen);
	return true;
}

import.h

#pragma warning(disable:4192)
#pragma warning(disable:4278)

#import <shdocvw.dll> rename_namespace("SHDocVw") named_guids
#import <mshtml.tlb> rename_namespace("MSHTML") named_guids

#pragma warning(default:4192)
#pragma warning(default:4278)

resource.h

#define	IDC_EDIT		100
#define	IDC_READ_BUTTON		101
#define	IDC_URL_EDITBOX		102
#define	IDC_SRC_EDITBOX		103
#define	IDC_CLASS_RADIOBOX	104
#define	IDC_ID_RADIOBOX		105
#define	IDC_GROUPBOX		106

resource.rc

#include <windows.h>
#include "resource.h"


DLG1 DIALOG DISCARDABLE 0, 0, 414, 366
EXSTYLE WS_EX_DLGMODALFRAME
STYLE WS_POPUP| WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX | DS_SETFONT | WS_THICKFRAME

CAPTION "htmlget6"
FONT 9, "MS 明朝"
{
 CONTROL "URL", -1, "STATIC", WS_CHILD | WS_VISIBLE | SS_NOTIFY, 7, 7, 32, 12
 CONTROL "", IDC_URL_EDITBOX, "EDIT", WS_CHILD | WS_DLGFRAME | WS_VISIBLE | ES_MULTILINE | ES_WANTRETURN | ES_LEFT, 70, 5, 320, 12

 CONTROL "div検索条件", IDC_GROUPBOX, "BUTTON", WS_CHILD | WS_VISIBLE | BS_GROUPBOX, 7, 26, 400, 33
 CONTROL "クラス名", IDC_CLASS_RADIOBOX, "BUTTON", WS_CHILD | WS_VISIBLE | BS_AUTORADIOBUTTON, 14, 40, 48, 12
 CONTROL "ID", IDC_ID_RADIOBOX, "BUTTON", WS_CHILD | WS_VISIBLE | BS_AUTORADIOBUTTON, 69, 40, 48, 12

 CONTROL "",  IDC_SRC_EDITBOX, "EDIT", WS_CHILD | WS_DLGFRAME | WS_VISIBLE | ES_AUTOHSCROLL, 124, 38, 266, 12


 CONTROL "リンク先", -11, "STATIC", WS_CHILD | WS_VISIBLE | SS_NOTIFY, 7, 66, 54, 12
 CONTROL "読み込まれていません。", IDC_EDIT, "EDIT", WS_CHILD | WS_DLGFRAME | WS_VISIBLE | WS_HSCROLL | WS_VSCROLL
			| ES_AUTOHSCROLL  | ES_AUTOVSCROLL | ES_MULTILINE | ES_READONLY, 7, 78, 400, 242
 CONTROL "読み込み(&R)", IDC_READ_BUTTON, "BUTTON", WS_CHILD | WS_VISIBLE | BS_DEFPUSHBUTTON, 146, 334, 54, 18
 CONTROL "キャンセル(&C)", IDCANCEL, "BUTTON", WS_CHILD | WS_VISIBLE | BS_DEFPUSHBUTTON, 214, 334, 54, 18
}

実行ファイルとソースファイルのダウンロード