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.

PolyGeo
65.5k29 gold badges115 silver badges350 bronze badges
asked Jul 19, 2016 at 10:03

3 Answers 3

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)
answered Aug 1, 2016 at 16:39
1
  • Thanks Dave. I've reverted to using the ReadControlValue function instead. It does exactly what I need Commented Aug 9, 2016 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.

answered Jul 19, 2016 at 15:26
2
  • 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. Commented Jul 19, 2016 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. Commented Aug 2, 2016 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
answered Jul 19, 2016 at 14:20

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.