Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How I can get information about the scrollbars of an Webbrowser control instance or the IE Webrowser?

I need to get information about the scrollbars (position, size, visibility) of a Webbrowser control of an external application, I tried using the GetScrollBarInfo function from my previous question, but the function always return false, I checked this function with another applications and works fine , but not with the IE or the Webbrowser control. So how I can get information about the scrollbars of an Webbrowser control instance or the IE Webbrowser?

like image 957
Salvador Avatar asked Jan 28 '26 18:01

Salvador


1 Answers

You can send WM_HTML_GETOBJECT message to "Internet Explorer_Server" class window of an external application to obtain IHtmlDocument2, then using IServiceProvider you can obtain IWebBrowser2 interface.
Here is some sample code in Delphi:

uses
  ActiveX, MSHTML;

type
  TObjectFromLResult = function(LRESULT: lResult; const IID: TIID;
    wParam: wParam; out pObject): HRESULT; stdcall;

function GetIEFromHWND(WHandle: HWND; var IE: IWebbrowser2): HRESULT;
var
  hInst: HWND;
  lRes: Cardinal;
  Msg: Integer;
  pDoc: IHTMLDocument2;
  ObjectFromLresult: TObjectFromLresult;
begin
  Result := S_FALSE;
  hInst := LoadLibrary('Oleacc.dll');
  @ObjectFromLresult := GetProcAddress(hInst, 'ObjectFromLresult');
  if @ObjectFromLresult <> nil then
  try
    Msg := RegisterWindowMessage('WM_HTML_GETOBJECT');
    SendMessageTimeOut(WHandle, Msg, 0, 0, SMTO_ABORTIFHUNG, 1000, lRes);
    Result := ObjectFromLresult(lRes, IHTMLDocument2, 0, pDoc);
    if Result = S_OK then
      (pDoc.parentWindow as IServiceprovider).QueryService(
        IWebbrowserApp, IWebbrowser2, IE);
  finally
    FreeLibrary(hInst);
  end;
end;

procedure TForm1.Button1Click(Sender: TObject);
var
  Wnd, WndChild: HWND;
  IE: IWebBrowser2;
  Document: IHtmlDocument2;
  ScrollTop, ScrollLeft: Integer;
begin
  Wnd := FindWindow('IEFrame', nil); // top level IE
  if Wnd = 0 then Exit;
  WndChild := FindWindowEX(Wnd, 0, 'Shell DocObject View', nil);
  if WndChild = 0 then Exit;
  WndChild := FindWindowEX(WndChild, 0, 'Internet Explorer_Server', nil);
  if WndChild = 0 then Exit;

  GetIEFromHWnd(WndChild, IE);
  if IE <> nil then
  begin
    ShowMessage(IE.LocationURL);
    Document := IE.Document as IHtmlDocument2;
    ScrollTop := ((Document as IHTMLDocument3).documentElement as IHTMLElement2).scrollTop;
    ScrollLeft := ((Document as IHTMLDocument3).documentElement as IHTMLElement2).scrollLeft;
    ShowMessage(Format('%d;%d', [ScrollTop, ScrollLeft]));

    // visible|hidden|scroll|auto|no-display|no-content
    ShowMessage(OleVariant(Document).documentElement.currentStyle.overflowX);
    ShowMessage(OleVariant(Document).documentElement.currentStyle.overflowY);
  end;
end;

Edit: when page uses <!DOCTYPE> directive to switch IE6 to strict standard-compliant mode use document.documentElement. (IHTMLDocument3) in pre-standard mode, the body represents the scrollable region, so you can retrieve the scroll position with document.body.scrollTop. In standard mode, HTML element is scrollable, so you should use document.documentElement.scrollTop.

If document.documentElement.clientWidth <> 0 use the documentElement element for properties else use the body element.
Useful properties related to scroll information are also clientHeight, scrollWidth, scrollHeight.

like image 105
kobik Avatar answered Jan 30 '26 09:01

kobik



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!