Android Question Msgbox2Async why doesn't it wait

Discussion in 'Android Questions' started by RB Smissaert, Nov 27, 2018.

  1. RB Smissaert

    RB Smissaert Well-Known Member Licensed User

    In a class I have this:

    Code:
    Sub ShowMsg(strPrompt As String, _
             strTitle 
    As String, _
             iTitleColour 
    As Int, _
             iPromptColour 
    As Int, _
             csPrompt 
    As CSBuilder, _
             bmpIcon 
    As Bitmap, _
             bCancelable 
    As Boolean, _
           bWait 
    As Boolean)
     
     
    Dim csTitle As CSBuilder
     
     
    'so like optional colour argument
     If iTitleColour = 0 Then
      iTitleColour = 
    Colors.RGB(000)
     
    End If
     
     
    If iPromptColour = 0 Then
      iPromptColour = 
    Colors.RGB(000)
     
    End If
     
     csTitle.Initialize.Color(iTitleColour).Append(strTitle).Pop
     
     
    'so csPrompt is like an optional argument, passing Null works fine
     If csPrompt.IsInitialized = False Then
      csPrompt.Initialize.Color(iPromptColour).Append(strPrompt).Pop
     
    End If
     
     
    'can pass Null for no icon
     Msgbox2Async(csPrompt, csTitle, "OK""""", bmpIcon, bCancelable)

     
    If bWait Then
      
    Wait For Msgbox_Result(iResult As Int)
     
    End If
     
    End Sub
    And I call this from Main like this:

    Code:
    Sub DeleteDuplicateSQL
     
    Dim strSQL As String
     
    Dim lAffectedRows As Long
     Msgbox2Async(
    "Are you sure to delete duplicate SQL from the table SQL?", _
         
    "Delete duplicate SQL from table SQL""Yes""No""",  General.bmpIcon32, False)
     
    Wait For Msgbox_Result(result As Int)
     
    If result = -1 Then
      strSQL = 
    "DELETE FROM SQL WHERE ROWID NOT IN(" & _
         
    "SELECT MAX(ROWID) FROM SQL " & _
         
    "GROUP BY SQL)"
      General.SQL1.ExecNonQuery(strSQL)
      lAffectedRows = GetNumberOfChanges
      cEvents.ShowMsg(
    "Duplicate rows deleted: " & lAffectedRows, _
          
    "Delete duplicate SQL from table SQL"00Null, General.bmpIcon32, TrueTrue)
     
    End If
     Msgbox2Async(
    "Are you sure to delete duplicate SQL from the table RUN_SQL?", _
         
    "Delete duplicate SQL from table RUN_SQL""Yes""No""",  General.bmpIcon32, False)
     
    Wait For Msgbox_Result(result As Int)
     
    If result = -1 Then
      strSQL = 
    "DELETE FROM RUN_SQL WHERE ROWID NOT IN(" & _
         
    "SELECT MAX(ROWID) FROM RUN_SQL " & _
         
    "GROUP BY SQL)"
      General.SQL1.ExecNonQuery(strSQL)
      lAffectedRows = GetNumberOfChanges
      cEvents.ShowMsg(
    "Duplicate rows deleted: " & lAffectedRows, _
          
    "Delete duplicate SQL from table RUN_SQL"00Null, General.bmpIcon32, TrueTrue
     
    End If
    End Sub
    Problem is it doesn't wait for the first cEvents.ShowMsg and I see the second Msgbox2Async first and
    the first cEvents.ShowMsg only later. Tried various constructions, eg with Sleep(0), but no success yet.
    How should this be done?

    RBS
     
  2. Computersmith64

    Computersmith64 Well-Known Member Licensed User

    When you're throwing up multiple async dialogs, you need to provide a reference to the ones you want to wait for. So try something like this:

    Code:
    ...

    Private mb As Object = Msgbox2Async(csPrompt, csTitle, "OK""""", bmpIcon, bCancelable)

     
    If bWait Then
      
    Wait For (mb) Msgbox_Result(iResult As Int)
     
    End If
    ...
    Depending on the order in which your dialogs are displaying, this might not the the correct one to be identifying, but you get the idea...

    You can also look at the async dialogs tutorial here -> https://www.b4x.com/android/forum/t...cated-and-async-dialogs-msgbox.79578/#content

    - Colin.
     
  3. RB Smissaert

    RB Smissaert Well-Known Member Licensed User

    Thanks; I tried your idea, but same result.

    RBS
     
  4. Erel

    Erel Administrator Staff Member Licensed User

    The most important rule of resumable subs:
    Wait For or Sleep are equivalent to Return from the calling sub perspective.

    Watch the resumable subs video tutorial and see how to handle it. The solution is simple.

    Also see: [B4X] [XUI] B4XDialog - Custom dialogs
     
  5. RB Smissaert

    RB Smissaert Well-Known Member Licensed User

    OK, thanks and have found this simple solution:

    In Main:

    Code:
    Sub DeleteDuplicateSQL
     
    Dim strSQL As String
     
    Dim lAffectedRows As Long
     
    Dim iResult As Int
     Msgbox2Async(
    "Are you sure to delete duplicate SQL from the table SQL?", _
         
    "Delete duplicate SQL from table SQL""Yes""No""",  General.bmpIcon32, False)
     
    Wait For Msgbox_Result(result As Int)
     
    If result = -1 Then
      strSQL = 
    "DELETE FROM SQL WHERE ROWID NOT IN(" & _
         
    "SELECT MAX(ROWID) FROM SQL " & _
         
    "GROUP BY SQL)"
      General.SQL1.ExecNonQuery(strSQL)
      lAffectedRows = GetNumberOfChanges
      
    wait for (cEvents.ShowMsg("Duplicate rows deleted: " & lAffectedRows, _
              
    "Delete duplicate SQL from table SQL"00Null, General.bmpIcon32, TrueTrue)) _
      Complete (iResult 
    As Int)
     
    End If
     Msgbox2Async(
    "Are you sure to delete duplicate SQL from the table RUN_SQL?", _
         
    "Delete duplicate SQL from table RUN_SQL""Yes""No""",  General.bmpIcon32, False)
     
    Wait For Msgbox_Result(result As Int)
     
    If result = -1 Then
      strSQL = 
    "DELETE FROM RUN_SQL WHERE ROWID NOT IN(" & _
         
    "SELECT MAX(ROWID) FROM RUN_SQL " & _
         
    "GROUP BY SQL)"
      General.SQL1.ExecNonQuery(strSQL)
      lAffectedRows = GetNumberOfChanges
      
    wait for (cEvents.ShowMsg("Duplicate rows deleted: " & lAffectedRows, _
              
    "Delete duplicate SQL from table RUN_SQL"00Null, General.bmpIcon32, TrueTrue)) _
      Complete (iResult 
    As Int) 
     
    End If
    End Sub
    And in the class:

    Code:
    Public Sub ShowMsg(strPrompt As String, _
             strTitle 
    As String, _
             iTitleColour 
    As Int, _
             iPromptColour 
    As Int, _
             csPrompt 
    As CSBuilder, _
             bmpIcon 
    As Bitmap, _
             bCancelable 
    As Boolean, _
           bWait 
    As Boolean) As ResumableSub
     
     
    Dim csTitle As CSBuilder
     
     
    'so like optional colour argument
     If iTitleColour = 0 Then
      iTitleColour = 
    Colors.RGB(000)
     
    End If
     
     
    If iPromptColour = 0 Then
      iPromptColour = 
    Colors.RGB(000)
     
    End If
     
     csTitle.Initialize.Color(iTitleColour).Append(strTitle).Pop
     
     
    'so csPrompt is like an optional argument, passing Null works fine
     If csPrompt.IsInitialized = False Then
      csPrompt.Initialize.Color(iPromptColour).Append(strPrompt).Pop
     
    End If
     
     
    'can pass Null for no icon
     Msgbox2Async(csPrompt, csTitle, "OK""""", bmpIcon, bCancelable)

     
    If bWait Then
      
    Wait For Msgbox_Result(iResult As Int)
      
    Return iResult
     
    End If
     
    End Sub
    I guess this is the solution you had in mind.
    I was hoping I could leave the Wait For (
    and _
    Complete (iResult As Int)
    out of the calling Sub and only have this in the class Sub. Reason for this is that ShowMsg
    is called in many places in Main and also in other modules, so it would save some typing.
    In any case this works fine now.

    RBS
     
  6. Computersmith64

    Computersmith64 Well-Known Member Licensed User

    Fyi - you can use the DialogResponse object (https://www.b4x.com/android/help/constants.html#dialogresponse) to check your result instead of using -1 to check for positive. Same thing, but just makes the code a bit more readable when you come back years later & can't remember what it was you were trying to do... :)

    Eg:
    Code:
    Msgbox2Async("Are you sure to delete duplicate SQL from the table SQL?", _
         
    "Delete duplicate SQL from table SQL""Yes""No""",  General.bmpIcon32, False)
     
    Wait For Msgbox_Result(result As Int)
     
    If result = DialogResponse.POSITIVE Then
    ...
    - Colin.
     
  7. RB Smissaert

    RB Smissaert Well-Known Member Licensed User

    Yes, thanks, that makes sense.

    RBS
     
Loading...
  1. This site uses cookies to help personalise content, tailor your experience and to keep you logged in if you register.
    By continuing to use this site, you are consenting to our use of cookies.
    Dismiss Notice