IE上のコントロール – プログラミング – Home

通知
すべてクリア

[解決済] IE上のコントロール


craz
 craz
(@craz)
ゲスト
結合: 19年前
投稿: 5
Topic starter  

IEに表示されているページ上のエディットボックスに文字列を入力したり、
リストボックスから項目を選択したり、ボタンを押したりするには
どうすればいいでしょうか?
普通のアプリケーションならウィンドウハンドルを取得して
それなりのメッセージをSendMessage等で送ってやればすむのですが、
IEに表示されているページのエディットボックス等のウィンドウ
ハンドルは取得できないので困っています。
(たとえば、このラウンジの新規質問の「タイトル」「質問内容」に
適当な文字を入れて、「送信」ボタンを押すことを自動化する
アプリケーションを作りたいのです)


引用未解決
トピックタグ
RAPT
 RAPT
(@RAPT)
ゲスト
結合: 22年前
投稿: 310
 

IEの操作を行なうには、COM(Component Object Model)を使用します。
下記のインターフェースについて調べてみてください。

IWebBrowser2
IHTMLWindow2
IHTMLDocument2

(環境が書かれていないので具体的な例は割愛します。)


返信引用
craz
 craz
(@craz)
ゲスト
結合: 19年前
投稿: 5
Topic starter  

すいません、環境は
XP SP2
VS8.0
です。
とりあえずそのインターフェースについて調べてみます


返信引用
craz
 craz
(@craz)
ゲスト
結合: 19年前
投稿: 5
Topic starter  

http://www.nitoyon.com/vc/tips/ie_component.htm
上記のサイトを参考に
CComPtr<IWebBrowser2> getWebBrowser2(HWND ie)
{
if (HWND server = FindWindowEx(FindWindowEx(ie, 0, LShell DocObject
View, 0), 0, LInternet Explorer_Server, 0)) {
LRESULT res = 0;
CComPtr<IWebBrowser2> document;

SendMessageTimeout(server, RegisterWindowMessage
(LWM_HTML_GETOBJECT), 0, 0, SMTO_ABORTIFHUNG, 1000,
reinterpret_cast<PDWORD_PTR>(&res));
if (SUCCEEDED(ObjectFromLresult(res, IID_IHTMLDocument, 0,
reinterpret_cast<void**>(&document)))) {
if (CComQIPtr<IServiceProvider> sp1 = document) {
CComQIPtr<IServiceProvider> sp2;

sp1->QueryService(SID_STopLevelBrowser,
IID_IServiceProvider, reinterpret_cast<void**>(&sp2));
if (sp2) {
CComPtr<IWebBrowser2> browser;

sp2->QueryService
(SID_SWebBrowserApp, IID_IWebBrowser2, reinterpret_cast<void**>(&browser));

return browser;
}
}
}
}

return 0;
}
inline CComPtr<IHTMLDocument2> webBrowser2ToHTMLDocument2
(CComPtr<IWebBrowser2> browser)
{
CComPtr<IDispatch> dispatch;

browser->get_Document(&dispatch);

return CComQIPtr<IHTMLDocument2>(dispatch);
}と、IWebBrowser2, IHTMLDocument2の取得をしていろいろ試しているのですが、うまく
いきません。
誰かお知恵をお貸しください・・・


返信引用
RAPT
 RAPT
(@RAPT)
ゲスト
結合: 22年前
投稿: 310
 

とりあえず、そのURLを参考に書いてみたら、タイトル・URLの取得はうまく動作して
いるようです。(VC++6sp6/Windows2000sp4/SDK Feb2003/ATL3.0)

CComPtr<IWebBrowser2> GetIWebBrowser2(HWND hWndServer)
{
if( !hWndServer ){
return NULL;
}

LRESULT lRes;
UINT nMsg = ::RegisterWindowMessage(_T(WM_HTML_GETOBJECT));
::SendMessageTimeout(hWndServer, nMsg, 0L, 0L, SMTO_ABORTIFHUNG,
1000, (DWORD*)&lRes);

CComPtr<IHTMLDocument2> spDoc;
HRESULT hr = ::ObjectFromLresult(lRes, __uuidof(IHTMLDocument2), 0L,
(void**)&spDoc);
if( FAILED(hr) ){
return NULL;
}

CComQIPtr<IServiceProvider> spSp1 = spDoc;
CComQIPtr<IServiceProvider> spSp2;
CComPtr<IWebBrowser2> spBrowser;
spSp1 && spSp1->QueryService(SID_STopLevelBrowser,
IID_IServiceProvider, (void**)(&spSp2));
spSp2 && spSp2->QueryService(SID_SWebBrowserApp, IID_IWebBrowser2,
(void**)(&spBrowser));
return spBrowser;
}

void Test(void)
{
HWND hWndFrame = ::FindWindowEx(NULL, NULL, _T(IEFrame), NULL);
HWND hWndView = ::FindWindowEx(hWndFrame, NULL, _T(Shell DocObject
View), 0);
HWND hWndServer = ::FindWindowEx(hWndView, NULL, _T(Internet
Explorer_Server), NULL);
CComPtr<IWebBrowser2> spBrowser = GetIWebBrowser2(hWndServer);

if( spBrowser ){
USES_CONVERSION;
CComBSTR bstr;

spBrowser->get_LocationName(&bstr);
ATLTRACE(_T(Title: [%s]\n), OLE2CT(bstr));

spBrowser->get_LocationURL(&bstr);
ATLTRACE(_T( URL: [%s]\n), OLE2CT(bstr));
}
}


返信引用
くまさん
 くまさん
(@くまさん)
ゲスト
結合: 20年前
投稿: 6
 

SPAM書き込みツールでも作るのかな・・・


返信引用
craz
 craz
(@craz)
ゲスト
結合: 19年前
投稿: 5
Topic starter  

>>RAPTさん
Testを参考に確認したところgetWebBrowser2はちゃんと動いているようです
ただ、IE中のエディットボックスやチェックボックスやボタンなどに
アクセスして操作する方法が未だに検討が付かず苦労しています・・
>>くまさん
やりたいのはいろんなサイトにログインするプログラムです。
郵貯や銀行やら・・こういうのはMoneyやSAISONPASS等わざわざ作らなくても
やってくれるソフトがあるのですが、どうしてもこういったソフトでは
対応できないマイナーなサイトがあって、かつこういうソフトを二つ以上
インストールしたくないから、じゃあ自分で作ってしまおうというわけです。


返信引用
Blue
 Blue
(@Blue)
ゲスト
結合: 20年前
投稿: 1467
 

そのサイトは一切見ていませんが、
VBScriptとかでよくやる方法らしいので
VBのコードをVC++&SHDocVw::IWebBrowser2Ptrのコードにした例です。

ただし、VS8だと、Warningが多数出るっぽいです。

// WindowsXp Pro Sp2 / Visual C++ 6.0 Enter Sp6 / Win32 Console Application
// エラー処理ほとんどなし。
// nameをキーにコントロールを探しています。
#include <windows.h>
#include <comdef.h>
#include <iostream>

#import <shdocvw.dll>
#import <mshtml.tlb>

void test()
{
SHDocVw::IWebBrowser2Ptr pBrowser;

// IEを立ち上げ、Yahooの検索ページを表示
pBrowser.CreateInstance( __uuidof( SHDocVw::InternetExplorer ) );
pBrowser->Visible = VARIANT_TRUE;
pBrowser->Navigate( _bstr_t( L http://search.yahoo.co.jp/ ) );

// ページが表示されるまで待つ
while ( pBrowser->Busy == VARIANT_TRUE ||
pBrowser->ReadyState != READYSTATE_COMPLETE )
::Sleep( 100 );

MSHTML::IHTMLDocument3Ptr pDocument( pBrowser->Document );
MSHTML::IHTMLElementCollectionPtr pCollection;

// 検索文字列を設定
pCollection = pDocument->getElementsByName( _bstr_t( Lp ) );
MSHTML::IHTMLInputTextElementPtr pText( pCollection->item() );
pText->value = _bstr_t( LVisual C++ 掲示板 );

// ウェブ検索ボタンを押す(Submit)
pCollection = pDocument->getElementsByName( _bstr_t( Lw ) );
MSHTML::IHTMLFormElementPtr pForm( pCollection->item() );
pForm->submit();

// ページが表示されるまで待つ
while ( pBrowser->Busy == VARIANT_TRUE ||
pBrowser->ReadyState != READYSTATE_COMPLETE )
::Sleep( 100 );
}

int main()
{
if ( FAILED( ::CoInitialize( NULL ) ) ) return -1;

test();

::CoUninitialize();
return 0;
}


返信引用
craz
 craz
(@craz)
ゲスト
結合: 19年前
投稿: 5
Topic starter  

Blueさんの方法で無事目的を達成することが出来ました
ありがとうございました!


返信引用

返信する

投稿者名

投稿者メールアドレス

タイトル *

プレビュー 0リビジョン 保存しました
共有:
タイトルとURLをコピーしました