Click here to Skip to main content
15,880,796 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
I have a windows forms application written in vb.net. I have a form called SplashScreen which is set as the Splash screen in the project properties. The Startup form is set to a form called Logon. I have a user who got an exception when running my app. It occurred right after the splash screen displayed and right before the logon screen displays. The user tried again and hasn't gotten the error again. However, if anyone has any ideas what could be causing this so I can make sure it's fixed, I'd appreciate it.

When googling this error, it seems that it may be related to threading, but I don't do anything special on my logon screen accept use a Me.Activate(). I was having trouble with the logon screen not having focus after the splash screen disappeared and found some forum that said Me.Activate() would fix it, and it has.
VB
Private Sub Logon_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        'This statement will fix the issue users occasionaly have with the logon form not having focus after the splash screen goes away
        Me.Activate()
        'Other loading tasks...
End Sub

Here is the error message:
Message: Invoke or BeginInvoke cannot be called on a control until the window handle has been created.
Exception: System.InvalidOperationException: Invoke or BeginInvoke cannot be called on a control until the window handle has been created.
   at System.Windows.Forms.Control.WaitForWaitHandle(WaitHandle waitHandle)
   at System.Windows.Forms.Control.MarshaledInvoke(Control caller, Delegate method, Object[] args, Boolean synchronous)
   at System.Windows.Forms.Control.Invoke(Delegate method, Object[] args)
   at System.Windows.Forms.Control.Invoke(Delegate method)
   at Microsoft.VisualBasic.ApplicationServices.WindowsFormsApplicationBase.HideSplashScreen()
   at Microsoft.VisualBasic.ApplicationServices.WindowsFormsApplicationBase.MainFormLoadingDone(Object sender, EventArgs e)
   at System.EventHandler.Invoke(Object sender, EventArgs e)
   at System.Windows.Forms.Form.OnLoad(EventArgs e)
   at System.Windows.Forms.Form.OnCreateControl()
   at System.Windows.Forms.Control.CreateControl(Boolean fIgnoreVisible)
   at System.Windows.Forms.Control.CreateControl()
   at System.Windows.Forms.Control.WmShowWindow(Message& m)
   at System.Windows.Forms.Control.WndProc(Message& m)
   at System.Windows.Forms.ScrollableControl.WndProc(Message& m)
   at System.Windows.Forms.Form.WmShowWindow(Message& m)
   at System.Windows.Forms.Form.WndProc(Message& m)
   at System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m)
   at System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m)
   at System.Windows.Forms.NativeWindow.Callback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)
Stack Trace:    at System.Windows.Forms.Control.WaitForWaitHandle(WaitHandle waitHandle)
   at System.Windows.Forms.Control.MarshaledInvoke(Control caller, Delegate method, Object[] args, Boolean synchronous)
   at System.Windows.Forms.Control.Invoke(Delegate method, Object[] args)
   at System.Windows.Forms.Control.Invoke(Delegate method)
   at Microsoft.VisualBasic.ApplicationServices.WindowsFormsApplicationBase.HideSplashScreen()
   at Microsoft.VisualBasic.ApplicationServices.WindowsFormsApplicationBase.MainFormLoadingDone(Object sender, EventArgs e)
   at System.EventHandler.Invoke(Object sender, EventArgs e)
   at System.Windows.Forms.Form.OnLoad(EventArgs e)
   at System.Windows.Forms.Form.OnCreateControl()
   at System.Windows.Forms.Control.CreateControl(Boolean fIgnoreVisible)
   at System.Windows.Forms.Control.CreateControl()
   at System.Windows.Forms.Control.WmShowWindow(Message& m)
   at System.Windows.Forms.Control.WndProc(Message& m)
   at System.Windows.Forms.ScrollableControl.WndProc(Message& m)
   at System.Windows.Forms.Form.WmShowWindow(Message& m)
   at System.Windows.Forms.Form.WndProc(Message& m)
   at System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m)
   at System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m)
   at System.Windows.Forms.NativeWindow.Callback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)

Does anyone have any ideas what would cause this?

**** UPDATE ****
One of my users continues to get this error randomly. Just like before, he'll try to run the app, get the error, then try to run the app again a few seconds later and it works just fine. I tried moving the Me.Activate() code to the Logon_Shown event. The user still gets the error every once and a while. Then tried removing the Me.Activate() entirely. The user STILL gets the error. It seems to happen when I publish a new version of the application and the user tries to run it for the first time. But it has also happened randomly at other times. Possibly after the user has rebooted, but not every time he reboots. He uses a machine that runs Windows 7, has admin authority, and has the UAC stuff on but not at it's highest level. It's happened enough with this user that I'm concerned I need to change something or fix something, but again...I have no idea where to start. It appears to be an issue with the built in splash screen feature. If anyone has any new suggestions, I would appreciate any ideas.
Posted
Updated 17-Apr-12 10:56am
v2
Comments
Sergey Alexandrovich Kryukov 7-Feb-12 18:03pm    
First of all, add a tag "WinForms".
--SA

This looks like it means you tried to interact with a form element that did not exist yet. Look at your constructors and ask if there's stuff better moved to the Load event.
 
Share this answer
 
Comments
Kschuler 7-Feb-12 12:16pm    
I don't have any special constructors for these forms. I use them as is.
Sergey Alexandrovich Kryukov 7-Feb-12 18:01pm    
Not true! If you did not type it with your own hand, Designer did. This is still your code (well, be brave enough to take responsibility for it :-)).
--SA
Christian Graus 7-Feb-12 18:02pm    
But it's fair to say that he would expect the boilerplate code to work, and, he sure can't edit it.
Christian Graus 7-Feb-12 12:17pm    
You don't put any code in any constructor ? Then I'm not sure what else you can hope to do. It does sound like a race condition, but, in my experience, some times one user has an issue that you will never be able to explain or reproduce. Who knows why ? It probably has to do with their machine and what else was running, then.
Kschuler 7-Feb-12 13:33pm    
That's kind of what I was thinking, but didn't want to dismiss it without a second opinion. Thanks for the input.
We can reproduce the error this way.

Re-boot the machine and as soon as the OS has loaded start you application. If will almost always fire the unhandled exception you mentioned! If you leave it a few minutes after the OS has loaded you might not get the exception.

The error only seems to happen with Windows 7.

This fix worked of me.

Add a boolean in My.Settings (LoadFinished)

Add the following to ApplicationEvents

VB
'Engineering case 220125 -  'Invoke or BeginInvoke cannot be called on a control until the window handle has beeen created.'
        Private Sub MyApplication_Startup(sender As Object, e As Microsoft.VisualBasic.ApplicationServices.StartupEventArgs) Handles Me.Startup
            Try
                If Not Me.SplashScreen Is Nothing Then
                    While My.Settings.LoadFinished = False
                        System.Threading.Thread.Sleep(5000)
                    End While
                End If
                My.Settings.LoadFinished = False
            Catch ex As Exception
                EmailError(ex)
            End Try
        End Sub

        Protected Overrides Function OnInitialize(commandLineArgs As System.Collections.ObjectModel.ReadOnlyCollection(Of String)) As Boolean
            MinimumSplashScreenDisplayTime = 3000
            Return MyBase.OnInitialize(commandLineArgs)
        End Function


Add this to your splash screen load event (at the very end)

VB
My.Settings.LoadFinished = True
 
Share this answer
 
Comments
Kschuler 20-Aug-12 9:05am    
In the time that has past since I last updated/posted this question, I've had the error occur on a few other random machines. Some of which were XP. Also, I had it happen to my own machine a couple of times. In those times the OS had loaded several hours previously. So either we have different but similar problems, or there is still something that hasn't initialized or loaded when my users are having the issue. Thanks for your feedback and I will give your code a try and see if it helps!
gchq 22-Aug-12 10:23am    
Perhaps we just haven't had any feedback from XP users, or they are now getting thin on the ground. I have had this occur on my workstation, but only after the app was started the first time after a re-boot (and I only reboot mine once a month after Tuesday patch day). It happened on a laptop when I was giving a demo of our software - always a good time!!

Since updating with the above workaround we have not had one reported incident (just over three weeks now) and I had tried so many ways to beat it for the best part of a year...
Oh, I can see the bug.

First of all, let me assure you that you have a form constructor. Just find it. It looks like you are handling the "fake" event Form.Load. This event is actually fired as if your place its handler in a constructor, after the auto-generated layout call. I actually do it manually, never use this event. This is not a problem yet.

The problem is that you call Activate. Of course it's way to early!

In the constructors the Windows handle for the window itself is not yet created, forget other controls. Many operations cannot be done there. To be really sure you call is not too late, do it in the handle of the event Form.Shown or in the overridden virtual method Form.OnShown.

Please see:
http://msdn.microsoft.com/en-us/library/system.windows.forms.form.shown.aspx[^],
http://msdn.microsoft.com/en-us/library/system.windows.forms.form.onshown.aspx[^].

However, usually you don't need to call Activate at all. Normally, the form is activated by itself. You need to activate it sometimes, but not when it is created, but when some other form is active and you want to activate another one.

[EDIT]

In reply to follow-up discussion:

Please see my recent answer where similar situation was discussed:
Close child form in vb.net[^].

Perhaps you do similar way: need to show one form after another: splash and then the main form, but you might do it in a wrong way.

—SA
 
Share this answer
 
v2
Comments
Kschuler 8-Feb-12 12:16pm    
I know there is a constructor. I said I don't have any "special constructors" by which I meant I didn't write one and have left it up to the designer. And about the Shown event...the reason I have the Me.Activate in the first place is because of trouble I was having with the Logon form not having focus after the Splash Screen disappeared. Unfortunately, that scenario doesn't always happen...I can't reproduce it on my machine but other users were having the issue and the Me.Activate fixed it. So I have no way of testing if moving it to the Shown event will work without just publishing it and thereby possibly breaking it for my customers. Have you ever used the Me.Activate in the Shown event yourself? Or heard of anyone using it for this specific purpose?
Kschuler 1-Mar-12 12:24pm    
I changed my program and moved the Me.Activate() into the Shown event for the form. The same user still gets the error. Do you have any other ideas?
Sergey Alexandrovich Kryukov 1-Mar-12 20:23pm    
This is not what I told you. You don't need to call Activate at all. I did not call Activate in Shown because it's never needed, but I know that in this event the windows handle already exists. Which form do you Activate? The same form or some other, which might not have a handle yest? Did you do BeginInvoke?

You know what: could you simply create a minimal possible code sample and post it using "Improve question"? Probably you are doing something wrong.

The problem of showing one form before main is very usual and many do it wrong. Anyway, Activate is totally redundant. I'll add the update to my answer above, please see, after [EDIT].

--SA
Sergey Alexandrovich Kryukov 1-Mar-12 20:27pm    
Done, please see.
Showing one form after another never cause problems, but some do it wrong. Please check up.
--SA
Kschuler 2-Mar-12 11:28am    
I'm not calling a different form. I know that I shouldn't HAVE to use the Me.Activate(). It makes no sense. But if you read my question carefully you will see that I put that statement in to fix a strange buggy issue involving the form not getting focus after the splash screen had displayed. Originally my program was written using an older version of VS. Now I'm using VS2010. I think my only option is to remove the Me.Activate() and just hope that the buggy focus issue was fixed in VS 2010 and doesn't come back. If it does, I'll just have to find some other way to fix that issue.

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900