Tough one !! 
Author Message
 Tough one !!

I have a problem that I've been trying to solve all day, and either I'm missing
something, or it is as complex as I think it is....

The problem is as follows. I have an ActiveX control (OCX) which is running in a
web page. From within the control, I need to get the container (browser) window
handle. No I can do this manually within the click event of the control because
if a user clicks, it sets the focus to the browser, then I can use the
'GetTheHandleOfTheForegroundWindow' type API (I can't remember the name!!).

Actually though, I want to allow it to just 'know' what the hWnd of the
container app is. This is where it gets problematic. If you use Spy++, the
control's parent is actually an intermediate window of the class
'ThunderRT6Main', and this is not a child of any of the windows within the
'IEFrame' class (the browser in my case). They do run in the same process and
thread, but have different 'top' level windows!! The closest I have been able to
get is to scan through all of the windows, and find the 'IEFrame' window which
has the same ProcessID and ThreadID, but I don't like this. If IE6's class name
changes (maybe to IEFrameFoo) - this method falls down...

It's a toughie, but I'm sure someone could help me out. Thanks in advance if you
can...

CandT



Sun, 23 Feb 2003 23:48:38 GMT  
 Tough one !!



Quote:
>The problem is as follows. I have an ActiveX control (OCX) which is
>running in a web page. From within the control, I need to get the
>container (browser) window handle.

>Actually though, I want to allow it to just 'know' what the hWnd of the
>container app is. This is where it gets problematic. If you use Spy++,
>the control's parent is actually an intermediate window of the class
>'ThunderRT6Main', and this is not a child of any of the windows within
>the 'IEFrame' class (the browser in my case). They do run in the same
>process and thread, but have different 'top' level windows!! The closest
>I have been able to get is to scan through all of the windows, and find
>the 'IEFrame' window which has the same ProcessID and ThreadID, but I
>don't like this. If IE6's class name changes (maybe to IEFrameFoo) -
>this method falls down...

Just something off the top of my head: If you know the ProcessID of your
OCX, you can probably get its parent ProcessID (via toolhelp API on 9x
and 2000, not too sure how to do that on NT). Wouldn't it be the browser's
ProcessID? If so, then just enumerate all top-level windows, use
GetWindowThreadProcessID on each until you find the browser window (well,
to think about it, you may actually find more than one).

Or try this: for each top level window, enumerate all its descendants
(I believe using EnumChildWindows (sp?)) until you find the OCX. This
should be actually pretty fast. But then you'd have to handle multiple
browser windows with the OCX in them somehow.

--
(remove a 9 to reply by email)



Mon, 24 Feb 2003 09:35:26 GMT  
 Tough one !!

Quote:

>Just something off the top of my head: If you know the ProcessID of your
>OCX, you can probably get its parent ProcessID (via toolhelp API on 9x
>and 2000, not too sure how to do that on NT). Wouldn't it be the browser's
>ProcessID? If so, then just enumerate all top-level windows, use
>GetWindowThreadProcessID on each until you find the browser window (well,
>to think about it, you may actually find more than one).

Unfortunately, there a a few top level windows (those with the desktop as
parent), which have the same process and thread ID's. In fact ALL IE windows
have the same process ID, but different thread ID's, that's why if you kill a
crashed IE with task manager, all IE windows will die... As I said in my post,
that's kinda where I got to, but then have only got the Classname 'IEFrame' to
work with - and I hate using strings as conditions...

Quote:

>Or try this: for each top level window, enumerate all its descendants
>(I believe using EnumChildWindows (sp?)) until you find the OCX. This
>should be actually pretty fast. But then you'd have to handle multiple
>browser windows with the OCX in them somehow.

If you look at Spy++ you can see all of the descendants of the IE window, but
the OCX is not one of them!!!

CandT



Mon, 24 Feb 2003 15:53:40 GMT  
 Tough one !!
You can use GetParent API until you reach the top-level window:

Dim TopWindow As Long
Dim ParentWindow As Long

   ParentWindow = UserControl.hWnd

   Do While ParentWindow
      TopWindow = ParentWindow
      ParentWindow = GetParent(ParentWindow)
   Loop

   MsgBox "Top-Level window: " & TopWindow

With IE you can also use the IServiceProvider interface to get the
InternetExplorer object, which has a hWnd property (you will need a type
library for the interface):

Public Function GetIE(ByVal Document As IUnknown) As IWebBrowserApp
Dim ServiceProvider As IServiceProvider
Dim Browser As IUnknown
Dim IID_IWebBrowserApp As GUID
Dim SID_SInternetExplorer As GUID

   ' Initialize the GUIDs
   CLSIDFromString "{0002DF05-0000-0000-C000-000000000046}",
IID_IWebBrowserApp
   CLSIDFromString "{0002DF05-0000-0000-C000-000000000046}",
SID_SInternetExplorer

   ' Get IServiceProvider interface
   Set ServiceProvider = Document

   ' Get the InternetExplorer
   Set GetIE = ServiceProvider.QueryService(SID_SInternetExplorer,
IID_IWebBrowserApp)

End Function

IEWindow = GetIE(UserControl.Parent).hWnd

--
Eduardo A. Morcillo
http://www.domaindlx.com/e_morcillo



Mon, 24 Feb 2003 17:35:17 GMT  
 Tough one !!

Quote:
> If you look at Spy++ you can see all of the descendants of the IE window,
but
> the OCX is not one of them!!!

The control is a child of the IE window (the class name is
ThunderRT?UserControl). If you didn't find any window with that class name
then you are using a windowless control, so don't expect it to be a child
window!

--
Eduardo A. Morcillo
http://www.domaindlx.com/e_morcillo



Mon, 24 Feb 2003 18:09:37 GMT  
 Tough one !!
Add a reference to microsoft internet controls (shdocvw.dll)

IN code:

Define an IE object as Internet explorer
Define a Shell object as  ShellWindows

Loop through each occurrence of shellwindows until you find an internet
explorer
then check the name until it matches your component.

set the IE to this object, then you can get it's handle.

I've got code that does this, but I don't have it with me, it's at work so
this is all from memory.
If you need it let me know.

Iguana



Tue, 25 Feb 2003 07:40:05 GMT  
 
 [ 6 post ] 

 Relevant Pages 

1. A tough one! Import password protected VBA

2. Running Native Access commands in VB..Tough one

3. tough one for you experts

4. A tough one.. animating buttons

5. This is a tough one....

6. Tough one!!!

7. tough one for you experts

8. tough one for you experts out there...

9. This is a tough one ( ActiveX Dll problem )

10. Kind of a tough one...

11. Tough one: ActiveX control errors w/Collections

12. tough one

 

 
Powered by phpBB® Forum Software