gchippie

hi folks,

when a document completes loading in a new tab,

my bho gets notified via DISPID_DOCUMENTCOMPLETE.

how can i get the window handle for the tab window

i've tried the EnumChildWindows/IsWindowVisible combo but it's not always reliable. it would seem IE7 has the handle but how to get it

any ideas



Re: Internet Explorer Extension Development window handle for active tab

Dave Massy

From where are you trying to access the tab information You shoudl be able to make use of accessibility interfaces to access the tabs.

Thanks
-Dave






Re: Internet Explorer Extension Development window handle for active tab

John Sudds

Does the following code help This is a general-use replacement for the IWebBrowser2::get_HWND method that is supposed to work the same in IE6 and IE7.

IServiceProvider* psp;

HRESULT hr = pwb2->QueryInterface( IID_IServiceProvider, (void**)&psp );

if( SUCCEEDED(hr) && psp )

{

IOleWindow* pow;

psp->QueryService( SID_SShellBrowser, IID_IOleWindow, (void**)&pow );

if( SUCCEEDED(hr) && pow)

{

HWND hWnd = NULL;

hr = pow->GetWindow( &hWnd );

if( SUCCEEDED(hr) && hWnd )

{

//hWnd is the handle of TabWindowClass

}

pow->Release();

}

psp->Release();

}






Re: Internet Explorer Extension Development window handle for active tab

gchippie

from inside my event handler:

STDMETHOD(Invoke)(DISPID, REFIID, LCID, WORD, DISPPARAMS*,

VARIANT*, EXCEPINFO*, UINT*);

and when the document completes loading,

i need to get the window handle of the tab.

thanks...





Re: Internet Explorer Extension Development window handle for active tab

gchippie

thanks for your response.

yes, that code does work but i need the window handle to the Tab window (specifically
class of "Internet Explorer_Server").
as you point out, the code returns TabWindowClass.

i guess the question is: what is the relationship between the two classes

thanks for your input...





Re: Internet Explorer Extension Development window handle for active tab

gchippie

answering myself as well as to john...

Internet Explorer_Server class is the child of Shell DocObject View,
which itself is a child of TabWindowClass. So tracking down this is not bad,
but the my real problem is this....

when i receive DISPID_DOCUMENTCOMPLETE event as i open new tabs,
once in a while, the Internet Explorer_Server window does not exist yet.
i determine this via the EnumChildWindows.

it looks to me like a timing issue but within this event callback thread,
what can i do

thanks for any thoughts...
g





Re: Internet Explorer Extension Development window handle for active tab

gchippie

here's what i had to do:
using the TabWindowClass handle, find its child ShellDocObjectView
via EnumChildWindows. then, get its child via GetWindow.
for some reason, EnumChildWindows to locate the tab window class
Internet Explorer_Server is not completely reliable.
about 20% of the time, the tab window does not exist.

so i'm guessing it's a timing issue between IE7 thread creating the window and
its DocumentComplete callback into bho's routine.





Re: Internet Explorer Extension Development window handle for active tab

Qawi

Hey gchippie >>

It seems like you know how to locate the active IE tab
I just want to be able to do that and get the urllocation of it.

Can you help me
If you are not up to writing a complete workin code it's okay, but maby some lines of code

I am not used to this type of programming:(

thanks in advanced!






Re: Internet Explorer Extension Development window handle for active tab

gchippie

per my previous comments,
i'm using john's code above to get the tab window handle,
find its child window via EnumChildWindows for the handle to
the docObjView, and finally get its child window which is the tab.

for what it's worth, here's my code snippet:
::EnumChildWindows(htabwnd, cTabWndEnumProc, reinterpret_cast<LPARAM>(&hsdovwnd));
if (hsdovwnd) {
hbwnd = ::GetWindow(hsdovwnd, GW_CHILD);
if (hbwnd != 0) {// but make sure the window is proper class
TCHAR wclass[MAX_PATH];
wclass[0] = 0;
::GetClassName(hbwnd, wclass, MAX_PATH-1);
if (_tcscmp(wclass, _T("Internet Explorer_Server")))
hbwnd = 0;
}
}





Re: Internet Explorer Extension Development window handle for active tab

JohnBoy456

I would like to find the tab id as well and was wondering if you could post your code and John's code (and any other code necessary to get this to work). Greatly appreciated!



Re: Internet Explorer Extension Development window handle for active tab

Varun21

Not a coder yet into this domain but I'm a programmer still.

1) What language are you using to create these BHOs
2) Extending the code on this page is there a possibility of changing the color for each tab separately

Regards







Re: Internet Explorer Extension Development window handle for active tab

NathanInNashville

Hi John,

I have been working through the tutorial to Create a HelloWorld BHO, and I am doing for IE7, but the tutorial is obviously designed pre-tab. I think I understand what you are doing here, but my goal is to get at the DOM in a specific tab, and manipulate it IF the tab is displaying any of the URL's stored in a configuration file. I am not dealing with hWnds but ATL smart pointers.

I have implemented all the code in the tutorial by hand rather than cut and paste to get my chops up. The article is "Building Browser Helper Objects with Visual Studio 2005" which I just noticed that you wrote with Tony Schreiner!!

The problem is in IE 7 when I run it in debug, I have a breakpoint set on :SurprisenDocumentComplete and the check for the top-level browser that was stored in m_spWebBrowser being the caller is NEVER true. I am supposing this is because the top level browser being loaded is the tab window and not the WebBrowser itself...

Can u give me some guidance as to how to get at or recognize the active tab control in the tests in OnDocumentComplete

Maybe I can grok it out from this thread yall have left, but some specific help would be greatly appreciated.

Thanks,

Nathan (Now in Huntsville AL)





Re: Internet Explorer Extension Development window handle for active tab

John Lister

I may have misunderstood...

Each tab has its own WebBrowser2 object and a new BHO is created for each tab. I'm not sure what you mean by "top-level" WebBrowser, i'm guessing the value obtained in SetSite - this should be unique for each tab or do you mean the HWND - having looked further up the thread

In IE7 the HWND obtained is for the window, see the code earlier on to obtain it for the tab.

If the BHO is associated with a toolbar/button then it is useful to know the current tab.. I get around this, by storing a pointer to the active BHO and update it by catching the "windowStateChanged" event of DWebBrowser2Events. When the userVisible flag is set, the current object is that of the active tab.

To further complicate things each window counts separately, so i store a list of windows and their current BHO and track which is active matching the window to the toolbar/button





Re: Internet Explorer Extension Development window handle for active tab

NathanInNashville

Hello John,

Thanks for responding.

I may be misunderstanding why OnDocumentComplete never sees the stored "Top Level" BrowserInterface. The fact remains that when I run the tutorial code in debug from devenv.exe using IE7 as a host, it never recognizes the completion of the main browser to proceed to remove the images.

My goal is to master this technique to create a web browser helper object that will recognize when certain URL's have been loaded, and parse data out of completed forms when the form is submitted to a third party.

In the following function implementatio the test for top level browser is NEVER true...

void STDMETHODCALLTYPE CHelloWorldBHO:SurprisenDocumentComplete(IDispatch *pDisp, VARIANT *pvarURL)
{
  HRESULT hr = S_OK;

  // Query for the IWebBrowser2 interface.
  CComQIPtr<IWebBrowser2> spTempWebBrowser = pDisp;

  // Is this event associated with the top-level browser 
  if (spTempWebBrowser && m_spWebBrowser &&
    m_spWebBrowser.IsEqualObject(spTempWebBrowser))
  {
    // Get the current document object from browser...
    CComPtr<IDispatch> spDispDoc;
    hr = m_spWebBrowser->get_Document(&spDispDoc);
    if (SUCCEEDED(hr))
    {
      // ...and query for an HTML document.
      CComQIPtr<IHTMLDocument2> spHTMLDoc = spDispDoc;
      if (spHTMLDoc != NULL)
      {
        // Finally, remove the images.
        RemoveImages(spHTMLDoc);
      }
    }
  }
}
 
Thanks for your help.
 
Nathan in Huntsville, AL




Re: Internet Explorer Extension Development window handle for active tab

John Lister

Apologies i'd completely forgotten about frames Smile

Unfortunately for you, that works fine for me in IE7..

I'm guessing you have

CComQIPtr <IWebBrowser2> m_spWebBrowser;

and in Setsite something similar

m_spWebBrowser= pUnkSite;


I'm guessing you are using the ATL EventSink implementation One thing i've done is right my own IDispatch::Invoke as i found the ATL version mangled some of the functions. I have something like this:

STDMETHODIMP CPriceGoblinBHO::Invoke(DISPID dispidMember, REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS* pDispParams, VARIANT* pvarResult, EXCEPINFO* pExcepInfo, UINT* puArgErr) {

switch (dispidMember) {
case DISPID_DOCUMENTCOMPLETE:
if (pDispParams->cArgs == 2)
documentComplete(pDispParams->rgvarg[1].pdispVal, pDispParams->rgvarg[0].pvarVal);
break;
}
}

with documentComplete being the same as yours...

One thing to check is to make sure that pDisp, m_spWebBrowser are set to valid/real looking values