My blog has moved! Redirecting…

You should be automatically redirected. If not, visit http://www.digitalfugu.com/blog/ and update your bookmarks.

Friday, October 12, 2007

Calling ShowWindow from WinForm causes form loading to stall

In our quest to draw custom windows for our application we are using the WebBrowser control provided by .Net Framework 2.0, to display messages with rich formatting. However, our custom form drawing requires that we know the form dimensions before the form is initialized which presented us a problem because our messages can be user defined and allow line breaks, as well as some limited formatting options such as bold and italics and as such will vary in height when it is rendered in the WebBrowser control. So the problem became: How can I pre-render out the html and measure how tall it will be so that we can have the required window size in the constructor before form initialization?

We discovered that we could use a scheme of "splitting" up the constructor of our form so that we could load up the web browser control, then handle the DocumentComplete event for the "second" part of the constructor which includes the normal call to InitializeComponent(). If we don't wait for DocumentComplete() the Document associated with the browser control isn't null, but also doesn't have correct size information because it hasn't rendered yet. That was great. We could use WebBrowser.Document.Body.ScrollRectangle.Height.

An additional complication was that we didn't want the form to steal focus when it showed up and were using the ShowWindow api call with the SW_SHOWNOACTIVATE parameter. This meant that to keep the parent thread running we needed to use Application.Run() with no params instead of the normal Application.Run(FormObject) and we called the ShowWindow api from part two of the form constructor to prevent strange window ghosting. This caused a strange side effect that the form would load up part way and then not seem to respond. This was a mystery.

Strangely enough since we could see the form we assumed that it was fine, but why wasn't it responding to inputs and coding properly? Thank goodness for MSDN. After some research into the normal Form.Show() method call we found out that if we didn't set the form visibility to true, then some windows events wouldn't get processed. So as soon as we added this.Visible = true to the end of our "2 part constructor" every thing seems to run like it is supposed to.

No comments: