I have a splash-screen for a desktop app that I am making. The way the startup works is that it checks for certain files, if it finds them it closes immediately and loads up the main form.
However by doing so I get a threading error. I'm guessing its because the startup form closes before fully loading the Main form.
Here's the error message:
Cross-thread operation not valid: Control 'frm_SplashScreen' accessed from a thread other than the thread it was created on.
I've tried putting the thread to sleep, and even using timers to give the form time to load. But so far unsuccessfully.
Private Sub frm_Load_Load(sender As Object, e As EventArgs) Handles MyBase.Load
If Dir("System.dll") = "" then
Createfile()
Frm_Main.show()
Me.close()
Else
Frm_Main.show()
Me.close()
End IF
Everything else regarding the splash-screen is done in the project properties under application. Otherwise it is just an empty form.
How can I fix this?
In WinForms, the splash screen is not responsible for creating the main form and should not do so. If you have code that needs to run before the main form is created, while the splash screen is visible, place that code in the application's Startup event. Here's how to do it:
Go to the application tab of your project's properties (same place you set the startup form and splash screen).
Click on "View Application Events"
In the event dropdown near the top of the window, select "Startup". This should create an event handler method for the Startup event, if it doesn't already exist (Private Sub MyApplication_Startup(sender, e) Handles Me.Startup).
Put your code (the If Dir(...) Then Createfile() stuff in your example code) in the event handler.
The code in the Startup event handler will be called before the main form is created. The splash screen will automatically be created, displayed, and destroyed in another thread. You don't need to worry about creating or closing the splash screen, as that is done automatically.
If your startup code determines that you don't want the main form to be displayed at all, set e.Cancel = true in the startup event handler method and the application will quit instead of bringing up the main form.
Well, according to my previous experience, this is a bug in visual studio, and it comes as a result of setting your startup form to window state.maximized that overrides the default launch event. So in order to fix this, you need the start up for to laugh at the startup then set the event on the splash screen's form closing event, instead of it running directly in the startup form.worked on over 5 projects. They all had the same issues till I moved the maximized state to the splash closing event e.g
Private sub splash_closed(....)
Startup form.window state.maximized...
End sub
So, the issue was actually event collision.
Related
I'm working on a single instance application in VB.NET that goes hidden when we minimize the form:
Private Sub Form_Resize(sender As Object, e As EventArgs) Handles Me.Resize
If Me.WindowState = FormWindowState.Minimized Then
Me.Visible = False
End if
End Sub
Then, if I try to launch it again, it doesn't open because it is already running (so far, so good).
Is it possible to make it just visible on this stage? I mean, can I just make the application visible if I try to launch it when it's already running?
I suppose this can be done because there are some applications with this exact behavior.
In your WinForms project properties select "View Application Events" (My Project -> Application -> View Application Events). From there you can see the events that get fired at the start and end of your application. One of which is the StartupNextInstance event handler. In here you should be able to make your form visible again.
Per docs:
A single-instance application raises the StartupNextInstance event when you attempt to restart the application when it is already active. When a single-instance application starts for the first time, it raises the Startup event. For more information, see Startup.
StartupNextInstance Documentation
I'd like to know if there is a possible way to handle a closing application in Visual Studio 2008 without using the dispose event handler.
If my application crashes or if I close it while it is running:
Private Sub Foo_Disposed(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Disposed
Is not called.
This result in a serious problem, because I'm currently working on multiple Excel files and they remain open after the application crashes or I close it while it's running.
Is there a way to handle this kind of closing application event?
In a normal situation when your application is simply closing you can subscribe to the MyApplication.Shutdown event and close your excel documents in there.
Subscribing to the event can be done through these steps:
Right-click your project in the Solution Explorer and press Properties.
Go to the Application pane and press View Application Events.
In the file that was opened, either write the event handler on your own or let VS do it by first selecting (MyApplication Events) in the left combo box above the text editor, then selecting Shutdown in the right combo box.
Now you should have an event handler that looks something like the one below. Just go ahead and do your cleanup in there:
Private Sub MyApplication_Shutdown(sender As Object, e As System.EventArgs) Handles Me.Shutdown
'Do your cleanup here...
End Sub
For application crashes caused by CLR exceptions you can use the AppDomain.UnhandledException event, but for more serious crashes there isn't very much you can do.
A workaround would be to create another application which monitors your main app. When the other app senses that your main application's process has been terminated, it will close the excel documents. The tricky part with this solution is passing the information necessary for the other app to close the documents.
I have 3 forms
MDI parent for TCP client
MDI parent for serial
The main menu form
I want to set the main menu form as the startupform then I want the 2 MDI parent to be loaded on the background. I don't want to show them, but I want to load them so I can trigger the on_load event of those 2 mdi parent which is to create serial/client child and connect automatically.
I've tried, but it didn't work.
Private Sub frmMenu_Load(sender As Object, e As EventArgs) Handles MyBase.Load
frmTcpMDI.show
frmSerialMDI.show
End Sub
I even tried adding a timer then starting it upon the show event of my startup form, the tick event is to open my frmTcpMDI and frmSerialMDI, still, it is not working.
Okay basically, if I understand what you want, you need a way to load your forms but not display them.
You want to run some code when the Load event occurs. However, as stated here by Microsoft :
Occurs before the control becomes visible for the first time.
Which basically screws you up...
So there is a few workaround for that.
Option 1 : You decide to run your code in the Sub New()
If you put all the code you want to run in the Sub New() of your child forms, you don't need to call Form.Show(), you just need to create the forms, and your code is running. When you actually need to display the form you call the Show() method and it's done.
Option 2 : You can't run your code in the Sub New()
If, for some reason, you can't run your piece of code in the Sub New() method, you still can do it with the load event. Just hide the form after showing it... Looks silly but will work.
First notice, still from Microsoft :
The Load event occurs when the handle for the UserControl is created. In some circumstances, this can cause the Load event to occur more than one time. For example, the Load event occurs when the UserControl is loaded, and again if the handle is recreated.
Which mean you have to be carefull to run your code only once...
Then, from your parent :
Dim myNewForm = new frmTCPMdi()
myNewForm.Show()'will call the Load event
myNewForm.Hide()'will hide the form, so it is loaded but invisible...
Honnestly, I think Option 1 looks better, but sometimes and for some reason you can't always go the easy way...
I have used a timer, a progress bar and incremented the value by 2 on each timer tick. After that, "Main" should load, but it doesn't. Why? I did use a tracepoint which said the value was 100 and then the program exited with code 0.
Public Sub Timer1_Tick(sender As Object, e As EventArgs) Handles Timer1.Tick
ProgressBar1.Increment(2)
If ProgressBar1.Value = 100 Then
Main.Show()
Me.Close()
End If
End Sub
Presumably you are using the Application Framework and you have selected the form that has that timer as the Startup object and you have the Shutdown mode set to the When startup form closes option (these are all options on the Application tab of the project properties designer window). I suspect that is the case because those are the default settings for a new VB WinForm application project. When you have your project configured that way, the application will automatically close when the startup form closes. Therefore, when you call Me.Close() on the first form, the application terminates immediately, even when it has already shown another form. One way to correct it is to change the Shutdown mode to the When last form closes option.
I have a modal window popup so a user of my application can edit some stuff, then they save it and close the window. When they close the popup window, my parent (main) window gets sent to the back of all other applications on my desktop, and then it immediately gets sent back to the front.
Any idea why this would happen?
In your main form:
Dim frmDlg as New FormDialogToShow
frmDlg.ShowDialog(Me)
The main form should not get sent to the back. The child dialog will display on top of the parent. Without the owner reference, the mainform can sometimes get sent to the back. When you dont specify an owner form and that happens:
Dim frmDlg as New FormDialogToShow
frmDlg.ShowDialog()
Me.BringToFront
(the answer is the same as the first time)
Does your modal form somehow hide itself before ShowDialog line ends? This happened to me and was able to solve it by removing the Hide call from the modal form.
I think I read somewhere here in SO that this happens because Windows does not have an enabled window to send focus to in the active app so it sends focus to the next app instead.
This code seems to solve the problem:
' When closing the subform
' ------------------------
sub_form.close()
main.focus()
sub_form.dispose()
When doing this, my main form does not get sent to the back even when the sub form is modal window.
I was searching desperately to find the answer to a similar problem. I found this to be particularly useful:
Private Sub Frm_FormClosing(sender As Object, e As FormClosingEventArgs) Handles MyBase.FormClosing
Prompting = False
Frm = Nothing
FrmPrompt.Close()
FrmPrompt.Dispose()
FMain.Activate()
End Sub
Activate allowed my main form to not be sent behind anything else I had open.