サーバレス練習帳

着眼大局着手小局

フレーム(frameset)だとDOMオブジェクトがgetElementsByIdで見つからない

こんな感じで二重で読み込むのですね。

objIE.document.frames(0).document.getElementsByName("LOGIN")(0).Click

www.atmarkit.co.jp

こっちにも解説があった。大変そうではありますが。。。

HtmlDocument.GetElementById()などで目的のフレームの要素(HtmlElement)を取得する
HtmlElement.DocElementからアンマネージインターフェイスへのポインターを得る
アンマネージインターフェイスへのポインターからIHTMLFrameBase2インターフェイスを得る
IHTMLFrameBase2.contentWindowプロパティでIHTMLWindow2インターフェイスを得る
IHTMLWindow2インターフェイスからIServiceProviderインターフェイスを得る
IServiceProvider.QueryServiceメソッドに引数IID_IWebBrowserAppとIID_IWebBrowser2を渡すことでIWebBrowser2インターフェイスを得る
IWebBrowser2.DocumentプロパティでIHTMLDocumentインターフェイスを得る

ja.stackoverflow.com

iHTMLELEMENTの解説
http://www.ne.jp/asahi/hishidama/home/soft/java/doc/jp/hishidama/win32/mshtml/IHTMLElement.html#getDocument()

今度こそ、これでいけるかも!

d.hatena.ne.jp

あ、これでできた!やったー!↓↓↓
プログラム0016

#include <windows.h>
#include <exdisp.h>
#include <mshtml.h>
#include <oleacc.h>
#include <shlwapi.h>

#pragma comment (lib, "oleacc.lib")
#pragma comment (lib, "urlmon.lib")
#pragma comment (lib, "shlwapi.lib")

BOOL GetImages(IHTMLDocument3 *pDocument3);
BOOL GetDocumentFromIE(IHTMLDocument3 **pp);
BOOL CALLBACK EnumChildProc(HWND hwnd, LPARAM lParam);

int WINAPI WinMain(HINSTANCE hinst, HINSTANCE hinstPrev, LPSTR lpszCmdLine, int nCmdShow)
{

	IHTMLDocument3 *pDocument3;

	CoInitialize(NULL);

	if (!GetDocumentFromIE(&pDocument3)) {
		CoUninitialize();
		MessageBox(NULL, TEXT("ページが見つかりません!"), TEXT("終了"), MB_OK);
		return 0;

	}

	GetImages(pDocument3);


	return 0;
}

BOOL GetImages(IHTMLDocument3 *pDocument3)
{
	BSTR                   bstrText;
	LONG                   i, lTitleCount;
	VARIANT                varName, varIndex;
	IDispatch              *pDispatch;
	IHTMLElement        *pTitleElement, *pFrameElement;
	IHTMLFrameElement3			*pFrameElement3;
	IHTMLElementCollection *pElementCollection;

	IHTMLDocument3 *pDocument3frame;
	IDispatch              *pDispatchFrame;
	//まず、frame探す
	BSTR                   bstrFrameId;
	bstrFrameId = SysAllocString(L"frmManager");
	pDocument3->getElementById(bstrFrameId, &pFrameElement);
	SysFreeString(bstrFrameId);
	pFrameElement->QueryInterface(IID_PPV_ARGS(&pFrameElement3));
	pFrameElement3->get_contentDocument(&pDispatchFrame);
	pDispatchFrame->QueryInterface(IID_IHTMLDocument3, (void**)&pDocument3frame);

	//pFrameElement->get_document(&pDispatchFrame);

	//IHTMLFrameBase2* pFrame2 = NULL;
	//pDispatchFrame->QueryInterface(IID_IHTMLFrameBase3, (void**)&pFrame3);
	//pDispatchFrame->Release();

	//IHTMLWindow3* pWnd3 = NULL;
	//pFrame2->get_contentWindow(&pWnd2);
	//pFrame2->Release();

	//pWnd2->get_document(&pDocument3frame);

	//調査対象のタグ
	BSTR                   bstrTag;
	bstrTag = SysAllocString(L"input");
	pDocument3frame->getElementsByTagName(bstrTag, &pElementCollection);
	MessageBoxW(NULL, bstrTag, L"調査対象タグ", MB_OK);
	SysFreeString(bstrTag);
	pElementCollection->get_length(&lTitleCount);

	TCHAR msg[256];
	wsprintf(msg, TEXT("該当データは%d件です。"), lTitleCount);
	MessageBox(NULL, msg, TEXT("確認"), MB_OK);
	if (lTitleCount == 0) {
		MessageBox(NULL, TEXT("該当タグがありません。"), TEXT("OK"), MB_OK);
		return FALSE;
	}

	for (i = 0; i < lTitleCount; i++) {
		VariantInit(&varName);
		varName.vt = VT_I4;
		varName.lVal = i;

		VariantInit(&varIndex);
		varIndex.vt = VT_I4;
		varIndex.lVal = 0;

		pElementCollection->item(varName, varIndex, &pDispatch);
		pDispatch->QueryInterface(IID_PPV_ARGS(&pTitleElement));
		pDispatch->Release();

		//pTitleElement->get_innerText(&bstrText);
		pTitleElement->get_outerHTML(&bstrText);
		MessageBoxW(NULL, bstrText, L"抽出されたテキスト", MB_OK);


		//lpszFileName = PathFindFileNameW(bstrUrl);
		//wsprintfW(szFilePath, L"%s\\%s", szSrcDirectory, lpszFileName);
		//URLDownloadToFileW(NULL, bstrUrl, szFilePath, 0, NULL);

		//SysFreeString(bstrUrl);
		pTitleElement->Release();
	}

	MessageBox(NULL, TEXT("これで全てです!"), TEXT("OK"), MB_OK);

	pElementCollection->Release();

	IHTMLElement   *pElementTag = NULL;
	BSTR           bstrIdTag = SysAllocString(L"");
	bstrIdTag = SysAllocString(L"str_Value008");
	pDocument3frame->getElementById(bstrIdTag, &pElementTag);
	if (pElementTag == NULL) {
		SysFreeString(bstrIdTag);
		MessageBox(NULL, TEXT("DOMが見つからない!"), TEXT("確認"), MB_OK);
		return FALSE;
	}
	SysFreeString(bstrIdTag);
	CoUninitialize();
	MessageBox(NULL, TEXT("DOMあった!"), TEXT("確認"), MB_OK);



	return TRUE;
}

BOOL GetDocumentFromIE(IHTMLDocument3 **pp)
{
	HWND    hwnd;
	UINT    uMsg;
	LRESULT lResult;
	HRESULT hr;

	EnumChildWindows(FindWindow(TEXT("IEFrame"), TEXT("ワークフロー - Internet Explorer")), EnumChildProc, (LPARAM)&hwnd);
	if (hwnd == NULL)
		return FALSE;

	uMsg = RegisterWindowMessage(TEXT("WM_HTML_GETOBJECT"));
	if (!SendMessageTimeout(hwnd, uMsg, 0, 0, SMTO_ABORTIFHUNG, 1000, (LPDWORD)&lResult))
		return FALSE;

	hr = ObjectFromLresult(lResult, IID_IHTMLDocument3, 0, (void **)pp);
	if (FAILED(hr))
		return FALSE;

	return TRUE;
}


BOOL CALLBACK EnumChildProc(HWND hwnd, LPARAM lParam)
{
	TCHAR szClassName[256];

	GetClassName(hwnd, szClassName, sizeof(szClassName) / sizeof(TCHAR));
	if (lstrcmp(szClassName, TEXT("Internet Explorer_Server")) == 0) {
		*((HWND *)lParam) = hwnd;
		return FALSE;
	}
	else
		return TRUE;
}

追記
Delphiでやる場合、さらに悩み中
但し、このページの考え方でできるんじゃないか?
d.hatena.ne.jp


それから、IHTMLFrameCollection2型というのがある?
https://social.msdn.microsoft.com/Forums/ja-JP/af25a1a1-b0fc-4a82-9d30-64efb2252cf3/mshtmlhtmldocumentframes123951239082212535123450123731242812383124611?forum=netfxgeneralja

IHTMLDocument2::frames が IHTMLFramesCollection2 であり、IHTMLFramesCollection2::item の返す型は IHTMLWindow2 です。