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.
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 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.
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
BackgroundWorker1.RunWorkerAsync()
End Sub
Private Sub BackgroundWorker1_DoWork(sender As Object, e As System.ComponentModel.DoWorkEventArgs) Handles BackgroundWorker1.DoWork
MsgBox("test")
End Sub
Private Sub BackgroundWorker1_RunWorkerCompleted(sender As Object, e As System.ComponentModel.RunWorkerCompletedEventArgs) Handles BackgroundWorker1.RunWorkerCompleted
BackgroundWorker1.RunWorkerAsync()
End Sub
Once I click the Button1 ,Messagebox appears.When click okay with "Return" (enter) key it appears again and again...But when I click Return key permanently,almost 5 seconds later programs gives me the run time error.
Error is not English in my computer and I translated it.It is nearly mean "BackgroundWorker is busy,can't do two procces in the same time..."
I know that error.It is because of trying to run BackgroundWorker while it is running.In the code it just start with RunWorkerCompleted event.So it can't start again if "Work is not Completed".Who runs the BackgroundWorker ?
You need to read this post first, it talks about the dangers of re-entrancy and how dialogs (like MsgBox) solve the problem.
Which is what it is not doing in your program. A dialog can only be modal against other windows that are created on the same thread. That worker thread doesn't have any. So there is nothing that stops your Enter key press from also being seen by the control that has the focus. Button1. Note how you can simply use the mouse to select your main window and click the button. Kaboom.
That doesn't go wrong often enough as-is, you can help by leaning on the Enter key so it starts repeating. It will usually be detected by the message box window. But not always, there's a split second between DoWork ending and it starting back up. Just enough to give the UI thread a chance to see the keystroke. Now that Enter keypress operates Button1 and it starts the BGW back up again. So does the RunWorkerCompleted event handler, it cannot be started twice. Kaboom.
That's not the only problem with that dialog, you haven't discovered the other failure mode yet. A dialog needs an owner window, one that it can be displayed on top of. That message box does have one, it has to fallback to the desktop window. Now it is crapshoot which window is going to be in front. Could be the dialog, could be your main window. With the message box underneath your main window. The user cannot see it, has no idea that there is one. No taskbar button either.
Long story short: this cannot work. Only display UI on the UI thread. Only use a worker thread to do non-UI related work.
What I want to do is disable windows aero permanently for the user if he / she clicks a button.
Currently I have this code:
<System.RunTime.InteropServices.DLLImport("dwmapi.dll", PreserveSig:=False)>
Public Shared Sub DwmEnableComposition(bEnable As Boolean)
End Sub
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
DwmEnableComposition(False)
End Sub
The current problem with this code is... It works, but whenever you exit your application Aero switches back on.
Is there a way to prevent this?
It sounds like in windows 8 aero transparency is disabled by default.
http://www.howtogeek.com/howto/windows-vista/disable-aero-on-windows-vista/
Also, from the link: https://msdn.microsoft.com/en-us/library/windows/desktop/aa969510%28v=vs.85%29.aspx
Disabling DWM composition disables it for the entire desktop. DWM composition will be automatically enabled when all processes that have disabled composition have called DwmEnableComposition to enable it or have been terminated. The WM_DWMCOMPOSITIONCHANGED notification is sent whenever DWM composition is enabled or disabled.
So it sounds to me like you need to leave your program running. You could do something like minimize it to the task tray (as opposed to exiting it ). Who knows, maybe you can even just launch a separate executable that stays running and doesn't show up in the taskbar OR task tray. But you will have to leave the process running.
If you want Aero to be disabled "PERMANENTLY" for the user regardless of whether your app is running or not, then you'll need to identify where this setting lives in the registry and modify that setting.
If you meant that you only want to disable it for your application (meaning that the next time you launch the app, it will be either enabled or disabled based on how it was set when it was last closed), then you will need to store this in a user setting.
Create a new bool setting (user-scope) in the project settings and call it DWM. Then, in the button click event toggle it's value. Apply that value to the setting at runtime.
EDIT: The previous version would have resulted in an always false setting.
I've edited the If statements to an If-Else block.
<System.RunTime.InteropServices.DLLImport("dwmapi.dll", PreserveSig:=False)>
Public Shared Sub DwmEnableComposition(bEnable As Boolean)
End Sub
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
If My.Settings.DWM = False THEN
My.Settings.DWM = True
Else
My.Settings.DWM = False
End If
My.Settings.Save()
DwmEnableComposition(My.Settings.DWM)
End Sub
In the onload or startup event of the form/app, run the code to set true or false
DwmEnableComposition(My.Settings.DWM)
I have a windows application that when I close it still runs on the background process of task manager. I tried going through Application/Shutdown Mode/When start up form closes, but my startup form is a login form which then takes me to my main application which has a close button. I also tried the option When last form closes, no effect.
On this close button I have tried Me.Close(). and also I have tried Application.Quit() my both still not closing my application completely.
How can I terminate the application completely and clear it from the background services?
"my startup form is a login form which then takes me to my main application"
You are probably hiding the login form with Hide(), which is keeping the app alive. With the When last form closes option set, you can instead call Close() against the login form after showing the main form. Then it should shut down properly.
use Application.Exit or End...
In Login form
create a instance of MainForm
show the MainForm and close the Login form
If you want to pass any value to MainForm from Login form, create a public variable in MainForm. Eg. Public userAuth As String
Example:
Private Sub OK_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles OK.Click
Dim mf As New MainForm()
mf.userAuth = "Admin"
mf.Show()
Me.Close()
End Sub