Click to See Complete Forum and Search --> : Howto grab the URL address of the active IE?


Saxonika
November 20th, 2005, 09:54 AM
hello,

how can i grab the url address of the active internet explorer instance? my application can be run from the IE toolbar. when the application then starts, i like to grab the URL address from this active IE which is in the address bar.

golanshahar
November 20th, 2005, 10:05 AM
one way to do it is by using Accessibility SDK.
look at this link: Active Accessibility 2.0 SDK Tools (http://www.microsoft.com/downloads/details.aspx?FamilyId=3755582A-A707-460A-BF21-1373316E13F0&displaylang=en)

download the AccExplorer32.exe and see that you will be able to grab the text ( it is similar to use spy++ tool )

when you will see its ok and this is what you looking for, download the sdk and use it ;)

Cheers

Saxonika
November 21st, 2005, 03:03 PM
hm but there are only executables? or do i miss understand you? well, btw i found a delphi code which makes that what i need but i can't translate it to C++ (using Borland C++ Builder) does anyone know how to translate it to C++ ? here is it:

uses
ActiveX, Shdocvw_tlb, MSHTML_TLB;

type
TObjectFromLResult = function(LRESULT: lResult; const IID: TIID;
wParam: wParam; out pObject): HRESULT;
stdcall;


function GetIEFromHWND(WHandle: HWND; var IE: IWebbrowser2): HRESULT;
var
hInst: HWND;
lRes: Cardinal;
Msg: Integer;
pDoc: IHTMLDocument2;
ObjectFromLresult: TObjectFromLresult;
begin
hInst := LoadLibrary('Oleacc.dll'); @ObjectFromLresult :=
GetProcAddress(hInst, 'ObjectFromLresult');
if @ObjectFromLresult <> nil then
begin
try
Msg := RegisterWindowMessage('WM_HTML_GETOBJECT');
SendMessageTimeOut(WHandle, Msg, 0, 0, SMTO_ABORTIFHUNG, 1000, lRes);
Result := ObjectFromLresult(lRes, IHTMLDocument2, 0, pDoc);
if Result = S_OK then
(pDoc.parentWindow as IServiceprovider).QueryService(IWebbrowserApp,
IWebbrowser2, IE);
finally
FreeLibrary(hInst);
end;
end;
end;

function GetActiveIEURL: string;
var
Document: IHtmlDocument2;
IE: IWebBrowser2;
Wnd: HWND;
WndChild: HWND;
begin
Wnd := GetForeGroundWindow;
WndChild := FindWindowEX(Wnd, 0, 'Shell DocObject View', nil);
if WndChild <> 0 then
begin
WndChild := FindWindowEX(WndChild, 0, 'Internet Explorer_Server', nil);
if WndChild <> 0 then
begin
//Get Iwebbrowser2 from Handle
GetIEFromHWnd(WndChild, IE);
if IE <> nil then
begin
Result := IE.LocationURL;
// Document := IE.Document as IHtmlDocument2;
end;
end;
end;
end;

procedure TForm1.Timer1Timer(Sender: TObject);
begin
Caption := GetActiveIEURL;
end;

or has anyone a C++ code snippet?

golanshahar
November 21st, 2005, 03:27 PM
hm but there are only executables? or do i miss understand you?

not only exe file look at the right side of the page there is: "Related Resources" and there is the link to the SDK.


or has anyone a C++ code snippet?

here is a code using accessibility to get the address from the edit box of IE.


::CoInitialize(0);
HWND hwnd = // put here the handle to the window of the address bar ( the edit box)
IAccessible *ac =0 ;
::AccessibleObjectFromWindow( hwnd,OBJID_CLIENT ,IID_IAccessible , (void **)&ac );

if ( ac == 0 )
return;

char szAddressBar[MAX_PATH]={0};
VARIANT var;
::VariantInit( &var );
var.vt = VT_I4;
var.lVal = CHILDID_SELF;
BSTR tmp;
if ( ac->get_accValue( var,&tmp ) == S_OK )
{
_bstr_t tmpName( tmp, false );
::strcpy( szAddressBar, tmpName );
// szAddressBar has the string of the address bar
}
::VariantClear(&var);
::CoUninitialize();


dont forget to add:


#include <oleacc.h>
#include <comdef.h>

at the top.

and you should add the oleacc.lib to the link.

Cheers

Saxonika
November 21st, 2005, 03:51 PM
thank you! but i got a linking error :( is there any lib missing?

[Linker Fehler] Unresolved external '__stdcall _com_issue_error(long)'

[Linker Fehler] Unresolved external '__stdcall _com_util::ConvertBSTRToString(wchar_t *)'

golanshahar
November 21st, 2005, 04:01 PM
thank you! but i got a linking error :( is there any lib missing?

[Linker Fehler] Unresolved external '__stdcall _com_issue_error(long)'

[Linker Fehler] Unresolved external '__stdcall _com_util::ConvertBSTRToString(wchar_t *)'

the only lib you need to add is oleacc.lib ( i wrote you in my post ) did you add it?

PS: so are you the one who using cpp builder? :D

Cheers

Saxonika
November 21st, 2005, 04:03 PM
"so are you the one who using cpp builder?" <--- :D

well i have added the lib you have wrote. if i comment the line out:

_bstr_t tmpName(tmp, false);
::strcpy(szAddressBar, tmpName);

the linking problem is solved. Hmm..

golanshahar
November 21st, 2005, 04:07 PM
"so are you the one who using cpp builder?" <--- :D

:p :D


well i have added the lib you have wrote. if i comment the line out:

_bstr_t tmpName(tmp, false);
::strcpy(szAddressBar, tmpName);

the linking problem is solved. Hmm..

well you dont have to use that _bstr_t i just used it to convert BSTR to the char *. there are other ways that you can do it.

Cheers

Saxonika
November 21st, 2005, 05:09 PM
okay i have changed it now. but i dont get the url :)


::CoInitialize(0);
HWND hwnd = FindWindow("Edit", "Google - Microsoft Internet Explorer");
IAccessible *ac = 0;
::AccessibleObjectFromWindow(hwnd, OBJID_CLIENT, IID_IAccessible, (void**)&ac);
if(ac == 0)
{
return;
}
char szAddressBar[MAX_PATH] = {0};
VARIANT var;
::VariantInit(&var);
var.vt = VT_I4;
var.lVal = CHILDID_SELF;
BSTR tmp;
if(ac->get_accValue(var, &tmp) == S_OK)
{
String tmpName = WideCharToString(tmp);
::strcpy(szAddressBar, tmpName.c_str());
MessageBox(NULL, szAddressBar, "", 48);
}
::VariantClear(&var);
::CoUninitialize();


the messagebox is not shown. What do i make wrong?
EDIT: oh, the handle is NULL. But i dont understand why. I see with Spy++ that the classname is Edit and a IE instance to google is also active. Hm?

golanshahar
November 21st, 2005, 05:27 PM
first of all this is a bug:

HWND hwnd = FindWindow("Edit", "Google - Microsoft Internet Explorer");

this will return NULL since ::FindWindow(..) cannot find Child window.

what you need to do is locate the parent window and look for the child window.

you can use the next code:


HWND g_hEdit = 0;
BOOL CALLBACK EnumChildProc(HWND hwnd, LPARAM lParam)
{
char szClass[MAX_PATH]={0};
::GetClassName(hwnd,szClass,sizeof(szClass));
if ( ::strcmp(szClass,"Edit") == 0 )
g_hEdit = hwnd;

return TRUE;
}

void Func( )
{
HWND hParent = ::FindWindow(0, "Google - Microsoft Internet Explorer");
::EnumChildWindows(hParent,EnumChildProc,0);

if ( g_hEdit == 0 )
return;
// here is the rest of the code, work on g_hEdit
:
:
}


BTW: its not recomanded to look for hwnd with hardcoded caption when the window tend to change it like IE i hope its just for the test...;)

about this code:


String tmpName = WideCharToString(tmp);



i am not familiar with this function i hope is ok.

Cheers

kkez
November 21st, 2005, 06:01 PM
Yes, actually there's no need to use the Accessibility SDK since the address bar is a child of the rebar which is a child of the main ie window. :)

golanshahar
November 21st, 2005, 06:17 PM
Yes, actually there's no need to use the Accessibility SDK since the address bar is a child of the rebar which is a child of the main ie window. :)

you do need to use Accessibitly fucntions in order to get the text from there.
find the HWND is one thing but getting the text is another.

of course there are other methods to get the text like Hooking and such. but i think using accessibilty is easy and safe one. ;)

Cheers

Saxonika
November 22nd, 2005, 03:12 AM
thank you golanshahar now its like this


//---------------------------------------------------------------------------
HWND g_hEdit = 0;
BOOL CALLBACK EnumChildProc(HWND hwnd, LPARAM lParam)
{
char szClass[MAX_PATH] = {0};
::GetClassName(hwnd, szClass, sizeof(szClass));
if(::strcmp(szClass, "Edit") == 0)
{
g_hEdit = hwnd;
}
return TRUE;
}
//---------------------------------------------------------------------------
void Func()
{
HWND hParent = ::FindWindow(0, "Google - Microsoft Internet Explorer");
::EnumChildWindows(hParent, (WNDENUMPROC)EnumChildProc, 0);
if(g_hEdit == 0)
{
return;
}
::CoInitialize(0);
IAccessible *ac = 0;
::AccessibleObjectFromWindow(g_hEdit, OBJID_CLIENT, IID_IAccessible, (void**)&ac);
if(ac == 0)
{
return;
}
char szAddressBar[MAX_PATH] = {0};
VARIANT var;
::VariantInit(&var);
var.vt = VT_I4;
var.lVal = CHILDID_SELF;
BSTR tmp;
if(ac->get_accValue(var, &tmp) == S_OK)
{
String tmpName = WideCharToString(tmp);
::strcpy(szAddressBar, tmpName.c_str());
MessageBox(NULL, szAddressBar, "", 48);
}
::VariantClear(&var);
::CoUninitialize();
}
//---------------------------------------------------------------------------


is this right liek that? i have also added (WNDENUMPROC). Now the messagebox is shown with the address. and yes, the hardcoded string of title was just for test, because i dont know how to find the current active IE and without to know hows the title truly :D any idea?

golanshahar
November 22nd, 2005, 06:34 AM
thank you golanshahar

Your welcome :)


is this right liek that?
i have also added (WNDENUMPROC). Now the messagebox is shown with the address.

yeah it looks ok.


and yes, the hardcoded string of title was just for test, because i dont know how to find the current active IE and without to know hows the title truly :D any idea?

one thing you can do is use ::FindWindow(..) on the class name of ie.

HWND hIE = ::FindWindow("IEFrame",0);


another way is to use ::EnumWindows(..) and look for all IEFrame class names when you find one you can use ::GetForegroundWindow(..) to check if this is the active one:


HWND g_hParent = 0;
BOOL CALLBACK EnumWindowsProc( HWND hwnd, LPARAM lParam)
{
char szClass[MAX_PATH]={0};
::GetClassName(hwnd,szClass,sizeof(szClass));
if ( ::strcmp(szClass,"IEFrame") == 0 )
{
if ( ::GetForegroundWindow() == hwnd )
g_hParent = hwnd;
}

return TRUE;
}

void Func ()
{
::EnumWindows(EnumWindowsProc,0);
if (g_hParent == 0 )
return;
}


hope it helps

Cheers

Saxonika
November 22nd, 2005, 07:03 AM
very very much thanks golanshahar! :D

its enough with ::FindWindow("IEFrame",0);
is this why, the application is run from IE direct? because from every instance where i start the application, its still the right address sniffed. if i start the application without IE then its the last instance where i get the address from... :)

edit: i have now just replaced

HWND hParent = ::FindWindow(0, "Google - Microsoft Internet Explorer");

with

HWND hParent = ::FindWindow("IEFrame",0);

golanshahar
November 22nd, 2005, 09:45 AM
very very much thanks golanshahar! :D

Glad i could help.


its enough with ::FindWindow("IEFrame",0);
is this why, the application is run from IE direct? because from every instance where i start the application, its still the right address sniffed. if i start the application without IE then its the last instance where i get the address from... :)


Sorry but i didnt understand the question :confused:

Cheers

rajeshsubramani
September 27th, 2007, 01:35 AM
Hi Sax & golan,

i want to grab the URL from the active IE using c++. so send me the solution file , becoz i am newer to c++ coding ...i dont know where to place the above coding.
Thanx in advance...

regards,
Rajesh S

rajeshsubramani
September 27th, 2007, 03:25 AM
i got error C2065: 'OBJID_CLIENT' : undeclared identifier..how should i fix this....?

golanshahar
September 27th, 2007, 07:11 AM
Hi Sax & golan,

i want to grab the URL from the active IE using c++. so send me the solution file , becoz i am newer to c++ coding ...i dont know where to place the above coding.
Thanx in advance...

regards,
Rajesh S

Create new project and look at post #4 its very clear what you need to include in your project.


Cheers

thas_svk
September 14th, 2008, 03:26 PM
Hi saxonika,

could you pls pass me the c++ full code to grab the url address of the active IE.


Thanks in advance,
thas