3

I've hit an issue with using the Dialog Preserve command. I get the error message "Invalid Dialog preserve command. There is no active dialog". As far as I can tell I've followed the guidance provided in the MapBasic reference guide. Here is a subset of my code which reproduces the error in MapInfo 11.5 and 12

' * Include mapbasic.def - required for various MapBasic commands including "CMD_INFO_XXX"

Include "mapbasic.def"




' * OK button handler for Dialog

Declare Sub gmeu_goToGridReference ( gmeu_userEnteredGridRef As String )

Sub gmeu_goToGridReference ( gmeu_userEnteredGridRef As String )

    Dialog Preserve
    Print "You entered: " + gmeu_userEnteredGridRef

End Sub




Declare Sub Main

Sub Main

    ' * Create a custom dialog box to obtain the grid reference from the user

    Dim gmeu_userEnteredGridRef As String

    Dialog
        Title "Go to Grid Reference"
        Control StaticText
            Title "Enter a grid reference:"
        Control EditText
            Into gmeu_userEnteredGridRef
        Control OKButton
       Control CancelButton
    If CommandInfo( CMD_INFO_DLG_OK ) Then
        Call gmeu_goToGridReference( gmeu_userEnteredGridRef )
    End If

End Sub

I've tried moving the position of the declare statements from the top to just before the Subs are coded but this has not changed the result - I didn't think it would but wanted to be thorough.

2

What you are describing (The Calling clause) is not a work-around; it is the documented way that MapBasic custom dialogs work. See the documentation for the Dialog Preserve statement, under "Restrictions".

As far as sharing the string with the "Calling" sub, instead of using a Global, use the ReadControlValue function to examine the current value of the text box. I don't think the MB dialog will assign the text to the string variable until the dialog is truly dismissed, in which case a Global would not work.

  • Dave Smith (I am a Pitney Bowes employee)
  • Thanks Dave. I've reverted to using the ReadControlValue function instead. It does exactly what I need – Paul Barrington Aug 9 '16 at 13:25
2

The problem is that when you call CommandInfo(CMD_INFO_DLG_OK) the dialog box is dismissed (as this signals that the user has clicked ok), hence the error message you were getting. The call to CommandInfo(CMD_INFO_DLG_OK) also triggers the values from your controls to be written to any variables you've assigned (e.g. in your case Into gmeu_userEnteredGridRef) - if you don't call CommandInfo(CMD_INFO_DLG_OK) then the value will never get assigned to the variable.

It looks like you want your dialog to be modeless (able to stay open and not lock the main application window while it is open). Unfortunately a pure MapBasic application only supports modal dialog boxes. If you want your dialog to be modeless your best bet is to use a custom .NET dialog box compiled into a dll and called from your MapBasic application. You might find some of the information here helpful with regards to achieving that.

  • Thanks T_Bacon. Unfortunately for me you are correct. I was hoping to write a solution in pure MapBasic but I now know this is not possible. – Paul Barrington Jul 19 '16 at 16:37
  • @T_Bacon, you are almost correct. However, it's not the CommandInfo(CMD_INFO_DLG_OK) that dismisses the dialog. It's the user when closing the dialog via the OKButton, CancelButton or the cross in the upper right corner. The Dialog Preserve can only be used within a handler of a control on the dialog. It's often used when validating the users entry in the handler of the OKButton. If you come across an issue, you can use the Dialog Preserve statement to "recreate" the dialog as it was when the user clicked the OKButton. But you are right, modeless dialogs can't be created with MapBasic only. – Peter Horsbøll Møller Aug 2 '16 at 9:23
0

I have figured out a workaround. Instead of calling Sub gmeu_goToGridReference via

If CommandInfo( CMD_INFO_DLG_OK )

I am instead using the 'Calling' command directly below the OKButton control as follows

Dialog
Title "Go to Grid Reference"
Control StaticText
    Title "Enter a grid reference:"
Control EditText
    Into gmeu_userEnteredGridRef
Control OKButton
    Calling gmeu_goToGridReference
Control CancelButton

The disadvantage is that I can't pass a variable to a Sub called in this way. So for the time being I have made gmeu_userEnteredGridRef Global. For the avoidance of doubt the full working source code is as follows...

' Simple script to isolate and test the Dialog Preserve command


' * Include mapbasic.def - required for various MapBasic commands including "CMD_INFO_XXX"

Include "mapbasic.def"


Declare Sub Main
Declare Sub gmeu_goToGridReference


Global gmeu_userEnteredGridRef As String


Sub Main

    ' * Create a custom dialog box to obtain the grid reference from the user

    Dialog
        Title "Go to Grid Reference"
        Control StaticText
            Title "Enter a grid reference:"
        Control EditText
            Into gmeu_userEnteredGridRef
        Control OKButton
            Calling gmeu_goToGridReference
        Control CancelButton

End Sub


' * OK button handler for Dialog

Sub gmeu_goToGridReference

    Dialog Preserve
    Note "You entered: " + gmeu_userEnteredGridRef

End Sub

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.