Home | Contact Us | FAQ | Search & Site Map | Link to Us
Sign In | Join | Other 45 Sites in Network
Home
Discussion GroupsVB SyntaxEnterprise DevelopmentDatabase AccessControlsCOMWin APICrystal ReportDeploymentGeneralGeneral 2
Related Topics
VB.NET / ASP.NETMS SQL ServerMS AccessOther Database ProductsMore Topics ...

VB Forum / Win API / September 2008



Tip: Looking for answers? Try searching our database.

Scrolling Scrollbar in IE6

Thread view: 
Enable EMail Alerts  Start New Thread
Thread rating: 
Jack B. Pollack - 03 Sep 2008 13:21 GMT
Hi,

Using VB6 and trying to interact with an instance of IE6.

I need my program to be able to scroll the scrollbars in IE. I suspect that
I can use SetScrollPos API, but how do I get the hwnd of the scrollbar (I
can get the hwnd of the main IE window, but not the Scrollbar)?

Thanks
mayayana - 03 Sep 2008 14:15 GMT
You asked about accessing the window via API, but I
wonder if you might prefer going through the document
since you want to scroll the page. There are at
least two ways I know of to get the document
object. From there you should be able to use
document.body.scrolltop to get/set the scroll position.

Method 1: Set a reference to Microsoft Shell Controls
and Automation. Get a collection of open IE and Explorer
windows from Shell.Windows. Each of those is returned
as an IE object. (Even the folders!) Use properties like
LocationURL to find your window in a For/Each loop and
then access the IE.document object.

Method 2: Given your parent window hWnd, use
EnumChildWindows to find the subwindow of class
"Internet Explorer_Server". That's the actual
browser. Send that hWnd to the following function
to return the document object. (This function works
with any window of class "Internet Explorer_Server"
at least as far back as Win98.)

Two notes:
1) You need to set a reference to mshtml.tlb for
DOM ops and objects.
2)IE7 introduced tabs so that you may have multiple
"Internet Explorer_Server" windows in your Enum.
Likewise if the page has frames.

'--- function to return document object from hWnd -----

Type UUID
Data1 as Long
Data2 as Integer
Data3 as Integer
Data4(0 to 7) as Byte
End Type

Private Const SMTO_ABORTIFHUNG = &H2
Private Declare Function RegisterWindowMessage Lib "user32" Alias
"RegisterWindowMessageA" (ByVal lpString As String) As Long
Private Declare Function SendMessageTimeout Lib "user32" Alias
"SendMessageTimeoutA" (ByVal hWnd As Long, ByVal msg As Long, ByVal wParam
As Long, lParam As Any, ByVal fuFlags As Long, ByVal uTimeout As Long,
lpdwResult As Long) As Long
Private Declare Function ObjectFromLresult Lib "oleacc" (ByVal lResult As
Long, riid As UUID, ByVal wParam As Long, ppvObject As Any) As Long

Private Function GetIEDoc(ByVal H1 As Long, Success As Boolean) As
IHTMLDocument
 Dim IID_IHTMLDocument2 As UUID
 Dim LMsg As Long, LRes As Long, LRet As Long, H2 As Long
      Success = False
        H2 = GetIEWindow(H1)
          If (H2 = 0) Then Exit Function

 LMsg = RegisterWindowMessage("WM_HTML_GETOBJECT")
 LRet = SendMessageTimeout(H2, LMsg, 0, 0, SMTO_ABORTIFHUNG, 1000, LRes)
           If LRes = 0 Then Exit Function

     With IID_IHTMLDocument2
        .Data1 = &H332C4425
        .Data2 = &H26CB
        .Data3 = &H11D0
        .Data4(0) = &HB4
        .Data4(1) = &H83
        .Data4(2) = &H0
        .Data4(3) = &HC0
        .Data4(4) = &H4F
        .Data4(5) = &HD9
        .Data4(6) = &H1
        .Data4(7) = &H19
     End With

     LRet = ObjectFromLresult(LRes, IID_IHTMLDocument2, 0, GetIEDoc)
    If LRet = 0 Then Success = True
End Function

> Using VB6 and trying to interact with an instance of IE6.
>
[quoted text clipped - 3 lines]
>
> Thanks
Jack B. Pollack - 03 Sep 2008 14:24 GMT
>     You asked about accessing the window via API, but I
> wonder if you might prefer going through the document
[quoted text clipped - 82 lines]
> >
> > Thanks

Thanks for your reply. I'll try this when I get back from this evening. I'll
post back if I have problems
mayayana - 03 Sep 2008 15:47 GMT
One note on that. I had copied and pasted the function
from my own code and later realized that it was connected
with a specific project. Notice there's a call to GetIEWindow.
That's calling an EnumChildWindows function to get the
Internet Explorer_Server subwindow. (The incoming H1
parameter was an IE window hWnd.) I'm posting
here a corrected version where the incoming H1 parameter
is the hWnd of the Internet Explorer_Server subwindow:

Private Function GetIEDoc(ByVal H1 As Long, Success As Boolean) As
IHTMLDocument
 Dim IID_IHTMLDocument2 As UUID
 Dim LMsg As Long, LRes As Long, LRet As Long
      Success = False

 LMsg = RegisterWindowMessage("WM_HTML_GETOBJECT")
 LRet = SendMessageTimeout(H1, LMsg, 0, 0, SMTO_ABORTIFHUNG, 1000, LRes)
           If LRes = 0 Then Exit Function

     With IID_IHTMLDocument2
        .Data1 = &H332C4425
        .Data2 = &H26CB
        .Data3 = &H11D0
        .Data4(0) = &HB4
        .Data4(1) = &H83
        .Data4(2) = &H0
        .Data4(3) = &HC0
        .Data4(4) = &H4F
        .Data4(5) = &HD9
        .Data4(6) = &H1
        .Data4(7) = &H19
     End With

     LRet = ObjectFromLresult(LRes, IID_IHTMLDocument2, 0, GetIEDoc)
    If LRet = 0 Then Success = True
End Function

 There's also more involved sample code, if you
need it, here. (It's part of a Shell Object/ ShellFolderView
package of sample code.) :

www.jsware.net/jsware/vbcode.php5#shlop

> > '--- function to return document object from hWnd -----
> >
[quoted text clipped - 57 lines]
> Thanks for your reply. I'll try this when I get back from this evening. I'll
> post back if I have problems
Jack B. Pollack - 04 Sep 2008 01:09 GMT
As you suspected, I am still having problems with the function GetIEDoc
Wahat doed your EnumChildWindows function look like?

Thanks again

>    One note on that. I had copied and pasted the function
> from my own code and later realized that it was connected
[quoted text clipped - 104 lines]
> I'll
> > post back if I have problems
mayayana - 04 Sep 2008 03:07 GMT
> As you suspected, I am still having problems with the function GetIEDoc
> Wahat doed your EnumChildWindows function look like?

  You can see it all in the download I linked, though
that project also has a few other things going on.
EnumChildWindows uses a callback, so it's a bit
awkward. In the following example I use two public
variables that are visible from both the enum function
and the callback function:

Public HCur As Long
Public sClassName As String

You also need these declares:

Private Declare Function GetClassName Lib "user32.dll" Alias "GetClassNameA"
(ByVal hWnd As Long, ByVal lpClassName As String, ByVal nMaxCount As Long)
As Long
Private Declare Function EnumChildWindows Lib "user32" (ByVal hWndParent As
Long, ByVal lpEnumFunc As Long, lParam As Long) As Long

 Then, assuming that you have an IE hWnd, you
use the following to get the actual browser window
from it:

Private Function GetIEServerWindow(ByVal H1 As Long)
  Dim LRet As Long
   HCur = 0
   GetIEServerWindow = 0
   sClassName = "Explorer_Server" ' "Internet Explorer_Server"
   LRet = EnumChildWindows(H1, AddressOf EnumChildProc, 0)
   GetIEServerWindow = HCur  '-- either 0 or handle of browser.
End Function

Public Function EnumChildProc(ByVal hWnd As Long, lParam As Long) As Long
  Dim s2 As String
    s2 = GetWinClass(hWnd)
   If InStr(1, s2, sClassName, 1) > 0 Then
     HCur = hWnd
     EnumChildProc = 0
   Else
     EnumChildProc = 1
   End If
End Function

 Those two functions work together. You send the IE
hWnd into GetIEServerWindow, which calls EnumChildWindows
on that. EnumChildProc is the callback function.
EnumChildWindows will call EnumChildProc for each child
window. EnumChildProc then gets the class name of that
window. If the class name is "Internet Explorer_Server"
it sets the public HCur to the hWnd of that window and
returns 0, causing the enum to quit. Otherwise it returns
1, signaling the enum to continue. By the time it's done
hCur is either a browser window hWnd or 0, if there was
no I E_Server window in the hierarchy.

 The following shows getting the class name of a window
from the hWnd:

Public Function GetWinClass(ByVal H1 As Long) As String
 Dim sBuf As String
 Dim LRet As Long
    On Error Resume Next
      GetWinClass = ""
   sBuf = String$(256, 0)
   LRet = GetClassName(H1, sBuf, Len(sBuf))
    If (LRet > 0) Then GetWinClass = Left$(sBuf, LRet)
End Function

So you send the IE hWnd to GetIEServerWindow and
if non-zero is returned then you send that to GetIEDoc.
That then returns a document object and you're
"ready to roll".  :)

  I'm assuming you have an IE hWnd to start. If not
you'll need to use Shell Object or basic top-level window
enumeration to get it.

  If this all seems confusing you might try starting IE
and then running Spy++. That will let you see the
window hierarchy and see how the actual browser that
has the document, Internet Explorer_Server, is not the
top-level window. I think something like "IEFrame" is
the class name of the top window with the chrome.
Jack B. Pollack - 04 Sep 2008 13:31 GMT
> > As you suspected, I am still having problems with the function GetIEDoc
> > Wahat doed your EnumChildWindows function look like?
[quoted text clipped - 81 lines]
> top-level window. I think something like "IEFrame" is
> the class name of the top window with the chrome.

Thanks. Think I got it.
 
Sign In
Join
My Latest Posts
My Monitored Threads
My Blog
My Photo Gallery
My Profile
My Homepage

Start New Thread
Enable EMail Alerts
Rate this Thread



©2008 Advenet LLC   Privacy Policy - Terms of Use
This website includes both content owned or controlled by Advenet as well as content owned or controlled by third parties.