none
goto statement in sub buttonclicked RRS feed

  • Question

  • So I was programming this program, but when I wanted to make a "Back to menu" button with GoTo, but it didn't work, so I tried to make the goto a sub, but when i do that, the program only shows a blank GraphicsWindow, Like GraphicsWindow.Show.

    What did I do wrong?

    With the goto:

    GraphicsWindow.BackgroundColor = "white"
    GraphicsWindow.Height = 400
    GraphicsWindow.Width = 600
    GraphicsWindow.BrushColor = "black"
    main_menu:
    GraphicsWindow.Clear()
    GraphicsWindow.DrawText(30,110,"Kies wat je wil berekenen:")
    vergrotingsfactor = Controls.AddButton("N (vergrotingsfactor)",30,150)
    brandpuntsafstand = Controls.AddButton("f (brandpuntsafstand)",30,200)
    voorwerpsafstand = Controls.AddButton("v (voorwerpsafstand)",30,250)
    beeldsafstand = Controls.AddButton("b (beeldsafstand)",30,300)
    fancynatuurkundeschrift = ImageList.LoadImage("C:\Users\HP\Pictures\voor na.png")
    GraphicsWindow.DrawImage(fancynatuurkundeschrift,0,0)
    Controls.ButtonClicked = buttonClicked
    Sub buttonclicked
    If Controls.LastClickedButton = vergrotingsfactor Then
      GraphicsWindow.Clear()
      GraphicsWindow.DrawImage(fancynatuurkundeschrift,0,0)
      GraphicsWindow.DrawText(30,110,"Vul de gegevens in (variabele is bijv bij beide do hoogte of de breedte):")
      GraphicsWindow.DrawText(30,160,"voorwerpsvariabele")
      variabele1textbox = Controls.AddTextBox(30,180)
      GraphicsWindow.DrawText(230,160,"beeldvariablele")
      variabele2textbox = Controls.AddTextBox(230,180)
      berekenknopvergrotingsfactor = Controls.AddButton("Bereken",30,230)
    ElseIf Controls.LastClickedButton = berekenknopvergrotingsfactor Then
      variabele1 = Controls.GetTextBoxText(variabele1textbox)
      variabele2 = Controls.GetTextBoxText(variabele2textbox)
      GraphicsWindow.Clear()
      GraphicsWindow.DrawImage(fancynatuurkundeschrift,0,0)
      GraphicsWindow.DrawText(30,110,"Vul de gegevens in (variabele is bijv bij beide do hoogte of de breedte):")
      GraphicsWindow.DrawText(30,160,"voorwerpsvariabele")
      variabele1textbox = Controls.AddTextBox(30,180)
      GraphicsWindow.DrawText(230,160,"beeldvariablele")
      variabele2textbox = Controls.AddTextBox(230,180)
      berekenknopvergrotingsfactor = Controls.AddButton("Bereken",30,230)
      Antwoord = variabele1 / variabele2
      GraphicsWindow.DrawText(30, 280,Antwoord)
      afrondknop = Controls.AddButton("afronden",100, 230)
      Terugknop = Controls.AddButton("Terug",400,300)
      Elseif Controls.LastClickedButton = afrondknop then
        Afgerondantwoord = Math.Round(Antwoord*100)/100
        GraphicsWindow.DrawText(30,300,Afgerondantwoord)
      Elseif Controls.LastClickedButton = brandpuntsafstand then
        GraphicsWindow.Clear()
        GraphicsWindow.DrawImage(fancynatuurkundeschrift,0,0)
        GraphicsWindow.DrawText(30,110,"vul de gegevens in:")
        GraphicsWindow.DrawText(30,160,"beeldafstand")
        variabele3textbox = Controls.AddTextBox(30,180)
        GraphicsWindow.DrawText(230,160,"voorwerpsafstand")
        variabele4textbox = Controls.AddTextBox(230,180)
      Elseif Controls.LastClickedButton = Terugknop then
       Goto main_menu
        EndIf
    EndSub
    
    buttonclicked()
    

    With a sub in stead of a goto:

    GraphicsWindow.BackgroundColor = "white"
    GraphicsWindow.Height = 400
    GraphicsWindow.Width = 600
    GraphicsWindow.BrushColor = "black"
    sub main_menu
    GraphicsWindow.Clear()
    GraphicsWindow.DrawText(30,110,"Kies wat je wil berekenen:")
    vergrotingsfactor = Controls.AddButton("N (vergrotingsfactor)",30,150)
    brandpuntsafstand = Controls.AddButton("f (brandpuntsafstand)",30,200)
    voorwerpsafstand = Controls.AddButton("v (voorwerpsafstand)",30,250)
    beeldsafstand = Controls.AddButton("b (beeldsafstand)",30,300)
    fancynatuurkundeschrift = ImageList.LoadImage("C:\Users\HP\Pictures\voor na.png")
    GraphicsWindow.DrawImage(fancynatuurkundeschrift,0,0)
    EndSub
    Controls.ButtonClicked = buttonClicked
    Sub buttonclicked
    If Controls.LastClickedButton = vergrotingsfactor Then
      GraphicsWindow.Clear()
      GraphicsWindow.DrawImage(fancynatuurkundeschrift,0,0)
      GraphicsWindow.DrawText(30,110,"Vul de gegevens in (variabele is bijv bij beide do hoogte of de breedte):")
      GraphicsWindow.DrawText(30,160,"voorwerpsvariabele")
      variabele1textbox = Controls.AddTextBox(30,180)
      GraphicsWindow.DrawText(230,160,"beeldvariablele")
      variabele2textbox = Controls.AddTextBox(230,180)
      berekenknopvergrotingsfactor = Controls.AddButton("Bereken",30,230)
    ElseIf Controls.LastClickedButton = berekenknopvergrotingsfactor Then
      variabele1 = Controls.GetTextBoxText(variabele1textbox)
      variabele2 = Controls.GetTextBoxText(variabele2textbox)
      GraphicsWindow.Clear()
      GraphicsWindow.DrawImage(fancynatuurkundeschrift,0,0)
      GraphicsWindow.DrawText(30,110,"Vul de gegevens in (variabele is bijv bij beide do hoogte of de breedte):")
      GraphicsWindow.DrawText(30,160,"voorwerpsvariabele")
      variabele1textbox = Controls.AddTextBox(30,180)
      GraphicsWindow.DrawText(230,160,"beeldvariablele")
      variabele2textbox = Controls.AddTextBox(230,180)
      berekenknopvergrotingsfactor = Controls.AddButton("Bereken",30,230)
      Antwoord = variabele1 / variabele2
      GraphicsWindow.DrawText(30, 280,Antwoord)
      afrondknop = Controls.AddButton("afronden",100, 230)
      Terugknop = Controls.AddButton("Terug",400,300)
      Elseif Controls.LastClickedButton = afrondknop then
        Afgerondantwoord = Math.Round(Antwoord*100)/100
        GraphicsWindow.DrawText(30,300,Afgerondantwoord)
      Elseif Controls.LastClickedButton = brandpuntsafstand then
        GraphicsWindow.Clear()
        GraphicsWindow.DrawImage(fancynatuurkundeschrift,0,0)
        GraphicsWindow.DrawText(30,110,"vul de gegevens in:")
        GraphicsWindow.DrawText(30,160,"beeldafstand")
        variabele3textbox = Controls.AddTextBox(30,180)
        GraphicsWindow.DrawText(230,160,"voorwerpsafstand")
        variabele4textbox = Controls.AddTextBox(230,180)
      Elseif Controls.LastClickedButton = Terugknop then
        main_menu()
        EndIf
    EndSub
    
    buttonclicked()
    

    Sorry for the wrong colors, but i couldn't find small basic

    This is one of my first programs, so I apologize in advance for bad programming

    Friday, September 12, 2014 8:19 PM

Answers

  • Good question.

    You cannot use GoTo to jump into or out of a subroutine.

    This is because when a subroutine is called, where it is called from is recorded (Call Stack) so it knows where to return to when the subroutine ends.  When the subroutine ends it returns where it was called from and the call stack is unwound.  Basically jumping in or out of a subroutine with a GoTo corrupts the call stack an things will go badly from there.

    • Proposed as answer by Ezra94 Friday, September 12, 2014 8:33 PM
    • Marked as answer by Steven Jelsma Saturday, September 13, 2014 3:40 PM
    Friday, September 12, 2014 8:28 PM
    Moderator
  • It is difficult to run your program since I don't have access to your images so I had to figure out the intend of your program. Here is a prototype: 

    GUI() 
    Controls.ButtonClicked = onButtonClick
    
    Sub GUI
      Controls.AddButton("Main Menu",0,0)
      Controls.AddButton("Select Level",78,0)
    EndSub 
    
    Sub mainMenu 
      GraphicsWindow.DrawText(250,150,"Welcome to the Main Menu")
    EndSub
    
    Sub selectLevel 
      GraphicsWindow.DrawText(250,150,"Select Level") 
    EndSub 
    
    Sub onButtonClick
      If (Controls.GetButtonCaption(Controls.LastClickedButton) = "Main Menu") Then 
        GraphicsWindow.Clear() 
        mainMenu() 
        GUI()
      ElseIf (Controls.GetButtonCaption(Controls.LastClickedButton)= "Select Level") Then 
        GraphicsWindow.Clear() 
        selectLevel()
        GUI()
      EndIf 
    EndSub 
    No Goto statements. When you run the program, two buttons appear. When you press the main menu, you'll be taken there while pressing the select level button will take you to another screen. Going back to the main menu only requires pressing the main menu button. Let me know if you need me to explain anything or need more help. 


    • Proposed as answer by litdevModerator Friday, September 12, 2014 9:41 PM
    • Edited by Ezra94 Friday, September 12, 2014 9:56 PM Reword
    • Marked as answer by Steven Jelsma Saturday, September 13, 2014 3:40 PM
    Friday, September 12, 2014 9:20 PM

All replies

  • Good question.

    You cannot use GoTo to jump into or out of a subroutine.

    This is because when a subroutine is called, where it is called from is recorded (Call Stack) so it knows where to return to when the subroutine ends.  When the subroutine ends it returns where it was called from and the call stack is unwound.  Basically jumping in or out of a subroutine with a GoTo corrupts the call stack an things will go badly from there.

    • Proposed as answer by Ezra94 Friday, September 12, 2014 8:33 PM
    • Marked as answer by Steven Jelsma Saturday, September 13, 2014 3:40 PM
    Friday, September 12, 2014 8:28 PM
    Moderator
  • Hello, S Jelsma 

    I highly recommend reading these two articles by litdiv:

    This article will give you useful alternatives to Goto statements. 

    http://social.technet.microsoft.com/wiki/contents/articles/21075.small-basic-how-to-remove-goto-statements.aspx

    This article will give you some useful programming tips in general (usage of Goto statements are briefly discussed)

    http://social.technet.microsoft.com/wiki/contents/articles/15081.small-basic-programming-tips.aspx

    From my experience, I would recommend limiting your use in Goto statements. There is usually a more efficient way to write your code without one. The less Goto statements, the more smoothly your program will run and the logic will be clearer to read, especially for other programmer who will read your programs. Have fun programming. 

    • Edited by Ezra94 Friday, September 12, 2014 8:48 PM Reword
    Friday, September 12, 2014 8:37 PM
  • so how should I do it now, or is it just impossible with microsoft small basic?

    I now did this, but it still doesn't work:

    'In the sub'
    Elseif controls.LastClickedButton = Terugknop then
        Terugknop =1
    
    'out the sub'
    If Terugknop = 1 Then
      Goto main_menu
      Terugknop = 0
      EndIf

    Terugknop is Dutch for "Backbutton"


    • Edited by Steven Jelsma Friday, September 12, 2014 8:58 PM new piece of code
    Friday, September 12, 2014 8:48 PM
  • To help it is easiest to start with short code.  I recommend:

    1] Put all the subroutine AFTER the main code

    2] Try not to use GoTo at all if you can

    So we do the main stuff at the top - create the GW - register button click event and call main_menu

    If you can simplify the code to show the problem you have - I mean just one button, no images etc - something we can easily reproduce and understand what it it is supposed to do and see that it doesn't.

    GraphicsWindow.BackgroundColor = "white"
    GraphicsWindow.Height = 400
    GraphicsWindow.Width = 600
    GraphicsWindow.BrushColor = "black"
    Controls.ButtonClicked = buttonClicked
    main_menu()
    
    sub main_menu
      GraphicsWindow.Clear()
      GraphicsWindow.DrawText(30,110,"Kies wat je wil berekenen:")
      vergrotingsfactor = Controls.AddButton("N (vergrotingsfactor)",30,150)
      brandpuntsafstand = Controls.AddButton("f (brandpuntsafstand)",30,200)
      voorwerpsafstand = Controls.AddButton("v (voorwerpsafstand)",30,250)
      beeldsafstand = Controls.AddButton("b (beeldsafstand)",30,300)
      fancynatuurkundeschrift = ImageList.LoadImage("C:\Users\HP\Pictures\voor na.png")
      GraphicsWindow.DrawImage(fancynatuurkundeschrift,0,0)
    EndSub
    
    Sub buttonclicked
      If Controls.LastClickedButton = vergrotingsfactor Then
        GraphicsWindow.Clear()
        GraphicsWindow.DrawImage(fancynatuurkundeschrift,0,0)
        GraphicsWindow.DrawText(30,110,"Vul de gegevens in (variabele is bijv bij beide do hoogte of de breedte):")
        GraphicsWindow.DrawText(30,160,"voorwerpsvariabele")
        variabele1textbox = Controls.AddTextBox(30,180)
        GraphicsWindow.DrawText(230,160,"beeldvariablele")
        variabele2textbox = Controls.AddTextBox(230,180)
        berekenknopvergrotingsfactor = Controls.AddButton("Bereken",30,230)
      ElseIf Controls.LastClickedButton = berekenknopvergrotingsfactor Then
        variabele1 = Controls.GetTextBoxText(variabele1textbox)
        variabele2 = Controls.GetTextBoxText(variabele2textbox)
        GraphicsWindow.Clear()
        GraphicsWindow.DrawImage(fancynatuurkundeschrift,0,0)
        GraphicsWindow.DrawText(30,110,"Vul de gegevens in (variabele is bijv bij beide do hoogte of de breedte):")
        GraphicsWindow.DrawText(30,160,"voorwerpsvariabele")
        variabele1textbox = Controls.AddTextBox(30,180)
        GraphicsWindow.DrawText(230,160,"beeldvariablele")
        variabele2textbox = Controls.AddTextBox(230,180)
        berekenknopvergrotingsfactor = Controls.AddButton("Bereken",30,230)
        Antwoord = variabele1 / variabele2
        GraphicsWindow.DrawText(30, 280,Antwoord)
        afrondknop = Controls.AddButton("afronden",100, 230)
        Terugknop = Controls.AddButton("Terug",400,300)
      Elseif Controls.LastClickedButton = afrondknop then
        Afgerondantwoord = Math.Round(Antwoord*100)/100
        GraphicsWindow.DrawText(30,300,Afgerondantwoord)
      Elseif Controls.LastClickedButton = brandpuntsafstand then
        GraphicsWindow.Clear()
        GraphicsWindow.DrawImage(fancynatuurkundeschrift,0,0)
        GraphicsWindow.DrawText(30,110,"vul de gegevens in:")
        GraphicsWindow.DrawText(30,160,"beeldafstand")
        variabele3textbox = Controls.AddTextBox(30,180)
        GraphicsWindow.DrawText(230,160,"voorwerpsafstand")
        variabele4textbox = Controls.AddTextBox(230,180)
      Elseif Controls.LastClickedButton = Terugknop then
        main_menu()
      EndIf
    EndSub
    

    Friday, September 12, 2014 9:19 PM
    Moderator
  • It is difficult to run your program since I don't have access to your images so I had to figure out the intend of your program. Here is a prototype: 

    GUI() 
    Controls.ButtonClicked = onButtonClick
    
    Sub GUI
      Controls.AddButton("Main Menu",0,0)
      Controls.AddButton("Select Level",78,0)
    EndSub 
    
    Sub mainMenu 
      GraphicsWindow.DrawText(250,150,"Welcome to the Main Menu")
    EndSub
    
    Sub selectLevel 
      GraphicsWindow.DrawText(250,150,"Select Level") 
    EndSub 
    
    Sub onButtonClick
      If (Controls.GetButtonCaption(Controls.LastClickedButton) = "Main Menu") Then 
        GraphicsWindow.Clear() 
        mainMenu() 
        GUI()
      ElseIf (Controls.GetButtonCaption(Controls.LastClickedButton)= "Select Level") Then 
        GraphicsWindow.Clear() 
        selectLevel()
        GUI()
      EndIf 
    EndSub 
    No Goto statements. When you run the program, two buttons appear. When you press the main menu, you'll be taken there while pressing the select level button will take you to another screen. Going back to the main menu only requires pressing the main menu button. Let me know if you need me to explain anything or need more help. 


    • Proposed as answer by litdevModerator Friday, September 12, 2014 9:41 PM
    • Edited by Ezra94 Friday, September 12, 2014 9:56 PM Reword
    • Marked as answer by Steven Jelsma Saturday, September 13, 2014 3:40 PM
    Friday, September 12, 2014 9:20 PM
  • Thanks Ezra, You really helped me out, it worked!

    The intend of my program was a program that can Calculate basic Physics calculations, but I wrote the code variables in my native language(dutch) so it was to be expected that you didn't guessed the intent ;)

    Regards, Steven



    • Edited by Steven Jelsma Friday, September 12, 2014 9:40 PM corrections
    Friday, September 12, 2014 9:39 PM