Rick Strahl's Weblog  

Wind, waves, code and everything in between...
.NET • C# • Markdown • WPF • All Things Web
Contact   •   Articles   •   Products   •   Support   •   Advertise
Sponsored by:
West Wind WebSurge - Rest Client and Http Load Testing for Windows

Web Browser Control Flicker


:P
On this page:

The Web Browser control has a mind of its own when you stick it onto a form with most ActiveX environments and especially inside of Visual FoxPro. I’m using the control both for previews and HTML editing in Help Builder and while it works OK, coercing it to behave like a proper control takes some work.

 

The most annoying problem I’ve had for a while is that the control displays at some default position in the container it is hosted on when first loaded. You see a white flashing rectangle briefly before the control can be resized.

 

I’ve tried all sorts of different things:

 

  • Initializing the form with right coordinates to start with in the Form’s Init
  • Assigning the top and left in the constructor
  • Using LockScreen to keep the form from updating its display
  • Hiding the container briefly, then showing it after the resize is complete

 

None of them worked. Even the last option which temporarily hides the container then redisplays it once the control is on it didn’t work. The control flashes ONTOP of the container and shows in the window!

 

Anything set in code prior to displaying the control – setting top, left, width and height also had no effect until the control becomes visible. The problem is that the control loads relatively slowly so you see a visible flicker of the WB control loading in a default position then ‘snapping’ into its real position.

 

Well, eventually I stumbled on the solution which is to set the control’s base properties to a width of 0 and height 0. Surprisingly this worked where assignments from the Init of the control did not. Now the Web Browser control still misbehaves but it does so ‘invisibly’.

 

Note that when you do this you have to still resize the browser at some point and adjust one of the size/location parameters AFTER the control has been made visible. Otherwise the control will not show the new location. Talk about a buggy implementation.

 

 

I’ve been struggling with a few issues in Help Builder and the HTML Edit mode when this came up again. One other problem in edit mode is that if you edit the document and navigate off IE prompts you to save the document. I couldn’t find a way around this problem so the easiest solution I could find was to simply remove the control and reload it – this is where the above comes in – more flicker because this loading unloading now happens a little more frequently. Surprisingly the overhead of unloading/reloading is minor once the visual nastiness has been removed.

 

Here’s the code that demonstrates how I now do this:

FUNCTION SetViewMode
LPARAMETER
lnMode

LOCAL loHelp, llError, loEdit

 

loHelp = ThisForm.oHelp

 

IF lnMode = 2

 

   *** If the control exists already remove it!

   IF VARTYPE(this.Parent.oHtmlEdit) == "O"

         this.Parent.RemoveObject("oHtmlEdit")

   ENDIF

  

 

   TRY

      THIS.parent.AddObject("oHTMLEdit","wwBrowser_editor",;

                                        this.left,this.top,this.Width,this.height)

   CATCH

      llError = .t.

   ENDTRY

   IF llError

      THIS.SetViewMode(1)

      WAIT WINDOW "Can't set control into WYSIWYG edit mode..." nowait

      RETURN

   ENDIF

     

   loEdit = THIS.parent.oHTMLedit

   loEdit.visible = .T.

 

   *** Force the resize from 0,0 height/width

   loEdit.Height = THIS.height +1

   loEdit.Height = THIS.height -1

  

   *** Load the Html   

   THIS.UpdateHTMLEditDisplay()

  

   THIS.nViewMode = 2

ELSE

   this.nViewMode = 1

  

   *** We're just in Text Mode - no need to switch

   IF VARTYPE(this.Parent.oHtmlEdit) != "O"

      RETURN

   ENDIF

  

   THIS.Parent.oHTMLEdit.visible = .F.

   THIS.visible = .T.

 

   THISFORM.lockscreen = .T.

  

   *** Display the textbox and read data from Design Mode

   THIS.SaveHTMLToText()

  

   *** Try to pre-selelect the text in the edit control

   LOCAL loRange, lnAt, lcSelectedHtml

   loEdit = THIS.parent.oHTMLedit

 

   loRange =  loEdit.Document.Selection.CreateRange()

   loParent = null

   IF VARTYPE(loRange) = "O"

      TRY

         loParent = loRange.parentElement

      CATCH

      FINALLY

         IF !ISNULL(loParent)

            lcSelectedHtml =  FixBasePath(loParent.outerHtml , loEdit.Document.Body)

            lnAt =ATC(lcSelectedHtml,this.Value)

            IF lnAt > 0

               this.SelStart = lnAt

               this.SelLength = LEN(lcSelectedHtml)

               this.SetFocus()

            ENDIF

         ENDIF

      ENDTRY

   ENDIF

  

   this.SetFocus()

 

   THIS.parent.RemoveObject("oHTMLEdit")

   THIS.nViewMode = 1

   THISFORM.LockScreen = .F.

ENDIF

 


The Voices of Reason


 

Mårten Törnquist
March 06, 2005

# re: Web Browser Control Flicker

Well, I have found another very nasty and annoying thing with the browser control, which I havn't even found a way around for. I use it to display various content, and I have hyperlinks in the displayed pages which opens up other FoxPro windows, the problem is that the browser window always want's to be on top when loading another window, you always have to manually click on the other window for it to gain focus, this is especially annoing when the opened window loads very fast and completly hides between the browser window, I know where to look for it, but many of my user doesn't if you know what I mean... Any clue on how to solve this one?

Malcolm Greene
March 07, 2005

# re: Web Browser Control Flicker

Rick:

Isn't there a Windows API equivalent of LockScreen that you could use while you're mucking with the web browser control?

DECLARE INTEGER LockWindowUpdate IN user32 INTEGER hWndLock
http://www.news2news.com/vfp/?group=-1&function=404 (definition)
http://www.news2news.com/vfp/?example=257&function=404 (example)

The following extracted from the above News2News.com URL's:

The LockWindowUpdate function disables or enables drawing in the specified window. Only one window can be locked at a time.

hWndLock [in] Specifies the window in which drawing will be disabled. If this parameter is NULL, drawing in the locked window is enabled.

Return value: If the function succeeds, the return value is nonzero. If the function fails, the return value is zero, indicating that an error occurred or another window was already locked.

When the drawing is disabled, whatever you do with controls on this form, you still have its image unchanged. You can still close this form by clicking on the Close button, which image will not change during the click.

This behaviour could possibly be useful for windowing controls (controls with window handles, as OLE controls) to disable their visual update for the time of performing some operations on them, like adding rows etc. Though this is only my assumption, needs to be tested.

Malcolm Greene
March 07, 2005

# re: Web Browser Control Flicker

Mårten:

Two ideas:

(1) Use a timer to launch the window you want activated - in other words, instead of launcing the form immediately, start a timer that waits 0.5 seconds (that's a guess) AFTER your browser control has processed the click event, THEN launch the form you want launched.

- OR -

(2) Checkout news2news.com's window functions. You should be able to use the Windows API to set window focus to the appropriate form - possibly (???) with an optional delay as described above so that the web browser has completed its processing and won't try to be on top.

Rick Strahl
March 07, 2005

# re: Web Browser Control Flicker

Malcom,

Interesting idea but my guess that behind the scenes that's FoxPro is actually doing with Form.Locksreen and that doesn't work because the WB appently draws into it's own window - windowed control. The other issue I found is that if the Web Browser is not visible or locked it doesn't size properly. So at some point I have to make it visible with the wrong size and then resize it anyway whihc is apparently what gives the flicker.

The solution above of setting the control to 0 height and width works to eliminate the flicker, but to be sure it's a hack around a very ill behaved control.

Rick Strahl's WebLog
March 07, 2005

# Help Builder 4.05 improves .NET support

Help Builder 4.05 was supposed to be a very minor update. Instead user feedback of the last few days inspired a number of fixes and improvements that amount to a fairly significant update. Here are some additional details and a behind the scenes look.

Rick Strahl's Web Log
February 17, 2007

# Help Builder 4.05 improves .NET support - Rick Strahl's Web Log

Help Builder 4.05 was supposed to be a very minor update. Instead user feedback of the last few days inspired a number of fixes and improvements that amount to a fairly significant update. Here are some additional details and a behind the scenes look.

West Wind  © Rick Strahl, West Wind Technologies, 2005 - 2024