Как мы можем сохранить первую отображаемую строку неизменной в веб-браузере при изменении размера формы? - PullRequest
0 голосов
/ 04 июля 2019

В бланке приложения Delphi RIO имеется веб-браузер1 с Align = alClient. Содержимое веб-браузера прокручивается, поэтому первая отображаемая строка не является первой строкой содержимого веб-браузера. В этом случае при изменении размера формы первая отображаемая строка веб-браузера изменяется, что создает неудобства. Я получаю первый отображаемый htmlelement до изменения размера формы и пытаюсь прокрутить этот элемент в поле зрения после завершения изменения размера. Но первая отображаемая строка все еще изменяется при изменении размера.

FirstDisplayedElement1:IHTMLElement;
// is declared in private section of TFormText

procedure TFormText.FormCanResize(Sender: TObject; var 
  NewWidth, NewHeight: Integer; var Resize: Boolean);
begin
  Resize:=True;
  FirstDisplayedElement1 := 
    GetFirstDisplayedElement(WebBrowser1);
end;

Function  TFormText.GetFirstDisplayedElement(WebBr:TWebBrowser):IHTMLELEMENT;
var
  ChildElems :IHTMLElementCOLLECTION;
  Element:IHTMLElement;
  iHTMLDoc: IHtmlDocument2;
  Element2:IHTMLElement2;
  ElemRect:IHTMLRect;
  i:integer;
begin
  Result:=Nil;
  if Supports(WebBr.Document, IHtmlDocument2, iHTMLDoc) 
then
  begin
    ChildElems:=(WebBr.Document as IHTMLDocument2).all;
    for i := 0 to ChildElems.length - 1 do
    begin
      Element := ChildElems.item(i, varEmpty) as IHTMLElement;
      Element2 := ChildElems.item(i, varEmpty) as 
IHTMLElement2;
      ElemRect:=Element2.getBoundingClientRect;
      if ElemRect.Top > 0 then
      begin
        Result:=Element;
        Exit;
      end;
    end;
  end;
end;

procedure TFormText.FormResize(Sender: TObject);
begin
  if FirstDisplayedElement1<> NIL then 
  FirstDisplayedElement1.scrollIntoView(True);
end;

Как сохранить первую отображаемую строку без изменений?

1 Ответ

0 голосов
/ 08 июля 2019

Процедура FormCanResize вызывается три раза, когда происходит событие изменения размера. Переменная ResizeStep используется для вызова GetFirstDisplayedElement (WebBrowser1) только один раз при первом выполнении FormCanResize. Так что это работает.

ResizeStep:Integer;
FirstDisplayedElement1:IHTMLElement;
// are declared in private section of TFormText
// and are set to 0 and Nil in FormCreate

procedure TFormText.FormCanResize(Sender: TObject; var NewWidth,
  NewHeight: Integer; var Resize: Boolean);
begin
  Resize:=True;
  if ResizeStep = 0 then
  begin
    inc(ResizeStep);
    FirstDisplayedElement1:=GetFirstDisplayedElement(WebBrowser1);
  end;
  if ResizeStep > 1 then ResizeStep := 0;
end;

procedure TFormText.FormResize(Sender: TObject);
begin
  inc(ResizeStep);
  if FirstDisplayedElement1<> NIL then FirstDisplayedElement1.scrollIntoView(True);
end;

Function TFormText.GetFirstDisplayedElement(WebBr:TWebBrowser):IHTMLELEMENT;
var
  ChildElems :IHTMLElementCOLLECTION;
  Element:IHTMLElement;
  i:integer;
begin
  Result:=Nil;
  if Supports(WebBr.Document, IHtmlDocument2, iHTMLDoc) then
  begin
    ChildElems:=(iHTMLDoc.body.children AS IHTMLElementCOLLECTION);
    for i := 0 to ChildElems.length - 1 do
    begin
      Element := ChildElems.item(i, varEmpty) as IHTMLElement;
      if ((Element.offsetTop +Element.offsetHeight) > ((IHTMLDoc.body AS HTMLBODY).scrolltop)) then
      begin
        Result:=Element;
        Exit;
      end;
    end;
  end;
end;
...