よろしくお願いします。
Windows XP SP2
Visual Studio 2005
この様な環境です、MSDNの方で質問したのですがレスが付きそうもないので
仕方なくマルチポストのような格好になるのですが、お許しください。
現在アクティブなインターネットエクスプローラのURLを取得したいのですが、
COMコンポーネントの知識が無く、何処をどの様に修正してよいのか分かりません
間違い誤認識ございましたらご指摘願います。
下記のコードをデバッグしますと
「test1.exe の 0x0040106a でハンドルされていない例外が発生しました: 0xC0000005: 場所 0x00000000 を読み込み中にアクセス違反が発生しました。」
←印の部分でこの様なエラーが出てしまいます
#include <windows.h>
#include <tchar.h>
#include <atlbase.h> // ATL基本機能用ヘッダファイル
#include <atlhost.h> // ATL コンテナ機能サポート用ヘッダファイル
void main()
{
HWND hWindow = FindWindow(L"IEFrame", NULL);
DWORD thid = GetWindowThreadProcessId(hWindow, NULL);
static CComQIPtr< IWebBrowser2 > pWB2;
BSTR LocationURL;
char theURL[ 256 ];
::ZeroMemory( theURL, 256 );
pWB2->get_LocationURL( &LocationURL );
int n = WideCharToMultiByte( CP_ACP, 0, LocationURL, SysStringLen( LocationURL ), theURL, sizeof( theURL ) - 1, 0, 0 );
printf ("%s", theURL);
::SysFreeString( LocationURL ); // リソースの開放
}
ATLを使わない方法ですが、こんな感じ。
BSTRはcomdef.hの_bstr_tクラスを使うとconst char*にキャストできるので便利。
(WideCharToMultiByteはおそらく内部で処理される)
// 一番最初に見つかったInternet Explorerの表示しているURLを取得する
// 環境:Windows Xp Pro SP2/Visual C++ 6.0 Enter SP6/Internet Explorer 6.0 SP2
#include <windows.h>
#import <shdocvw.dll>
#import <mshtml.tlb>
HRESULT GetIEURL( _bstr_t& url )
{
HRESULT hr = S_OK;
SHDocVw::IShellWindowsPtr pSW = NULL;
try
{
hr = pSW.CreateInstance( __uuidof( SHDocVw::ShellWindows ) );
if ( FAILED( hr ) ) _com_issue_error( hr );
// Internet Explorer と Explorere が列挙される
for ( long i = 0; i < pSW->Count; ++i )
{
SHDocVw::IWebBrowser2Ptr pIE = NULL;
if ( pIE = pSW->Item( i ) )
{
MSHTML::IHTMLDocumentPtr pDoc = NULL;
if ( pDoc = pIE->GetDocument() ) // IInternet Explorerかどうか判定
{
url = pIE->GetLocationURL();
break;
}
}
}
}
catch (_com_error& e)
{
hr = e.Error();
}
if ( pSW ) pSW.Release();
return hr;
}
int main()
{
if ( SUCCEEDED( ::CoInitialize( NULL ) ) )
{
_bstr_t url;
if ( SUCCEEDED( GetIEURL( url ) ) )
{
// 確認
::MessageBox( NULL, url, TEXT( "URL" ), MB_OK );
}
::CoUninitialize();
}
return 0;
}
ちなみに
>現在アクティブなインターネットエクスプローラの
が微妙ですが、任意のウィンドウハンドルをもつIEを限定する場合、
SHDocVw::IWebBrowser2PtrのGetHWND(もしくはHWND)で取得できる値を
HWND型にキャストすると判定できます。
但し、IEコンポーネントを使っているようなアプリ(たとえばSleipnirとか)
を使っている場合、
pIE->GetHWND();
で取得しようとすると_com_errorが発生します。
なので、ここだけは邪道ですが、get_HWNDをつかって戻り値で成功しているか判定します。)
以下変更したコード
// 指定したウィンドウハンドルを持つInternet Explorerの表示しているURLを取得する
// 環境:Windows Xp Pro SP2/Visual C++ 6.0 Enter SP6/Internet Explorer 6.0 SP2
#include <windows.h>
#import <shdocvw.dll>
HRESULT GetIEURL( _bstr_t& url, const HWND target )
{
HRESULT hr = S_OK;
SHDocVw::IShellWindowsPtr pSW = NULL;
try
{
hr = pSW.CreateInstance( __uuidof( SHDocVw::ShellWindows ) );
if ( FAILED( hr ) ) _com_issue_error( hr );
for ( long i = 0; i < pSW->Count; ++i )
{
SHDocVw::IWebBrowser2Ptr pIE = NULL;
if ( pIE = pSW->Item( i ) )
{
long hWnd;
if ( SUCCEEDED( pIE->get_HWND( &hWnd ) ) &&
( reinterpret_cast< HWND >( hWnd ) == target ) )
{
url = pIE->GetLocationURL();
break;
}
}
}
}
catch (_com_error& e)
{
hr = e.Error();
}
if ( pSW ) pSW.Release();
return hr;
}
int main()
{
if ( SUCCEEDED( ::CoInitialize( NULL ) ) )
{
_bstr_t url;
HWND target = ::FindWindow( TEXT( "IEFrame" ), NULL );
if ( target && SUCCEEDED( GetIEURL( url, target ) ) )
{
::MessageBox( NULL, url, TEXT( "URL" ), MB_OK );
}
::CoUninitialize();
}
return 0;
}
ただ、ウィンドウハンドルがわかるのであれば、別にIWebBrowser2を使う必要もないかなぁと。
(SendMessageとか使っていけばEditにある文字列を取得することが出来そうな)
ありがとうございました
コードまで書いていただきお手数おかけしました。
ツイート | ![]() |