How can I restart a running VB program from within?
I have written a VB program that solves SUDOKU puzzles.
When it completes the solution, it asks if the user wants to run again with another puzzle.
I can not:
-determine the first line of code that the program executes. The main() is empty. All code is on the tab for Form1. I have tried breakpoints, but still can't determine the starting point.
-figure out how to cause the program to jump back to the starting point in the code.
Can you help me?
I've tried placing breakpoints in the code at places that might be close to the starting point, but so far that hasn't worked. When the program starts, Form1 is displayed, and it is waiting to see if a check box gets activated, or if text is entered anywhere in many text boxes.
You should do what Alejandro said in his comment: "reset the data state to the starting point".
But if you must, you can restart a WinForms application with Shell(Application.ExecutablePath)
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
If MessageBox.Show("Start from scratch?", "Confirm Restart", MessageBoxButtons.YesNo, MessageBoxIcon.Question) = DialogResult.Yes Then restart()
End Sub
Private Sub restart()
Shell(Application.ExecutablePath, AppWinStyle.NormalFocus, False)
End
End Sub
Related
The basic problem is I have a form (Form A) that opens another form (Form B for now) to edit information in Form A. When Form B is done, it should refresh the information in Form A.
To accomplish this, I create in Form B
Public Event Saved(sender As Object, e As EventArgs)
And then call it with
RaiseEvent Saved(sender, e)
I know that the RaiseEvent line is executing (if I set breakpoints and step over the debugger lands on it), but then the line in Form A that should be picking up the event
Private Sub frmContactPrefixDel_Saved(sender As Object, e As EventArgs) Handles frmContactPrefixDel.Saved
Where frmContactPrefixDel points to Form B doesn't pick up the event and execute it's lines. If I set a breakpoint on that line it doesn't even get to that sub at all. Any obvious problems? I'm new to object oriented programming, but I can't see where I've gone wrong. It seems simple to me. Also, intellisense in Visual Studio 2015 is picking up the .Saved on the end of frmContactPrefixDel so I don't think it's a scope issue.
I realize I'm making assumptions here as someone new to the game. Feel free to ask questions.
So i want to make a maze game in Visual Basic and if the cursor reaches a certain panel, it will show a message box ONCE and then the Form closes.
The question is How?
I've tried
Private Sub Panel1_Paint(ByVal sender As System.Object, ByVal e As System.Windows.Forms.PaintEventArgs) Handles Panel1.Paint
If Cursor.Position = Panel1 Then
MsgBox("Completed")
Application.Exit()
End If
End Sub
And didn't work. I got
Error 1 Overload resolution failed because no accessible '=' can be
called with these arguments:
'Public Shared Operator =(left As System.Drawing.Point, right As System.Drawing.Point) As Boolean': Value of type
'System.Windows.Forms.Panel' cannot be converted to
'System.Drawing.Point'. C:\Documents and Settings\Admin\Local
Settings\Application Data\Temporary
Projects\WindowsApplication1\Form1.vb 4 12 WindowsApplication1
Remember that i want the message box to only appear once, because sometimes when the cursor is on the panel, it shows multiple msgbox until the cursor is outta there.
I want the mouse inside the panel and run a code.
I believe there is an event called 'mouse enter' event you can use so if you type the code for the messagebox in that even for the control you want them to mouseover it will pop up everytime they do that.
For it to to nly pop up once make a counter that adds 1 and dont execute that code if the counter is already on 1.
I had a little search and found: Determine whether the mouse is over a control? (over a Control pixel range)
I just knocked up a test with a button and seemed to work fine. Please adapt to your own needs.
Private Sub Button1_Paint(sender As Object, e As PaintEventArgs) Handles Button1.Paint
Debug.WriteLine(MouseIsOverControl(Button1))
End Sub
Public Function MouseIsOverControl(ByVal c As Control) As Boolean
Return c.ClientRectangle.Contains(c.PointToClient(Control.MousePosition))
End Function
In this example I've just output "true or false" to determine detection. You can test and change it to your own needs to determine what you want to do depending on 'true/false'. Hope this helps.
In my program I have a preview, and edit side.
When you edit using the text boxes on the edit side(right side) and click "save", It should change the label on the right side (preview side). Although when you exit the program and re-open, all the data you entered has disappeared!,
I have tried the below code and had no luck as my result.
Public Class Form1
Private Shared NameBasic As Integer
Public Sub New()
InitializeComponent()
lblNameBasic.Text = Convert.ToString(NameBasic)
End Sub
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
NameBasic = txtFirstBasic.Text
lblNameBasic.Text = Convert.ToString(NameBasic)
End Sub
End Class
Also my goal is to have it be able to take it on a flashdrive onto any computer and have that data still saved within the exe. Is this even manageable? (I am more of a web based programmer so I am a bit new to this)
You need to write values to a text file at the same location of the exe. and read it. you will need both exe and the textfile.
OR
You will need to write a dll on run-time and write some values while closing the application. this will be more secure then the text file. here you will need both exe and dll to be copied into flash drive
OR
the application setting as spoken by others..
So I've set my application to a console type application and pointed it to a module containing just Sub Main, i.e.
Module mdlConsole
Sub Main(ByVal cmdArgs() As String)
If cmdArgs.Length = 0 Then
Dim frm As New frmMain
frm.Show()
End If
End Sub
End Module
Ideally if no arguments are supplied then the program would simply launch the primary form. The goal is to make this program (optionally) script-able from the command line. If arguments are supplied then the application form is not loaded and processes its features based off the command line arguments supplied.
As it is now, the program runs, briefly launches the form (frmMain) and then closes. What am I doing wrong or missing?
If you're not keen on giving me the answer, I'd be happy to be pointed in the right direction also. I don't expect anyone to just supply answers. I need to learn also.
Thanks!
For Winforms, you need to 'run' the App object, passing a form to use:
Sub Main(ByVal cmdArgs() As String)
If cmdArgs.Length = 0 Then
Dim frm As New frmMain
Application.Run(frm)
Else
' cmd line version
End If
End Sub
I see in your comment that you'd like to remove the console window that appears when running the form version of the program with the solution currently proposed. I cannot comment due to lack of reputation, so I will make this a full-fledged answer.
Consider approaching this from an inverse perspective: if you write the program as a forms application, opening it by default will bring up the form. But in the Form1_Load event, check the command line arguments; if they are greater than 0, simply run your (abbreviated) code logic here. At the end of the code, simply run Application.Exit(), like so:
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
If My.Application.CommandLineArgs.Count > 0 Then
' Execute (abbreviated) code logic
' When finished, exit the program
Application.Exit()
End If
End Sub
This can also make your code cleaner and more practical if you're relying on a user-interface, because you can still access the values of form elements that the user would otherwise be modifying - but without the form showing on the screen (unless you prompt it to with a MsgBox or such).
This also works very nicely for Scheduled Tasks, as the user can run them manually with a user-interface, while the program executes without being visible via a scheduled task.
Kind of a follow-on to Chad's solution above I used the steps defined in How to have an invisible start up form? to avoid showing my form.
In short, create an Overrides subroutine that gets launched before Form1_Load:
This worked for me:
Protected Overrides Sub SetVisibleCore(ByVal value As Boolean)
If Not Me.IsHandleCreated Then
Me.CreateHandle()
value = False
MyBase.SetVisibleCore(value)
Else
Exit Sub
End If
If My.Application.CommandLineArgs.Count > 0 Then
MsgBox("Argument Sensed!")
' Execute (abbreviated) code logic
' When finished, exit the program
Me.Close()
Application.Exit()
Else
MyBase.SetVisibleCore(True)
End If
End Sub
I am confused. Yes i understand I can't use the same backgroundworker to do two tasks at the same time. What I do not understand is this. Here is my code (all this thing does is set the marqueeanimationspeed of a progress bar...
'THE FOLLOWING SUB TOGGLES THE PROGRESS BAR
Private Sub BackgroundWorker1_DoWork(ByVal sender As System.Object, ByVal e As System.ComponentModel.DoWorkEventArgs) Handles BackgroundWorker1.DoWork
'CHECK THE STATE OF THE PROGRESS BAR AND TOGGLE IT
If ToolStripProgressBar1.MarqueeAnimationSpeed = 0 Then
ToolStripProgressBar1.MarqueeAnimationSpeed = 22
End If
ToolStripProgressBar1.MarqueeAnimationSpeed = 0
End Sub
OK, so how long can this possibly take? Doesn't the worker do the task and exit? So I put in a pause (system.threading.thread.sleep(2000)... same problem, made it 20 seconds... same problem.
So I am assuming this is a simple thing I'm missing, but I've spent more than an hour searching and I don't get it.
All I am trying to accomplish here is to start the marquee progress bar while the UI is running something else, and then stop it. I assume I can create another backgroundworker and just use it, but I want to understand why the first one is not done with the task.
Thanks, and again, yes I spent an hour searching and I find all kinds of "solutions" but no explanation as to why this thing is not finished.
OK SO HERE IS THE SUB CALLING THE BGW
'THE FOLLOWING SUB FIRES THE SETTING CONNECTION STRINGS SUB
Private Sub SetCSButton_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles SetCSButton.Click
'START THE PROGRESS BAR & CHANGE THE LABEL
BackgroundWorker1.RunWorkerAsync()
Threading.Thread.Sleep(1000)
ToolStripStatusLabel1.Text = "Preparing the connection strings..."
Me.Refresh()
thread3 = New System.Threading.Thread(AddressOf SetConnectionStrings)
thread3.Start()
'STOP THE PROGRESS BAR & CHANGE THE LABEL
BackgroundWorker2.RunWorkerAsync()
Threading.Thread.Sleep(1000)
ToolStripStatusLabel1.Text = "Standing by..."
Me.Refresh()
End Sub**strong text**
I had a 20second delay but still the first BGW does not finish. I know this is something simple but I dont understand, that's all I am after here.
I DID change the code and do not use the same methodology as I was trying at the time I wrote this question... What I do not understand is why a simple operation is never, apparently, finishing... having said that, it DOES finish as I was able to show a msgbox using the runworkercompleted event. So, as I tried and failed to convey, thbis is not about the right or wrong way to code, I know it wa wrong and was just trying to be quick and dirty, regardless of that, I am not doing that now, but I do not understand why the BGW is "still working". There must be some simple thing I am ignorant about.
Thanks
The error is not in the posted code but where you start the Bgw.
But it is all irrelevant because you should not touch the GUI from DoWork:
Private Sub BackgroundWorker1_DoWork(...) Handles BackgroundWorker1.DoWork
'CHECK THE STATE OF THE PROGRESS BAR AND TOGGLE IT
If ToolStripProgressBar1.MarqueeAnimationSpeed = 0 Then ' Boom, cross-threading violation
ToolStripProgressBar1.MarqueeAnimationSpeed = 22
End If
I don't think you need a Bgw, thread or timer here. Just change the speed before/after the slow action.