Msgbox in Accelerated Surface Touch's sub

johnaaronrose

Active Member
Licensed User
Longtime User
I seem to have my app stuck repeatedly entering acsfMap_Draw in the following (where acsfmap is an Accelerated Surface):

B4X:
Sub acsfMap_Draw (AC As AS_Canvas)
Dim xc, yc, x1, y1, x2, y2, x3, y3 As Int
Msgbox("ScreenX="&MapPoint.ScreenX&",ScreenY="&MapPoint.ScreenY, "acsf_Draw")
If Not(acsfMap.Enabled) Then
  Msgbox("Not drawing "&"acsfMap.Enabled="&acsfMap.Enabled, "acsfMap_Draw")
  Return
End If

I'm setting acsfMap.Enabled to False or True elsewhere (e.g. in Activity_Create or Activity_Resume). acsfMap is initialized & view added in Activity_Create.

Could the cause be due to not using CallSubDelayed rather than using the Msgbox command above? I've been trying to find an example of this without success. i did not understand the posts about CallSubDelayed in the Dev Forum. Could anyone point me to an explanation and/or an example of it?
 

johnaaronrose

Active Member
Licensed User
Longtime User
MsgBox should never be called in an event (same thing for DoEvents), especially the events of my libraries. If you want to call it, use another sub. Example:

B4X:
Sub MyEvent
   CallSubDelayed(Me, "Display_MsgBox")
End sub

Sub Display_MsgBox
   MsgBox(....
End sub

I don't understand the documentation on CallSubDelayed: it seems to say that the message wiil be displayed after the code in the rest of MyEvent (in your code) has executed. I want it to happen immediately followed by executing the rest of the code in MyEvent. Is that what happens?

Also, I get a compile error (when I try to use Msgbox2 & analyse the answer) of:
Error description: Cannot assign void value.
Occurred on line: 122
Answ = CallSubDelayed(Me, "DisplayMsgbox2")
Word: )

Code snippet:

B4X:
Sub Process_Globals
Private MsgBoxDetail As String
Private MsgboxTitle As String

Sub ...
Dim Answ As Int
MsgBoxDetail = "Do you really want to quit the program?"
MsgboxTitle = "A T T E N T I O N"
Answ = CallSubDelayed(Me, "DisplayMsgbox2")
If Answ = DialogResponse.NEGATIVE Then
  Return True
End If
Sub DisplayMsgbox2 As Int
  Return Msgbox2(MsgBoxDetail, MsgboxTitle, "Yes", "", "No", Null)
End Sub
 
Upvote 0

Informatix

Expert
Licensed User
Longtime User
I don't understand the documentation on CallSubDelayed: it seems to say that the message wiil be displayed after the code in the rest of MyEvent (in your code) has executed. I want it to happen immediately followed by executing the rest of the code in MyEvent. Is that what happens?

In this case, you have to move all your code to the function called.
Example:
B4X:
Sub MyEvent_Click
    CallSubDelayed(Me, "Display_MsgBox")
End Sub

Sub Display_MsgBox
    Dim Answer As Int = MsgBox2(...)
    If Answer = DialogResponse.NEGATIVE Then
        ....
    End If
End Sub

If your event is Activity_OnKeyPressed, then you have to return true in the event to cancel any further action, and in Display_Msgbox, you call Activity.Finish if the answer is positive.
 
Upvote 0

johnaaronrose

Active Member
Licensed User
Longtime User
In this case, you have to move all your code to the function called.
Example:
B4X:
Sub MyEvent_Click
    CallSubDelayed(Me, "Display_MsgBox")
End Sub

Sub Display_MsgBox
    Dim Answer As Int = MsgBox2(...)
    If Answer = DialogResponse.NEGATIVE Then
        ....
    End If
End Sub

If your event is Activity_OnKeyPressed, then you have to return true in the event to cancel any further action, and in Display_Msgbox, you call Activity.Finish if the answer is positive.

Thanks. That now works OK. I have a validation routine (amongst other checks, the user must enter 2 characters) for an EditText view. I want to display a Msgbox if the user has made an error and keep the focus on this view; if the user keys a valid value & presses Enter or clicks on another view, I want to move the focus to another specific view. I was told to use the Accessibility Library & use SetNextFocus... commands. The validation works & the appropriate Msgbox displays if the user enters 1 character but the focus always moves to the next view.

B4X:
Sub Process_Globals
Private MsgBoxDetail As String
Private MsgboxTitle As String

Sub edtOSGBGridRef1_FocusChanged (HasFocus As Boolean)
   'Set uppercase
   edtOSGBGridRef1.InputType= Bit.OR(edtOSGBGridRef1.INPUT_TYPE_TEXT, 4096)
   If HasFocus = True Then
     ' Got focus
     Acc.SetNextFocusDown(edtOSGBGridRef1, edtOSGBGridRef2)
     Acc.SetNextFocusUp(edtOSGBGridRef1, edtOSGBGridRef2)
     Acc.SetNextFocusLeft(edtOSGBGridRef1, edtOSGBGridRef2)
     Acc.SetNextFocusDown(edtOSGBGridRef1, edtOSGBGridRef2)
   End If
End Sub

Sub edtOSGBGridRef1_EnterPressed
   If edtOSGBGridRef1Valid Then
     edtOSGBGridRef2.RequestFocus
   Else
     edtOSGBGridRef1.RequestFocus
   End If
End Sub

Sub edtOSGBGridRef1Valid
   Dim GR As String
   GR = edtOSGBGridRef1.Text.Trim
   If GR.Length <> 2 Then
     MsgBoxDetail = "OSGB Grid Reference Map must be 2 characters"
     MsgboxTitle =  "Incorrect OSGB Grid Reference Map"
     CallSubDelayed(Me, "DisplayMsgbox")
   End If

Sub DisplayMsgbox
  Msgbox(MsgBoxDetail, MsgboxTitle)  
End Sub
 
Upvote 0
Top