Still celebrating National IT Professionals Day with 3 months of free Premium Membership. Use Code ITDAY17

x
?
Solved

Form not instantiated on inter-thread call OR how to load a form w/o making visible

Posted on 2006-11-06
4
Medium Priority
?
253 Views
Last Modified: 2010-05-18

Hey, I have an MDI application with a child window that is sort of an "output" window.  I also have buttons that start processes on background threads, and sometimes when the process is done it needs to send text to the output window.  So I made my Write functions thread-safe as follows (pretty much parroting another answer from this great site -- I don't understand this as well as I should).

In my OutputWindow form:

    Public Sub Write(ByVal txt As String)
        AppendLine(txt)
    End Sub

    Delegate Sub SetTextCallback(ByVal [text] As String)

    Private Sub AppendLine(ByVal txt As String)

        ' InvokeRequired required compares the thread ID of the
        ' calling thread to the thread ID of the creating thread.
        ' If these threads are different, it returns true.

        If Me.RichTextBox1.InvokeRequired Then
            Dim d As New SetTextCallback(AddressOf RawAppendLine)
            Me.Invoke(d, New Object() {txt})
        Else
            RawAppendLine(txt)
        End If

    End Sub

    Private Sub RawAppendLine(ByVal txt As String)

        RichTextBox1.AppendText(vbCrLf + txt)
        ScrollToEnd()

    End Sub

Now... when I start my application, I *New* the form but I do not set Visible=True (which I think means the form and constituent controls do not actually get loaded) unless the user has set an option that he wants it visible on startup.  If this option is not set and it is not made visible, calls to Write from an alternate thread fail with the following exception:

"Invoke or BeginInvoke cannot be called on a control until the window handle has been created."

Now, BEFORE this error the program uses the Write function at startup from the same thread (for messages like "Program started") and when the user eventually shows the window it appears with all the messages, which seems to mean the RichTextBox was loaded.  So this succeeds:

1) Starts invisible (New but no Visible=True)
2) Write from same thread
3) User calls Visible=True (from menu item) (previous writes are visible, which seems to mean it was instantiated?)
4) Write from other thread

And this fails

1) Starts invisible (New but no Visible=True)
2) Write from same thread  (why didn't this instantiate the control, i.e., "create the window handle"?)
3) Write from other thread   <-- above exception!

Anybody have any good theories which fit these observations??  I'd like to (1) fix this and (2) understand a little better.  

Thanks in advance...






0
Comment
Question by:riceman0
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 2
4 Comments
 
LVL 48

Expert Comment

by:AlexFM
ID: 17881954
   Public Sub Write(ByVal txt As String)
        AppendLine(txt)
    End Sub

In this function you can test whether form handle is created. You can subscribe to Control.HandleCreated Event and set some flag in the handler for this. If form is not created yet, accumulate all text in some container for example, StringBuilder or List<String>.
When form is shown first time, show information from container to RichTextBox1. From this moment, Write function can call AppendLine and safely use Invoke and RichTextBox1.

Unfortunately, .NET doesn't allow to create valid visible form - you cannot work normally with form controls and execute Invoke unless form is shown first time.
0
 

Author Comment

by:riceman0
ID: 17882021

Oh, man: subscribing to events, creating a flag.  

Seems like a bad oversight that they didn't allow you to start a window invisible, would save a lot of headache.

Question before I try all that... I suspect my window HAS been created, since the previous same-thread Write calls work, yes?  Why then this error?



0
 
LVL 48

Accepted Solution

by:
AlexFM earned 2000 total points
ID: 17882867
Well, possibly Form allows to set control properties before handle is created. But Invoke cannot work before handle is created. Handle is created only when Form.Show function is called, and this immediately makes form visible.
I think that when form is hidden (after it was shown initially), Invoke can fail as well. At least I know, that when form is hidden and shown again, its handle may change.
So, to make this working, I suggest the following algorithm (pseudo-code):

dim handleExists as boolean = false

HandleCreated:
    handleExists = true;
    Add text from container to RichTextBox
    Clear container

HandleDestroyed:
    handleExists = false;

AppendLine:
    if handle doesn't exist: add line to container
    else: existing code
0

Featured Post

Concerto's Cloud Advisory Services

Want to avoid the missteps to gaining all the benefits of the cloud? Learn more about the different assessment options from our Cloud Advisory team.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

A while ago, I was working on a Windows Forms application and I needed a special label control with reflection (glass) effect to show some titles in a stylish way. I've always enjoyed working with graphics, but it's never too clever to re-invent …
Parsing a CSV file is a task that we are confronted with regularly, and although there are a vast number of means to do this, as a newbie, the field can be confusing and the tools can seem complex. A simple solution to parsing a customized CSV fi…
In this video, Percona Director of Solution Engineering Jon Tobin discusses the function and features of Percona Server for MongoDB. How Percona can help Percona can help you determine if Percona Server for MongoDB is the right solution for …
We’ve all felt that sense of false security before—locking down external access to a database or component and feeling like we’ve done all we need to do to secure company data. But that feeling is fleeting. Attacks these days can happen in many w…

688 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question