Search code examples
delphidelphi-xe7twebbrowser

how to programmatically at the end of Navigation of a TWebBrowser autoscroll to desired position


I would like to know how to programmatically at the end of Navigation of a TWebBrowser (Delphi XE7) force this one to display the page from top left corner (some sort of auto scroll). For unknown reason the web browser scroll to the right at end of navigation.

I tried all sort of solutions from the net. SendMessage is one of them:

SendMessage(WebBrowser1.Handle, WM_HSCROLL, 0 , 0);

but none works. Any idea?


Solution

  • The simple and correct way is to use DOM rather than SendMessage to the WebBrowser. e.g.:

    var
      window: IHTMLWindow2;
    
    window := (WebBrowser1.Document as IHTMLDocument2).parentWindow;
    window.scroll(0, 0);
    

    Why SendMessage(WebBrowser1.Handle, ...) did not work?

    TWebBrowser.Handle is not the IE handle you should send messages to. it is a wrapper window (Shell Embedding) holding IE window with class name Internet Explorer_Server. Depending on IE version and document mode the structure could be (Use Spy++ to examine the structure):

    Shell Embedding
      Shell DocObject View
        Internet Explorer_Server <- send message to this window
    

    You could use EnumChildWindows to find Internet Explorer_Server:

    function EnumChilds(hwnd: HWND; lParam: LPARAM): BOOL; stdcall;
    const
      Server = 'Internet Explorer_Server';
    var
      ClassName: array[0..24] of Char;
    begin
      GetClassName(hwnd, ClassName, Length(ClassName));
      Result := ClassName <> Server;
      if not Result then
        PLongWord(lParam)^ := hwnd;
    end;
    
    function GetIEHandle(AWebBrowser: TWebbrowser): HWND;
    begin
      Result := 0;
      EnumChildWindows(AWebBrowser.Handle, @EnumChilds, LongWord(@Result));
    end;
    

    And send messages:

    IEHandle := GetIEHandle(WebBrowser1);
    if IEHandle <> 0 then
    begin
      SendMessage(IEHandle, WM_HSCROLL, SB_LEFT ,0);
      SendMessage(IEHandle, WM_VSCROLL, SB_TOP ,0);
    end;