1

I have a form with several splitters and panels. In the middle is a panel that ends up with a TWebBrowser set to align alClient.

In the past this has worked well. However, on Windows 7 with Internet Explorer 8 the the browser is not correctly resized. Everything else (i.e. the panels) are the correct size, just not the web browser. Sometimes when you click into the browser, or more often when you scroll the browser will jump to the correct size. That does not happen 100% of the time though.

I'm trying to deal with the resize directly and force the control to change size. I can't seem to find a method that makes any difference (i.e. .Invalidate; .Repaint; .Update;)

TWebBrowser is an OLE control (ActiveX) that wraps the Internet Explorer control. Any ideas on how I can make the resize happen?

Updated Background:

I narrowed this down to only happening when I have a child form that I change the parent to site it inside another form. My TWebBrowser control is on a child form that I use anytime I need to show an HTML document.

In my parent form I have a Grid, a splitter, and a panel with the grid set to Align top and the panel set to align client. My child form (called THtmlViewer) has its parent set to the panel. The THtmlViewer form is set to alClient and TWebBrowser control on the child form is also set to align client.

If I do anything in the form resize of the THtmlViewer form I run into this issue. Anything being directly in FormResize or indirectly using the align properties. However, if I call my resize from the parent form everything works fine.

The key seems to be turning off the resize code in the THtmlViewer form. If I leave a OnResize handler or the alignment set then it does not matter what I do in the parent, the resize is not done correctly.

I am still confused why this is needed and why I can't force it to update in the correct resize (THtmlViewer).

As a side note I also noticed that Delphi 2007 on Windows 7 has the exactly same problem with the "Welcome Page" in the IDE.

I have worked around the issue by adding a method to set OnResize of the child form to nil and then call my internal ForceResize from the parent's OnResize handler. I would still like to deal with this all from the THtmlViewer form and would accept an answer that let's me avoid this hack.

Mark Elder
  • 3,987
  • 1
  • 31
  • 47

4 Answers4

2

I had a similar problem.

It was solved by putting a TPanel "underneath" the TWebBrowser, and aligning the web browser to alClient.

Ian Boyd
  • 246,734
  • 253
  • 869
  • 1,219
2

To resize controls when their container changes size, you have two other options besides using "just" the Align property:

  • Use the Anchors property without the Align property, that is, set the Align property to alCustom or alNone, then set the anchors according to your needs. As the Align property is sort of short-hand for setting the Anchors, this is dependent upon the same alignment processing so may not work in your case.

  • Provide a handler for the OnResize event of the container on which the TWebBrowser sits and manually set the TWebBrowser's height and width to those of the container (optionally adjusted for any margins you want to have within the container).

That said, I don't have Windows7, so I can't vouch that this won't take more twiddling.

If your TWebBrowser jumps to the correct size on a scroll or click, it indicates that the control was sized correctly, just never received or processed the messages to actually respond to the changes.

This can be because realigning controls tries to prevent unnecessary repaints and recursions and somehow got mixed up. Using the OnResize method may then get better results as it "speaks to the TWebBrowser directly".

Repaint is "just" shorthand for Invalidate and Update unless the control has csOpaque in its ControlStyle, in which case painting seems more immediate. So you could try to fiddle with the Transparent property of the TWebBrowser and/or the container it sits on.

If all else fails, you could try to send a WM_PAINT (or similar) to the TWebBrowser directly. For exmample in the OnResize event of the TWebBrowser or the container it sits on. The a WM_Paint handler of the TWebBrowser calls OleDraw, which talks to the ActiveX directly using the ClientRect, which should have the correct dimensions when called from an OnResize event.

Marjan Venema
  • 19,136
  • 6
  • 65
  • 79
  • Sending the WM_PAINT message did not have any affect. I can see the color of the panel changing color when the resize happens like the control knows its new size, but the real content of the WebBrowser control is still only drawn inside the old size. – Mark Elder Jan 24 '11 at 21:47
  • @Mark: Have you tried putting the TWebBrowser on a TFrame and adding that to any form that needs to show a HTML document? TFrame's seem to suffer a lot less of the issues that re-parenting a TForm to another TForm does. – Marjan Venema Jan 25 '11 at 07:01
1

Maybe the same solution for this question works: Resize problem using AcroPDF in Delphi

In OnResize:

if Visible and (WebBrowser1 <> nil) then 
begin
  FocusControl(nil);
  FocusControl(WebBrowser1);
end;
Community
  • 1
  • 1
mjn
  • 36,362
  • 28
  • 176
  • 378
  • For some reason I am getting an exception if I try to call Focus control with my web browser control. I do have an unusual setup with nested forms that may be causing the issue. I re-parent forms instead of using frames. Focusing the control may work but I can't confirm that. I found a different solution so I didn't try to get this working. – Mark Elder Jan 24 '11 at 21:15
0

I'd try something like

  • changing WebBrowser1.Align to alLeft,
  • setting WebBrowser1.Width to WebBrowser1.Width - 1 and
  • setting WebBrowser1.Align to alClient again

in an OnResize handler.

Uli Gerhardt
  • 13,748
  • 1
  • 45
  • 83
  • 1
    I updated my questions with some more details. It turns out that these calls from the "parent" form will work, but on my nested form nothing in the OnResize handler seems to work correctly. – Mark Elder Jan 24 '11 at 21:48