vb .net check if the only open window is current window - vb.net

i'm working on a project that has several windows that the user opens AFTER clicking on a "start" button. i need to restrict the user by showing an error message if the "start" button is clicked WHEN other windows are still open.
here's what i got for the main window with the "start" button:
Private Sub btnStart_Click(sender As Object, e As EventArgs) Handles btnStart.Click
Dim openForms As New FormCollection()
openForms = Application.OpenForms()
If openForms.Count > 1 Then
MessageBox.Show("ERROR MESSAGE", "Errors", MessageBoxButtons.OK, MessageBoxIcon.Error)
Else
'some codes here
End If
End Sub
the problem with the above code, is that not all windows are "disposed" properly, hence it remains in an "open" state even after they are closed. and i am not in the position to edit those other windows. any help would be appreciated.

You can try it like this:
If Application.OpenForms().OfType(Of Form2).Any Then
MessageBox.Show("Opened")
Else
'Else
End If

Related

VB.NET MessageBox Help link opens several times

Message
I need to add a help button in my message box then find the answer here Clickable URL in a Winform Message Box? which is great! however, when I use this code inside a button then click the help button, it opens 2 tabs with the same link.
Private Sub btn1_Click(sender As Object, e As EventArgs) Handles btn1.Click
MessageBox.Show(
"test message",
"caption",
MessageBoxButtons.YesNo,
MessageBoxIcon.Information,
MessageBoxDefaultButton.Button1,
0, '0 is default otherwise use MessageBoxOptions Enum
"http://google.com",
"keyword")
End Sub
-Update: I just tried it with the new project Winforms .NET 5.0 and it's working fine, but I need this on my current project.

vb.net cannot access a disposed object when opening form

I have a program that we use to run different reports. Based on the menu option chosen, I open the same form that lists the reports based on the menu option.
(There are also different options and functionalities in the program, not just one form).
When clicking a menu option, I have the following bit of code
Private Sub ReportsToolStripMenuItem1_Click(sender As Object, e As EventArgs) Handles ReportsToolStripMenuItem1.Click
FormLocation = "F_Legal"
FormName = "Legal"
PrepareForm(F_Select_Report)
End Sub 'ReportsToolStripMenuItem1_Click
Where F_Select_Report the form is that is opened.
Private Sub PrepareForm(formName As Form)
Cursor = Cursors.WaitCursor
For Each Form In Me.MdiChildren
Form.Close()
Next
formName.MdiParent = Me
formName.Height = Me.Height
formName.Width = Me.Width
formName.Show()
Cursor = Cursors.Arrow
End Sub 'PrepareForm
This bit is called, closing all other opened forms, and then open the form that is called.
This works fine on the first time I try and open a form, but on the second try, I get an error message saying
Cannot access a disposed object.
And then on the third try, it opens the form again.
How would I fix this up?
Thanks a lot
Form.Close implicitly calls Form.Dispose
So if the formName is an MdiChild it gets disposed in the For Each loop.
Then, on the next line your code attempts to assign to its MdiParent property and there the error occurs.
So you need to skip it when closing MDI children like this:
For Each Form In Me.MdiChildren
If Not Form Is formName Then Form.Close
Next
Given your code I think it is better to close the children before showing the F_Select_Report form. I.e. move the For Each loop as is to the top of the ReportsToolStripMenuItem1_Click handler.
Not sure if it is the best/nicest solution, but found a solution to this.
Instead of 1 Sub that does both closes all open forms, and then opens the new one, I split it out over 2 Subs.
Close all open ones
Private Sub CloseAllForms()
For Each Form In Me.MdiChildren
Form.Close()
Next
End Sub 'CloseAllForms
And then open the new form
Private Sub PrepareForm(formName As Form)
Cursor = Cursors.WaitCursor
Try
formName.MdiParent = Me
formName.Height = Me.Height
formName.Width = Me.Width
formName.Show()
Catch ex As Exception
MessageBox.Show("Error: " & ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error)
End Try
Cursor = Cursors.Arrow
End Sub 'PrepareForm
Now it works as needed.

Application Auto-closes after dialog box

New to VB.NET but pretty stumpped at the moment.
My Windows Form application launches 'Form1' which then starts a dialog box using:
Dim dialogResult As Boolean = configWizard.ShowDialog()
The ConfigWizard then writes some data to the registry, pops up with the new registry values and closes at which point the rest for Form1 loads.
This all works fine.. When debugging from Visual Studio 2015.
The problem I'm facing is when I build an installer for this program using the in-built InstallShield. The installer set the registry values on install (which works perfectly) then the dialog box opens, sets new values and pops up with the new values it's written. This all works fine. However, the Form1 closes straight away as soon as I press 'OK' on the dialog box.
It's supposed to pop up with a message box saying 'True' but the entire program closes.
Upon constant running of the program it did appear that the Form1 did flash up for milliseconds before disappearing. Does seem like the program is just closing for some unknown reason. I'm pretty stumped as to how to stop the Form1 from closing. Any light of questions to help out would be must appreciated.
I've omitted some code that is irrelivent.
I managed to quick take a screenshot when the Form1 did flash up (verifying both Form1 and the messagebox saying 'True' ARE loading after the dialogbox is closing.. albeit only for a split second)
Code:
Dialog Box:
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
myValue1= Me.myValue1.Text
myValue2= Me.myValue2.Text
Dim regKey As RegistryKey
regKey = Registry.CurrentUser.OpenSubKey("SOFTWARE\removedSoftware", True)
regKey.SetValue("value1", myValue1)
regKey.SetValue("value2", myValue2)
MsgBox(myValue1 & " + " & myValue2)
MsgBox("Registry: " & regKey.GetValue("value1") & " data: " & regKey.GetValue("value2"))
regKey.Close()
Me.Close()
End Sub
Form1
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
Dim dialogResult As Boolean = configWizard.ShowDialog()
Try
Catch ex As Exception
MessageBox.Show(ex.ToString)
End Try
MsgBox(dialogResult)
End Sub
Use OnShown event (Form1_Shown) instead of OnLoad to display the dialog box.

Show MessageBox modaly from background thread

In my Winform VB.NET application I am checking some fields. In case that one particular field is equal to true I need to show message. Normally it would be like this:
If (myField) Then
MessageBox.Show("Something is wrong", "Warning", MessageBoxButtons.OK)
// continuing...
End If
This message must be shown modaly (user can return to main form only after clicking OK button). Problem is that I do not want the thread to wait for the clicking (just show the message and continue - do not wait for OK button).
My only idea is to show the message in background thread:
If (myField) Then
Dim t As Thread = New Thread(AddressOf ShowMyMessage)
t.Start()
// continuing...
End If
Private Sub ShowMyMessage()
MessageBox.Show("Something is wrong", "Warning", MessageBoxButtons.OK)
End Sub
But in this case the message is not shown modaly (user can return to main form and interact with it without clicking Ok button).
Any ideas?
Your design is likely to be wrong if this is what you want to do, but for an exercise I wrote something that should achieve what you want.
Private Sub Button11_Click(sender As Object, e As EventArgs) Handles Button11.Click
Dim thr As New Thread(Sub() ThreadTest())
thr.Start()
End Sub
Private Sub ThreadTest()
Debug.WriteLine("Started")
Me.ShowMessageBox("Can't click on the main form now", "Alert", MessageBoxButtons.OK, MessageBoxIcon.Exclamation)
Debug.WriteLine("Thread continued")
End Sub
Public Sub ShowMessageBox(textToShow As String, caption As String, buttons As MessageBoxButtons, icon As MessageBoxIcon)
Me.BeginInvoke(Sub() MessageBox.Show(textToShow, caption, buttons, icon))
End Sub
When you run it you will see that the ThreadTest code carries on past the showing of the messagebox, but no interaction is allowed with the main form until the ok is clicked on the message box

Application.Exit() and FormClosing event in Vb.net

I have a single windows form application that is running in system tray icon.If the user press X button of the windows form a messagebox is displayed with Yes and No ( Yes ->close the form---No->keep the form running in system tray icon).
I was thinking to prevent the scenario when the user open another instance of the application when there is already an instance running so i have used this code :
If Process.GetProcessesByName(Process.GetCurrentProcess.ProcessName).Length> 1 Then
MessageBox.Show("Another instance is running", "Error Window", MessageBoxButtons.OK,
MessageBoxIcon.Exclamation)
Application.Exit()
End If
The problem is that when i want to test this the message is displayed but after i press ok, a new messagebox appears (that one from Private Sub Form_FormClosing ).If i choose NO i will have to instance running!
I have read that Application.Exit fires the Form_FormClosing event.
Is there any possibility to cancel the triggering of the Form_FormClosing event,or am i doing something wrong?
'this is the formclosing procedure
Private Sub Form_FormClosing(ByVal sender As Object, ByVal e As System.Windows.Forms.FormClosingEventArgs) Handles Me.FormClosing
Try
Dim response As MsgBoxResult
response = MsgBox("Are you sure you want to exit", CType(MsgBoxStyle.Question + MsgBoxStyle.YesNo, MsgBoxStyle), "Confirm")
'If the user press Yes the application wil close
'because the application remains in taskmanager after closing i decide to kill the current process
If response = MsgBoxResult.Yes Then
Process.GetCurrentProcess().Kill()
ElseIf response = MsgBoxResult.No Then
e.Cancel = True
Me.WindowState = FormWindowState.Minimized
Me.Hide()
NotifyIcon1.Visible = True
End If
PS: I am not a programmer so please don't be to harsh with me:)
You don't need to Kill the current process or use the End Statement. If you have to use these then there is something amiss with your application.
When you want to end your application use Me.Close. This will fire the FormClosing event:
Private Sub Form1_FormClosing(sender As Object, e As System.Windows.Forms.FormClosingEventArgs) Handles Me.FormClosing
Select Case MessageBox.Show("Are you sure you want to exit?", "Confirm", MessageBoxButtons.YesNo, MessageBoxIcon.Question)
Case Windows.Forms.DialogResult.Yes
'nothing to do here the form is already closing
Case Windows.Forms.DialogResult.No
e.Cancel = True 'cancel the form closing event
'minimize to tray/hide etc here
End Select
End Sub
To stop more than one copy of your application from running use the option to Make Single Instance Application
In the situation where you are just starting your application and are testing for previous instances I have used the VB End Statement to terminate the application.
The End statement stops code execution abruptly, and does not invoke
the Dispose or Finalize method, or any other Visual Basic code. Object
references held by other programs are invalidated. If an End statement
is encountered within a Try or Catch block, control does not pass to
the corresponding Finally block.
If Process.GetProcessesByName(Process.GetCurrentProcess.ProcessName).Length> 1 Then
MessageBox.Show("Another instance is running", "Error Window", MessageBoxButtons.OK, MessageBoxIcon.Exclamation)
End
End If
Private Sub main_master_FormClosing(ByVal sender As Object, ByVal e As System.Windows.Forms.FormClosingEventArgs) Handles Me.FormClosing
If e.CloseReason = CloseReason.UserClosing Then
'Put you desired Code inside this!
Msgbox("Application Closing from Taskbar")
End If
End Sub
It will Close the exe from Taskbar or kill Process. If user Close the
Application from taskbar.
CloseReason.UserClosing
event will close the application if it is closed by User from
Taskber