COM Web Browser Window Handle Does Not Allow Autoscroll of the Window Contents


The COM web browser window handle does not autoscroll the window content.


The problem is the incorrect window handle is being passed to Snagit's COM interface (i.e. IWindowOptions). Usually the wrong handle is retrieved and getting the appropriate handle to the Web browser control is problematic.

Using Spy++, you see that the correct window, the window that actually needs to be scrolled, is the web browser control's child's child. There is a very annoying hierarchy here. When you use the Snagit application manually to do the autoscrolling, you can see that it chooses the handle of this child window, because it is the topmost thing in the center of the window where you click. Its parent's parent is the Web browser control.

Unfortunately, it is not easy to get at the appropriate handle for this window. The best practice is to get the document for the browser control and then ask the document what the handle is. However, the problem gets worse if you have frames; there will be a window containing the frames, and then each of the scrollable frames will have a handle as well. Again, the client is inside the browser which is inside the "Shell embedding" window.

      Sub SetFocusToBrowser(hBrowserHwnd As Long)
          Dim lStyle As Long
          Dim lResult As Long
          Dim hwnd As Long
          hwnd = hBrowserHwnd
          While (lResult = 0) And (hwnd <> 0)
              hwnd = GetWindow(hwnd, GW_CHILD)
              lStyle = GetWindowLong(hwnd, GWL_STYLE)
              lResult = lStyle And WS_VSCROLL
          SetFocusAPI (hwnd)
      End Sub

This Sub iterates through the children of the Web browser until it finds one that's scrollable which assumes it must be the one you're after. If there were frames, this would probably find the first frame.

A search in newsgroups can be helpful to see what others have done. For example, a quick search found this information:

Get the document object with IWebBrowser2::get_Document, query it for IOleWindow and use IOleWindow::GetWindow.

Lastly, a possible workaround to this problem is to consider passing the X,Y coordinates to Snagit's COM interface (i.e., use a point instead of a handle to specify the window). You could calculate these screen coordinates based on the location of your browser control.