Mapinfo Mapbasic v17 0 0 User Guide
Mapinfo Mapbasic v17 0 0 User Guide
Mapinfo Mapbasic v17 0 0 User Guide
Version 17.0
User Guide
Notices
Copyright
© 2006-2018 TomTom International BV. All Rights Reserved. This material is proprietary and the
subject of copyright protection and other intellectual property rights owned or licensed to TomTom.
The use of this material is subject to the terms of a license agreement. You will be held liable for
any unauthorized copying or disclosure of this material.
Microsoft Bing: All contents of the Bing service are Copyright © 2018 Microsoft Corporation and/or
its suppliers, One Microsoft Way, Redmond, WA 98052, USA. All rights reserved. Microsoft or its
suppliers own the title, copyright, and other intellectual property rights in the Bing service and content.
Microsoft, Windows, Windows Live, Windows logo, MSN, MSN logo (butterfly), Bing, and other
Microsoft products and services may also be either trademarks or registered trademarks of Microsoft
in the United States and/or other countries.
This product contains 7-Zip, which is licensed under GNU Lesser General Public License, Version
3, 29 June 2007 with the unRAR restriction. The license can be downloaded from
http://www.7-zip.org/license.txt. The GNU License may be downloaded from
http://www.gnu.org/licenses/lgpl.html. The source code is available from http://www.7-zip.org.
Products named herein may be trademarks of their respective manufacturers and are hereby
recognized. Trademarked names are used editorially, to the benefit of the trademark owner, with
no intent to infringe on the trademark.
4 - MapBasic Fundamentals
In this section
What's New 9
System Requirements 9
Installing the MapBasic Development Environment 10
MapBasic File Names and File Types 10
MapBasic Documentation Set 13
Conventions Used in This Manual 15
Getting Technical Support 16
Getting Started
What's New
System Requirements
This product is tested on the following Microsoft Windows Desktop Operating Systems:
• Windows 10 64-bit
• Windows 8.1 64-bit
• Windows 7 Ultimate 64-bit SP1
• Windows 2016 Server 64-bit
• Windows 2012 Server R2 64-bit SP1
• Windows 2012 Server R2 64-bit with XenApp 7.5
• Windows 2008 Server R2 64-bit SP1
• Windows 2008 Server R2 64-bit SP1 with XenApp 6.0
System Notes
The following are the hardware peripherals and disk space requirements:
• Display – Any display adapter supported by Windows.
• Mouse – Any mouse or pointing device supported by Windows.
• Disk Space – The minimum suggested disk space is 10 MB.
MapInfo Pro can run applications created with current or earlier versions of MapBasic.
QT Assistant 5.2.0
This product contains QT Assistant, version 5.2.0, which is licensed under GNU Lesser General
Public License, Version 2.1, February 1999. The license can be downloaded from:
http://www.gnu.org/licenses/lgpl-2.1.txt. The source code for this software is available from
http://qt-project.org/downloads.
Installation
The MapBasic development environment is free. You can download a copy of MapBasic from the
Pitney Bowes Inc. web site, at
http://www.pitneybowes.com/us/location-intelligence/geographic-information-systems/mapbasic.html,
by selecting SUPPORT PRODUCTS Location Intelligence and GIS and then clicking the MapBasic
link. There is also information there about building custom applications and integrating MapInfo Pro
into your application using the MapBasic development environment, go to
http://www.pitneybowes.com/us/location-intelligence/geographic-information-systems/mapbasic.html.
Starting MapBasic
Enums.def Enumerated defines for use with New Ribbon User Interface
extensibility.
MapBasicHelp.exe executable file which runs the MapBasic Help from outside the
application.
ExtensibilityReferenceHelp.exe executable file which runs the Extensibility Reference Help from
outside the application.
IntegratedMappingReferenceHelp.exe executable file which runs the Integrated Mappping Reference Help
from outside the application.
mbres.dll Part of the software; contains resources such as strings and dialog
boxes.
mihelp.dll Part of the QT Assistant tool; contains resources for the MapBasic
on-line help.
As you use the MapBasic development environment, you produce files with the following extensions:
filename.mbo Object files (compiled .mb for a project that references a method in another module or it lacks
a sub main)
filename.err Error listings, generated if you compile a program that has compilation errors.
Terms
This manual addresses the application developer as you, and refers to the person using an application
as the user. For example:
The terms program and application are used in the following manner:
• A program is a text file typed in by you, the programmer. Typically, MapBasic program files have
the extension .MB.
• An application file is a binary file executable by MapInfo Pro. The application file must be present
when the user runs the application. MapBasic creates the application file when you compile your
program. MapBasic application files typically have the extension .MBX (MapBasic eXecutable).
• A command is an item that you choose from a menu. For example, to open a file, choose the Open
command from the File menu.
• A statement is an instruction you can issue from a MapBasic program. For example, a MapBasic
program can issue a Select statement to select one or more rows from a table.
Typographical Conventions
In the examples that appear in this manual, the first letter of each MapBasic language keyword is
capitalized. However, you are not required to use the same capitalization when you type in your
own programs. If you prefer, you can enter your programs using upper case, lower case, or mixed
case.
References to menu commands in the MapBasic development environment use the greater-than
sign (>), as in the following example:
• Choose the FileNew command to open a new Edit window.
The expression "FileNew" refers to the New command on the File menu.
Pitney Bowes Inc. offers a free support period on all new software purchases and upgrades, so you
can be productive from the start. Once the free period ends, Pitney Bowes Inc. offers a broad
selection of extended support services for individual, business, and corporate users.
Technical Support is here to help you, and your call is important. This section lists the information
you need to provide when you call your local support center. It also explains some of the technical
support procedures so that you will know what to expect about the handling and resolution of your
particular issue.
Please remember to include your serial number, partner number or contract number when contacting
Technical Support.
Full technical support for MapBasic is provided for the currently shipping version plus the two previous
versions.
2. Your name and organization. The person calling must be the contact person listed on the support
agreement.
3. Version of the product you are calling about.
4. The operating system name and version.
5. A brief explanation of the problem. Some details that can be helpful in this context are:
• Error messages
• Context in which the problem occurs
• Consistency―is the problem reoccurring or occurring erratically?
Software Defects
If the issue is deemed to be a bug in the software, the representative will log the issue in Pitney
Bowes Inc. bug database and provide you with an incident number that you can use to track the
bug. Future upgrades and patches have fixes for many of the bugs logged against the current
version.
Other Resources
Community Downloads
Community Downloads is a new menu item added to the MapBasic IDE. This can be accessed from
Help Community Downloads . Selecting this takes the user to:
http://communitydownloads.pbinsight.com/code-exchange/product/mapinfo-professional-mapbasic
This page lists all the available MapInfo Pro or MapBasic products.
In this section
Getting Started 20
What Are the Key Features of MapBasic? 22
How Do I Learn MapBasic? 23
The MapBasic Window in MapInfo Pro 24
A Quick Look at MapBasic
Getting Started
The MapBasic software provides you with a development environment. Using this development
environment, you can write programs in the MapBasic programming language.
The MapBasic development environment includes:
• A text editor you can use to type your programs. If you already have a text editor you would rather
use, you can use that editor instead of the MapBasic text editor. For details, see Using the
Development Environment.
• The MapBasic compiler. After you have written a program, compile it to produce an "executable"
application (specifically, an application that can be run by MapInfo Pro).
• The MapBasic linker. If you are creating a large, complex application, you can divide your program
into separate modules, then "link" those modules together into one application.
• MapBasic Help, providing reference information for each statement and function in the MapBasic
language.
• From looking at the name, you might expect the MapBasic programming language to be reminiscent
of traditional BASIC languages. In fact, MapBasic programs do not look much like traditional BASIC
programs. MapBasic does, however, bear a resemblance to newer versions of BASIC which have
been developed in recent years (for example, Microsoft's Visual Basic language).
Every MapBasic program works in conjunction with MapInfo Pro. First, you use the MapBasic
development environment to create and compile your program; then you run MapInfo Pro when you
want to run your program. Thus, a MapBasic program is not a stand-alone program; it can only run
when MapInfo Pro is running. You could say that a MapBasic program runs on top of MapInfo Pro.
However, MapBasic is not merely a macro language, MapBasic is a full-featured programming
language, with over 300 statements and functions. Furthermore, since MapBasic programs run on
top of MapInfo Pro, MapBasic is able to take advantage of all of MapInfo Pro's geographic
data-management capabilities.
4. Choose FileSave to save the program to a file. Enter a file name such as welcome.mb.
Note: Do not close the Edit window.
5. Choose ProjectCompile Current File. MapBasic compiles your program (welcome.mb) and creates
a corresponding executable application file (welcome.mbx).
6. Run MapInfo Pro.
7. On the HOME tab, click Tools, and from the Options menu, select Run Program. You can also
on the HOME tab, click Open, Program.
MapInfo Pro prompts you to choose the program you want to run.
8. Select welcome.mbx to run your program and display the message, "Welcome to MapBasic!" in
a dialog box.
Those are the main steps involved in creating, compiling, and running a MapBasic application. In
practice, of course, the process is more complex. For example, the procedure outlined above does
not describe what happens if you encounter a compilation error. For more details on creating and
compiling MapBasic programs, see Using the Development Environment.
Through MapBasic, you can customize the MapInfo Pro user-interface. A MapBasic application can
modify or replace the standard MapInfo Pro menus, add entirely new menus to the MapInfo Pro
menu bar, and present the user with dialog boxes custom-tailored to the task at hand.
Thus, MapBasic lets you create turn-key systems, custom-tailored systems that help the user perform
tasks quickly and easily, with minimal training.
MapBasic applications are often used to spare end-users the tedium of doing time-consuming
manual work. For example, a MapInfo Pro user may need to develop a graticule (a grid of horizontal
and vertical longitude and latitude lines) in the course of producing a map. Drawing a graticule by
hand is tedious, because every line in the graticule must be drawn at a precise latitude or longitude.
However, a MapBasic application can make it very easy to produce a graticule with little or no manual
effort.
You can perform complex, sophisticated database queries with a single MapBasic statement. For
example, by issuing a MapBasic Select statement (which is modeled after the Select statement in
the SQL query language), you can query a database, apply a filter to screen out any unwanted
records, sort and sub-total the query results. All of this can be accomplished with a single MapBasic
statement.
Using powerful MapBasic statements such as Select and Update, you can accomplish in a few lines
of code what might take dozens or even hundreds of lines of code using another programming
language.
You are not limited to the statements and functions that are built into the MapBasic programming
language. Because MapBasic provides open architecture, your programs can call routines in external
libraries. If you need functionality that isn't built into the standard MapBasic command set, MapBasic's
open architecture lets you get the job done.
MapBasic programs can use Dynamic Data Exchange (DDE) to communicate with other software
packages, including Visual Basic applications. MapBasic programs also can call routines in Windows
Dynamic Link Library (DLL) files. You can obtain DLL files from commercial sources, or you can
write your own DLL files using programming languages such as C. MapBasic provides Integrated
Mapping, that lets you integrate MapInfo Pro functionality into applications written using other
development environments, such as Visual Basic. For details see Integrated Mapping.
If you have not already done so, you should learn how to use MapInfo Pro before you begin working
with MapBasic. This manual assumes that you are familiar with MapInfo Pro concepts and
terminology, such as tables, Map windows, and workspaces.
Once you are comfortable using MapInfo Pro, you can use the following printed and online
instructional materials to help you learn about MapBasic.
MapBasic User Guide
This book explains the concepts behind MapBasic programming. Read the User Guide when you
are learning how to program in MapBasic. Each chapter discusses a different area of programming.
For example, every MapBasic programmer should read MapBasic Fundamentals. Creating the
User Interface explains how to create custom menus and dialog boxes, while File Input/Output
tells you how to perform file input/output.
MapBasic Reference
This A-to-Z reference contains detailed information about every statement and function in the
MapBasic language. Use the MapBasic Reference when you need a complete description of a
particular statement or function.
Sample Programs
Many programmers find that the best way to learn a programming language is to study sample
programs. Accordingly, MapBasic comes with a library of sample programs. See the Samples
directory installed on your MapBasic DVD or download for sample programs included with MapBasic.
Note: The MapBasic User Guide frequently refers to the TextBox sample program (textbox.mb).
You may want to become familiar with this program before you learn MapBasic.
The MapBasic Help contains many brief sample programs which you can copy from the Help window
and paste into your program. You can copy text out of the Help window by clicking and dragging
within the Help window.
If you are viewing a Help screen and you click on a MapBasic menu or a MapBasic Edit window,
the Help window disappears. This is standard behavior for Windows Help. The Help window has
not been closed, it is simply in the background. Note that you can return to the Help window by
pressing Alt+Tab. You can also prevent the Help window from disappearing by checking the Help
window's HelpAlways on Top menu item.
The MapInfo Pro software provides the MapBasic window to help you learn the syntax of statements
in the MapBasic language.
To open the MapBasic window:
1. Run MapInfo Pro.
2. On the HOME tab, in the Tool Windows group, click MapBasic.
The MapBasic window appears on the screen. Thereafter, as you use MapInfo Pro's menus and
dialog boxes, the MapBasic window displays corresponding MapBasic statements.
For example, if you perform a query by using MapInfo Pro's Select dialog box, the MapBasic window
automatically shows you how you could perform the same operation through statements in the
MapBasic language.
You can also enter statements directly into the MapBasic window, although not all MapBasic
statements may be executed in this manner. To determine if a statement may be issued through
the MapBasic window, consult the MapBasic Reference and MapBasic Help. Statements that are
not supported through the MapBasic window are identified by a notice that appears under the
Restrictions heading. As a general rule, you cannot enter flow-control statements (for example,
For...Next loops) through the MapBasic window.
The MapBasic window is also a debugging tool. For details, see Debugging and Trapping Runtime
Errors.
Pitney Bowes Inc. Corporation offers MapBasic training classes. If you want to become proficient
in MapBasic as quickly as possible, you may want to attend MapBasic training. To ensure an ideal
training environment, class size is limited to eight to ten people. For information on scheduled
classes, call The Pitney Bowes Inc. Training department.
If you require extensive assistance in developing your MapBasic application, you may be interested
in Pitney Bowes Inc. Consulting Services. You can arrange to have MapBasic systems engineers
work on-site with you. For additional information, call MapInfo Pro Services.
In this section
Introduction to MapBasic Development Environment 27
Editing Your Program 27
Compiling Your Program 31
Linking Multiple Modules Into a Single Project 34
Menu Summary for the Development Environment 39
MapBasic IDE Features 44
Using the Development Environment
The MapBasic Development Environment contains a built-in text editor that you can use to create
and edit MapBasic programs. Pull-down menus—File, Edit, Search, Project, Window, and
Help—provide you with everything you need to create and edit programs, compile them, and handle
any syntax errors detected by the MapBasic compiler.
If you are familiar with other text editors, you will find MapBasic's text editor easy to use. Most of
the MapBasic menus are predictable: the File menu contains Open, Close, Print, and Save
commands, while the Edit menu contains Undo, Cut, Copy, and Paste commands. However,
MapBasic also contains elements not found in conventional text editors (for example, a compiler
and a linker).
If you have not already done so, run MapBasic. Then, from the File menu, either choose Open (to
display an existing program) or New (to open a blank Edit window).
Type your program into the Edit window. If you do not yet have a program to type in, you can use
the following one-line sample MapBasic program:
Once you have typed in your program, you can save your program to disk by choosing Save from
the File menu. Give your program a name such as welcome.mb.
MapBasic automatically appends the file extension .mb to program files. Thus, if you name your
program welcome, the actual file name is welcome.mb.
Since MapBasic saves your program in a conventional text file, you can use other text editing
software to edit your program if you wish.
Keyboard Shortcuts
The following table lists the keyboard shortcuts you can use within the MapBasic Edit window.
Ctrl+V Pastes text from the clipboard into the Edit window.
Ctrl+R Replaces the selected text (using the replacement text from the Find And Replace dialog
box), and performs another Find.
Ctrl+E Next Error command; scrolls the Edit window to show the line that caused a compilation error.
F1 Displays Help.
F8 Displays Text Style dialog box, allowing you to change the font.
Note: If you select a function name before pressing F1, Help shows a topic describing that function.
Mouse Shortcuts
Double-click Double-clicking on text within your program selects a word. Double-clicking in the list of error
messages scrolls the window to show the line of your program that caused the error.
Drag & Drop Dragging text to another window copies the text. Dragging text within the same window moves
the text (unless you hold down the Ctrl key during the drag, in which case the text is copied).
Note: The MapBasic Help contains code samples. You can drag & drop code samples from the
Help window to your Edit window.
To drag and drop code samples from the Help window to your Edit window:
1. Display help.
2. Click and drag within the Help window to highlight the text you want to copy.
3. Click on the text you highlighted. Without releasing the mouse button, drag the text out of the
Help window.
4. Move the mouse pointer over your Edit window, and release the mouse button. The text is
dropped into your program.
Each MapBasic Edit window can hold a limited amount of text. If the MapBasic text editor beeps
when you try to insert text, the beeping indicates that the Edit window is full. The maximum file size
is currently limited to 512 Kbytes. If a program is created using extended characters in UTF-8 then
2 or more bytes per character are required to accommodate this extended character set. It is
recommended to break down programs into smaller related modules where possible for easier code
maintenance.
There are three ways to work around this size limitation:
• If you have another text editor, you can use that editor to edit your program. To compile your
program, switch to MapBasic and choose the Compile From File menu command.
• You can break your program file (.mb file) into two or more smaller files, and then use the MapBasic
Include statement to incorporate the various files into a single application. For more information
about the Include statement, see the MapBasic Reference.
• You can break your program file (.mb file) into two or more smaller files, and then create a MapBasic
project file which links the various program files into a single application. In some ways, this is
similar to using the Include statement to combine program modules. Project files, however, provide
a more efficient solution. Each file included in a project can be compiled separately; this means
that when you edit only one of your modules, you only need to recompile that module.
If you haven't already done so, display your program in a MapBasic Edit window. Then, to compile
your program, choose Compile Current File from the Project menu.
Note: You can have multiple Edit windows open at one time. When you choose Compile Current
File, MapBasic compiles the program that is in the front-most window. Thus, if you have
multiple Edit windows open, you must make the appropriate window active before you
compile.
The MapBasic compiler checks the syntax of your program. If your program contains any syntax
errors, MapBasic displays a dialog box indicating that errors were found, and then displays
descriptions of the errors in a list beneath the Edit window.
Each error message begins with a line number, indicating which line in the program caused the
error. You must correct your program's errors before MapBasic can successfully compile your
program.
Figure 1: First.mb
If you double-click an error message that appears beneath the Edit window, MapBasic scrolls the
window to show you the line of the program that caused the error.
After you correct any errors in your program, choose Compile Current File again to try to recompile.
Once your program compiles successfully, MapBasic displays a dialog box indicating that compilation
was complete.
When compilation is successful, MapBasic creates an .mbx file (MapBasic eXecutable). This .mbx
file must be present to run the finished application. Thus, if you want to provide your users with a
finished MapBasic application, but you do not want to give them all of your source code, give the
users your .mbx file but not your .mb file.
There are some types of spelling errors which the MapBasic compiler cannot detect. For example,
the MapBasic compiler will compile the following program, even though the program contains a
typographical error on the second line (STATES is misspelled as TATES):
The MapBasic compiler cannot identify the typographical error on the second line. This is not a
defect of the compiler, rather, it is because some variable and table references are not evaluated
until runtime (until the moment the user runs the program). When the user runs the preceding
program, MapInfo Pro attempts to carry out the Map From tates statement. At that time, MapInfo
Pro displays an error message (for example, "Table tates is not open") unless a table called tates
is actually available.
To run the compiled application, choose FileRun MapBasic Program from MapInfo Pro's main menu.
The Run MapBasic Program dialog box prompts you to choose a MapBasic application file (.mbx
file) to run.
The MapBasic development environment also provides a shortcut to running your program: After
compiling your program, choose Run from MapBasic's Project menu (or press Ctrl+U). MapBasic
sends a message to MapInfo Pro, telling MapInfo Pro to execute the application.
Note: MapInfo Pro must already be running.
If you already have a favorite text editor, you can use that editor for editing your MapBasic program.
Just save your MapBasic program as a standard text file.
You can also use word processing software to edit your programs. However, if you use a word
processor to edit your programs, you may need to take special steps to make sure that the word
processor saves your work in a plain text file format. Saving a document as plain text often involves
choosing Save As instead of Save. For more details on saving a document in a plain text format,
see the documentation for your word processing software.
mapbasic
If the command line also includes the parameter -D followed by one or more program names,
MapBasic automatically compiles the program files. For example, the following command line
launches MapBasic and compiles two program files (main and sub1):
If the command line includes the parameter -L followed by one or more project file names, MapBasic
links the projects. (Linking and Project files are discussed in Compiling and Linking a Project.)
For example, the following command line links the TextBox application:
mapbasic -L tbproj.mbp
The command line can include both the -D and the -L parameters, as shown below:
If you launch MapBasic with a command line that includes the -D parameter or the -L parameter,
MapBasic shuts down after compiling or linking the appropriate files.
To start MapBasic without displaying a splash screen use the -Nosplash parameter:
mapbasic -Nosplash
If the command line includes the parameter -utf8, MapBasic is set to compile files and create
executable application files (.mbx) in UTF-8 charset, otherwise MapBasic compiles in system charset.
An example command line using the parameter is shown below:
A project file is a text file that allows MapBasic to link separate program files into one application.
If you are developing a large, complex application, your program could eventually contain thousands
of lines of code. You could type the entire program into a single program file. However, most
programmers dislike managing program files that large; once a program file grows to over a thousand
lines, it can be difficult to locate a particular part of the program. Therefore, many programmers
break up large applications into two or more smaller files. The practice of breaking large programs
down into smaller, more manageable pieces is known as modular programming.
If you do divide your program into two or more modules, you need to create a project file. The project
file tells the MapBasic linker how to combine separate modules into a single, executable application.
Project files are an optional part of MapBasic programming. You can create, compile, and run
applications without ever using a project file. However, if you plan to develop a large-scale MapBasic
application, it is worth your while to take advantage of MapBasic's project-file capabilities.
• Project files can reduce the time it takes to recompile your application. If you change one module
in a multiple-module project, you can recompile just that module, then relink the project. This is
often much faster than recompiling all source code in the project—which is what you must do if
you do not use project files.
[Link]
Application=textbox.mbx
Module=textbox.mbo
Module=auto_lib.mbo
Similarly, the ScaleBar application uses a project file (sbproj.mbp) that looks like this:
[Link]
Application=scalebar.mbx
Module=scalebar.mbo
Module=auto_lib.mbo
In both examples, the final line of the project file tells MapBasic to build the auto_lib module into the
project. The auto_lib module is one of the sample programs included with the MapBasic software.
If a MapBasic program includes the auto_lib module, the program can provide a special Auto-Load
button in its About dialog box. By choosing the Auto-Load button, the user can set up the application
so that it loads automatically every time the user runs MapInfo Pro. If the user does not turn on the
Auto-Load feature, the MapBasic application stops running as soon as the user exits MapInfo Pro.
To build the Auto-Load feature into your MapBasic program, see the instructions listed in the file
auto_lib.mb.
If you have already written a program file, and you want to create a project file for your program,
follow these steps:
1. Choose FileNew to open a new Edit window.
2. Enter the following line in the Edit window:
[Link]
3. Enter a line that contains the text Application=appfilename (where appfilename specifies the file
name of the executable file you want to create). For example:
Application=C:\MB\CODE\CUSTOM.MBX
Application=Local:MapBasic:custom.mbx
Application=/MapBasic/mb_code/custom.mbx
4. Enter a line that contains the text Module=modulename (where modulename specifies the name
of a MapBasic object file). For example:
Module=C:\MB\CODE\CUSTOM.MBO
Module=Local:MapBasic:custom.mbo
Module=/MapBasic/mb_code/custom.mbo
Note the extension on the filename; MapBasic object files have the file extension .mbo. MapBasic
creates an object file when you compile a single module that is part of a multiple-module project.
Whenever you choose ProjectCompile Current File, MapBasic tries to compile the current file
into an executable application file (ending with .mbx). However, if the program file contains calls
to functions or procedures that are not in the file, MapBasic cannot create an .mbx file. In this
case, MapBasic assumes that the program is part of a larger project. MapBasic then builds an
object file (.mbo) instead of an executable file (.mbx). MapBasic also creates an object file
whenever the module that you are compiling does not have a Main procedure.
5. Repeat step 2 for every file you wish to include in your application.
6. Choose FileSave As to save the project file.
In the Save As dialog box, choose the file type "Project File" (from the list of file types in the
lower left corner of the dialog box), so that the file has the extension .mbp (MapBasic Project).
7. Close the Edit window (either choose FileClose or click on the window's close box).
If you add more modules to the project at a later date, remember to add appropriate Module= lines
to the project file.
Once you have created a project file, you can compile and link your project by following these steps:
1. Compile each module that is used in the project.
To compile a module, choose FileOpen, then choose ProjectCompile Current File.
To compile a module without first displaying it, choose FileCompile From File.
2. Choose ProjectSelect Project File to tell MapBasic which project file you want to link. The Select
Project File dialog box displays.
3. Choose the project (.mbp) file you want, and click OK. The selected project file appears in an
Edit window. This file remains selected until you exit MapBasic, close the project file's Edit
window, or choose the ProjectSelect Project File command again. Only one project file can be
selected at any time.
Note: You cannot change which project file is selected by making an Edit window the front-most
window. You cannot change which project file is selected by choosing FileOpen. To select
the project file you want to link, choose ProjectSelect Project File.
4. Choose ProjectLink Current Project to link your application. MapBasic reads the object (.mbo)
files listed in the project file. If there are no link errors, MapBasic builds an executable (.mbx) file.
If there are link errors, MapBasic displays an error message.
You can also link a project in a single step, without first displaying the project file in an Edit window,
by choosing File Link From File .
The object files created by the MapBasic compiler cannot be linked using any other linker, such as
a C-language linker. Only the MapBasic linker can link MapBasic object modules.
Note: Linking of .MBO files compiled with different charsets are not allowed.
If an .MB file is part of a multiple-module project, it can call functions and sub procedures located
in other modules. For example, textbox.mb calls the HandleInstallation procedure, which is located
in the auto_lib library. Calling a function or sub procedure located in another module is known as
an external reference.
If your MapBasic program calls an external procedure, your program file must contain a Declare
Sub statement. Similarly, if your program calls an external function, your program file must contain
a Declare Function statement. These Declare statements tell the MapBasic compiler what parameters
are used by the procedure or function.
The sample program textbox.mb contains the statement Include "auto_lib.def". The auto_lib.def
definitions file contains a set of Declare Sub and Declare Function statements which correspond to
the auto_lib module. If textbox.mb did not include the auto_lib.def definitions file, the MapBasic
compiler would consider the call to the HandleInstallation procedure to be a syntax error ("Invalid
sub procedure name").
Include "auto_lib.def"
Therefore, the two modules can share the global variables. When the textbox.mb program stores
values in the global variables, the auto_lib.mb library is able to read the new values.
Global variables also allow you to share information with other applications that are running.
The File menu provides commands that let you create, open, close, save, exit, and print MapBasic
programs.
• New opens a new Edit window where you can type in your program.
• Open displays an existing file in an Edit window. The file can be a MapBasic program file (for
example, dispatch.mb), a list of error messages (dispatch.err), or a MapInfo Pro workspace file.
Each workspace is actually just a text file containing an assortment of MapBasic statements.
The Open dialog box lets you open two or more files at the same time. To select multiple files,
hold down the Shift key or the Ctrl key as you click on the file names.
Note: Some text files are too big to be displayed in a MapBasic Edit window. For information on
bypassing this limitation, see Limitations of the MapBasic Text Editor.
• Close closes the active Edit window. If you have made changes in the current window, MapBasic
prompts you to either save or discard the changes before closing the window. Close is available
when at least one Edit window is open.
• Close All closes all open Edit windows. As with the Close command, MapBasic prompts you to
either save or discard any unsaved changes. Close All is available when at least one Edit window
is open.
• Save saves the contents of the active Edit window to disk. Save is available when you have
changed the contents of an Edit window.
• Save As saves the contents of the active Edit window under a new file name. Save As is available
when you have an open Edit window.
• Revert discards any changes made to the Edit window since it was last saved. Revert is available
when you have changed the contents of an Edit window.
• Charset allows the user to choose the character set in which they want to compile or link or read
the MapBasic source files. The user can select either UTF-8 or System Charset by using this
button. Any change made in Charset preference will persist for the next MapBasic sessions.
UTF-8: With this preference the files can be created using UTF-8 string literals, function names
and variables. UTF-8 function names or variable names are limited to 32 bytes. Fixed length string
takes number of characters into account, not bytes, thus actual length of UTF-8 variable names
allowed would be less than or equal to 16 characters. The actual length avaialble is based on the
language used for variable names.
Note: The files created using UTF-8 charset cannot be compiled using the previous versions of
MapBasic.
System Charset: With this preference the files can be created using ANSI/System Charset.
Note: MapBasic files with UTF-8 characters will be read as UTF-8 even if the preference is set
to System Charset.
• Compile From File compiles an existing .mb file directly from the contents of the disk file, without
first displaying the contents of the file in an Edit window. (As opposed to the Compile Current File
command on the Project menu, which compiles whatever program is in the active Edit window.)
Use Compile From File to compile a program written in another text editor.
If there are compilation errors, Compile From File writes error messages to a text file named
filename.err. To view the errors file, choose File Open .
• Link From File links an existing project without first displaying the contents of the project file in an
Edit window. (As opposed to the Link Current Project command on the Project menu, which links
the current project.)
Note: Linking of .MBO files compiled with different charsets are not allowed.
• Page Setup defines printer options (for example, paper size and orientation).
• Print prints the active Edit window. Print is available when there is at least one Edit window open.
• Exit exits the MapBasic environment. MapBasic prompts you to either save or discard any changes
that have not been saved.
The Edit menu provides commands that you can use when drafting and editing your MapBasic
program.
• Undo cancels the most recent change you made in the active Edit window. When you select Undo,
MapBasic discards the last change you performed, and then the menu item changes to read Redo.
If you select Redo, MapBasic then re-applies the discarded change.
Undo is enabled when there is at least one open Edit window, and you have made changes to
the text in that window.
• Cut copies the selected (highlighted) text to the Clipboard, then removes the selected text from
the Edit window. The text remains on the Clipboard and you can later insert it elsewhere through
the Paste command (see below). Cut is available when text is selected in the active Edit window.
• Copy copies the selected text to the Clipboard, but does not delete it. Copy is available when text
is selected in the active Edit window.
• Paste copies the contents of the Clipboard to the active Edit window at the current cursor location.
If you select text in the Edit window, and then perform Paste, the text from the clipboard replaces
the selected text.
Paste is available when text is in the Clipboard and there is at least one open Edit window.
• Clear deletes selected text without copying it to the Clipboard. Clear is available when there is
selected text in an open Edit window.
• Select All selects the entire contents of the active Edit window. Select All is available when there
is at least one open Edit window.
The Search menu helps you to locate and replace text in the Edit window. Some of these commands
simplify the process of locating statements that have syntax errors.
• Find searches the active Edit window for a particular text string. Find is available when there is
at least one open Edit window. To find the next occurrence of a text string: Type the text string
you want to find into the Find text box. If you want the search to be case-sensitive, check the
Match Case check box.
When you click on the Find button, MapBasic searches forward from the current insertion point.
If MapBasic finds an occurrence of the Find string, the window scrolls to show that occurrence. If
the text is not found, MapBasic beeps.
• Find Again finds the next occurrence of the string specified in the previous Find dialog box.
Find Again is available when there is at least one open Edit window, and a Find operation has
been performed.
• Replace And Find Again replaces the selected text with text specified in the Find dialog box, then
finds and highlights the next occurrence of the search string.
Next Error is a feature of the compiler that helps you correct syntax errors. When a program does
not compile correctly, MapBasic displays a list of the errors at the bottom of the Edit window. Next
Error scrolls forward through the Edit window, to the line in your program which corresponds to
the next error in the error list. Next Error is available when there are error messages in the active
Edit window.
• Previous Error is similar to Next Error. Previous Error scrolls backward through the Edit window
to the previous item in the error list. Previous Error is available when there are error messages
relating to the active Edit window.
• Go To Line prompts you to type in a line number, then scrolls through the Edit window to that line
in your program.
A program may compile successfully, yet it may encounter an error at runtime. When this happens,
a dialog box appears, indicating that an error occurred at a certain line in your program. Typically,
you then want to return to the MapBasic development environment and go to the appropriate line
of your program. Go To Line is available when there is at least one Edit window open.
The Project menu lets you compile and run MapBasic programs, display program statistics, and
show or hide the error window.
• Select Project File presents a dialog box which lets you open an existing project file. A project file
is a text file that lists all the modules that comprise your application. Once you select a project file,
that project file becomes the active project file, and you can compile the file by choosing Link
Current Project.
• Compile Current File compiles the program in the active Edit window. Compile Current File is
available if there is at least one open Edit window.
If the compiler detects syntax errors in the program, MapBasic displays a list of errors at the bottom
of the Edit window. If there are no syntax errors, MapBasic builds an mbx file (if the module is a
stand-alone program) or an object module (mbo) file.
• Link Current Project links the modules listed in the current project file, and produces an executable
application file (unless there are errors, in which case an error message displays). Link Current
Project is available whenever a project file is open.
• Run sends a message to the MapInfo Pro software, telling it to execute the application in the
front-most Edit window.
• Get Info displays statistics about the program in the active Edit window. Get Info is available if
there is at least one open Edit window.
• Show/Hide Error List activates or deactivates the error list associated with the active Edit window.
If the error list is currently displayed, the menu item reads Hide Error List. If the error list is currently
hidden, the menu item reads Show Error List. Show/Hide Error List is available when there is an
open Edit window with associated error messages.
If you have more than one Edit window open, MapBasic's Window menu lets you arrange your
windows or switch which window is active.
Commands on this menu are available when there is at least one Edit window open.
• Tile Windows arranges the Edit windows in a side-by-side pattern.
• Cascade Windows arranges the Edit windows in an overlapping pattern.
• Arrange Icons organizes the icons that correspond to your minimized Edit windows. You can click
an Edit window's minimize button to temporarily shrink that window down to an icon.
• Text Style lets you choose the font in which the window is displayed. The font you choose is applied
to the entire window.
• The bottom of the Window menu lists a menu item for each open Edit window. To make one of
the Edit windows active (i.e., to bring that window to the front), select the appropriate item from
the Window menu.
Use the Help menu to access MapBasic Help. The help file contains descriptions of all statements
and functions in the MapBasic language. Help also includes a comprehensive set of cross-reference
screens to help you find the name of the statement you need.
• Contents opens the Help window at the Contents screen. From there, you can navigate through
help by clicking on hypertext jumps, or you can click on the Search button to display the Search
dialog box.
• Search For Help On jumps directly to the Search dialog box.
• How To Use Help displays a Help screen that explains how to use MapBasic Help.
• Extensibility Reference opens the MapInfo Pro Extensibility Reference guide for customizing
MapInfo Pro Ribbon interface.
• Community Downloads opens the Pitney Bowes Inc. web site focusing on a page that lists any
available MapInfo Pro or MapBasic products.
• About MapBasic displays the About box, which shows you copyright and version number
information.
Note: Many of the Help screens contain brief sample programs. You can copy those program
fragments onto the clipboard, then paste them into your program. To copy text from a Help
screen, choose EditCopy from the Help window's Edit menu or by dragging text directly out
of the Help window, and drop it into your program.
To make it easier to develop MapBasic libraries of definitions and modules, you can set environment
variables for search paths for Include (.def) files when compiling and Module (.mbo) files when
linking. By default, MapBasic will search for these files first in the path specified in your MapBasic
code and then under the folder where MapBasic is installed. By setting these environment variables
you can specify additional folders to search after the path specified in your code but before the
MapBasic folder. The environment variables are called MBINCLUDE and MBMODULE for Include
and Module files, respectively, and their values should be set to a semi-colon delimited list of folders
to search. MapBasic will search the folders specified and all sub-folders beneath them.
You can set environment variables via the Advanced System Settings on your system. The variables
must be set before you run MapBasic for them to be effective.
To set additional search folders for Include files, set the environment variable MBINCLUDE. For
example, if you have libraries of .def files in or beneath the folders C:\My MapBasic Library and
C:\Work, set the MBINCLUDE environment variable as follows:
Do not use quotes around the folder names even if the path contains spaces.
To set additional search folders for Module files, similarly set the environment variable MBMODULE.
For example, if you have libraries of .mbo files in or beneath the folder C:\My MapBasic Library, set
the MBMODULE environment variable as follows:
Include “mapbasic.def”
Include “utilities.def”
Include “myapplication.def”
Assuming you set your environment variables as above, when compiling MapBasic will search for
these .def files first in the folder where the file your are compiling is located, then under C:\My
MapBasic Library and its subfolders, next under C:\Work and its subfolders, and last under the folder
where MapBasic was installed. If the file utilities.def, for example, is used by multiple applications
you’ve written you can put it somewhere under C:\My MapBasic Library or C:\Work and MapBasic
can find it without you having to specify the path in the code.
Similarly your project (.mbp) file could look as follows:
[Link]Application=myapplication.mbx
Module=myapplication.mbo
Module=library.mbo
If the file library.mbo, for example, is used by multiple applications you’ve written you can put it
somewhere under C:\My MapBasic Library and MapBasic can find it without you having to specify
the path in the project file.
In this section
General Notes on MapBasic Syntax 47
Expressions 55
Looping, Branching, and Other Flow-Control 70
Procedures 75
Procedures That Act As System Event Handlers 79
Tips for Handler Procedures 83
Compiler Instructions 85
Program Organization 87
MapBasic Fundamentals
Before getting into discussions of specific MapBasic statements, it is appropriate to make some
observations about MapBasic program syntax in general.
Comments
In MapBasic, as in some other BASIC languages, the apostrophe character (') signifies the beginning
of a comment. When an apostrophe appears in a program, MapBasic treats the remainder of the
line as a comment, unless the apostrophe appears within a quoted string constant.
Case-Sensitivity
The MapBasic compiler is case-insensitive. You can enter programs with UPPER-CASE, lower-case,
or Mixed-Case capitalization.
For clarity, this manual capitalizes the first letter of each MapBasic language keyword. Program
variables appear in lower-case. For example, in the following program sample, the words If and
Then have proper capitalization because they are keywords in MapBasic, whereas the word counter
appears in lower-case, because it is the name of a variable.
When you write a MapBasic program, you can continue longer statements across more than one
line. For example, the following code sample continues the If...Then statement across several lines:
If counter = 55
Or counter = 34 Then
Note "Counter is invalid"
End If
Many MapBasic statements and function calls will not work properly unless the following statement
appears at or near the top of your program:
Include "mapbasic.def"
The file mapbasic.def is a text file containing definitions for many standard MapBasic codes. As a
rule, the codes defined in mapbasic.def are all in upper-case (for example, TRUE, FALSE, BLACK,
WHITE, CMD_INFO_X, OBJ_INFO_TYPE, etc.). As you read the program examples that appear
in the MapBasic documentation, you will see many such codes. For example:
If your program references standard codes (such as CMD_INFO_DLG_OK in the example above),
your program must issue an Include statement to include mapbasic.def. If you omit the Include
statement, your program will generate a runtime error (for example, "Variable or Field
CMD_INFO_DLG_OK not defined").
The MapInfo Pro software has a feature known as the MapBasic window. Typing statements directly
into the MapBasic window helps you to learn MapBasic statement syntax. However, some restrictions
apply to the MapBasic window:
• Some MapBasic statements may not be entered through the MapBasic window, although you
may use those statements within compiled MapBasic programs. The general rule is flow-control
statements (such as If...Then, For...Next, and GoTo) do not work in the MapBasic window.
• To determine whether you can type a particular statement into the MapBasic window, see the
MapBasic Reference or MapBasic Help. If a statement does not work in the MapBasic window,
that statement's entry in the MapBasic Reference indicates the restriction.
• When you type statements directly into MapInfo Pro's MapBasic window, you must take special
steps if you want to continue the statement across multiple lines. At the end of the each partial
line, type Ctrl+Enter instead of Enter. After you have typed the entire statement, highlight the lines
that make up the statement, and press Enter.
• Codes that are defined in mapbasic.def (for example, BLACK, WHITE, etc.) may not be entered
in the MapBasic window. However, each code has a specific value, which you can determine by
reading mapbasic.def; for example, the code BLACK has a numerical value of zero (0). When you
are entering commands into the MapBasic window, you must use the actual value of each code,
instead of using the name of the code (for example, use zero instead of "BLACK").
• Each statement that you type into the MapBasic window is limited to 256 characters.
Variables
MapBasic's syntax for declaring and assigning values to variables is much like the syntax of other
modern BASIC languages. However, MapBasic supports some types of variables that are not
available in other languages (such as the Object variable; for a complete list of MapBasic variable
types, see the description of the Dim statement in the MapBasic Reference).
What Is a Variable?
Think of a variable as a very small piece of your computer's memory. As you write programs, you
will find that you need to temporarily store various types of information in memory. To do this, you
declare one or more variables. Each variable has a unique name (for example, counter, x, y2,
customer_name). For each variable that you declare, MapBasic sets aside a small piece of memory.
Thereafter, each variable can contain one small piece of information.
A single Dim statement can declare multiple variables, provided that the variable names are separated
by commas. The following Dim statement declares three floating-point numeric variables:
A single Dim statement can declare variables of different types. The following statement declares
two Date variables and two String variables:
Variable Names
Variable names must conform to the following rules:
• Each variable name can be up to thirty-one characters long.
• Variable names may not contain spaces.
• Each variable name must begin with a letter, an underscore (_) or a tilde (~).
• Each variable name can consist of letters, numbers, pound signs (#), or underscore characters
(_).
• A variable name may end in one of the following characters: $, %, &, !, or @. In some BASIC
languages, these characters dictate variable types. In MapBasic, however, these characters have
no special significance.
• You may not use a MapBasic keyword as a variable name. Thus, you may not declare variables
with names such as If, Then, Select, Open, Close, or Count. For a list of reserved keywords, see
the discussion of the Dim statement in the MapBasic Reference.
Data Types
MapBasic supports the following types of variables:
Type Description
Alias Column reference of a table; see Working With Tables for details.
Date Date.
Integer Integer value between -2 billion and 2 billion; stored in four bytes.
Object Graphical object, such as a line or a circle; see Graphical Objects for details.
Type Description
RefPtr Refers to a pointer for a .Net Class (e.g. for .Net extensibility).
SmallInt Integer value between -32767 and 32767; stored in two bytes.
MapBasic supports both fixed-length and variable-length String variables. A variable-length String
variable can store any string value, up to 32,767 characters long. A fixed-length String variable,
however, has a specific length limit, which you specify in the Dim statement.
To declare a variable-length String variable, use String as the variable type. To declare a fixed-length
String variable, follow the String keyword with an asterisk (*), followed by the length of the string in
bytes. In the following example, full_name is declared as a variable-length String variable, while
employee_id is declared as a fixed-length String variable, nine characters long:
Note: Like other BASIC languages, MapBasic automatically pads "every fixed-length String variable
with blanks, so that the variable always fills the allotted space. Thus, if you declare a
fixed-length String variable with a size of five characters, and then you assign the string
"ABC" to the variable, the variable will actually contain the string "ABC " ("ABC" followed
by two spaces). This feature is helpful if you need to write an application that produces
formatted output.
Array Variables
To declare an array variable, follow the variable name with the size of the array enclosed in
parentheses. The array size must be a positive integer constant expression. The following Dim
statement declares an array of ten Date variables:
array_name(element-number)
Thus, the following statement assigns a value to the first element of the start_date array:
start_date(1) = "6/11/93"
To resize an array, use the ReDim statement. Thus, in cases where you do not know in advance
how much data your program will need to manage―perhaps because you do not know how much
data the user will enter―your program can use the ReDim statement to enlarge the array as needed.
Use the UBound( ) function to determine the current size of an array.
The following example declares an array of String variables called name_list. The latter part of the
program increases the size of the array by ten elements.
Use the Type...End Type statement to define a custom data type. A custom data type is a grouping
of one or more variables types. Once you define a custom data type, you can declare variables of
that type by using the Dim statement.
The following program defines a custom data type, employee, then declares variables of the employee
type.
Type employee
name As String
title As String
id As Integer
End Type
Dim manager, staff(10) As employee
Each component of a custom data type is referred to as an element. Thus, the employee data type
in the preceding example has three elements: name, title, and id. To refer to an individual element
of an array, use the generic syntax:
variable_name.element_name
The following statement assigns values to each element of the manager variable:
manager.name = "Joe"
manager.title = "Director of Publications"
manager.id = 111223333
You can declare an array of variables of a custom type. The following statement assigns values to
some of the elements of the first item in the employee array:
staff(1).name = "Ed"
staff(1).title = "Programmer"
Type...End Type statements must appear outside of any sub procedure definition. Sub procedures
are discussed later in this chapter. Typically, Type...End Type statements appear at or near the very
top of your program. A Type definition may include elements of any other type, including
previously-defined custom data types. You can also declare global variables and arrays of custom
data types.
Global Variables
Variables declared with the Dim statement are local variables. A local variable may only be used
within the procedure where it is defined. MapBasic also lets you declare global variables, which may
be referenced within any procedure, anywhere in the program.
To declare a global variable, use the Global statement. The syntax for the Global statement is
identical to the syntax for the Dim statement, except that the keyword Global appears instead of the
keyword Dim. Thus, the following Global statement declares a pair of global Integer variables:
Global statements must appear outside of any sub procedure definition. Sub procedures are
discussed later in this chapter. Typically, Global statements appear at or near the top of the program.
The following program declares several global variables, then references those global variables
within a sub procedure.
Whenever possible, you should try to use local variables instead of global variables, because each
global variable occupies memory for the entire time that your program is running. A local variable,
however, only occupies memory while MapBasic is executing the sub procedure where the local
variable is defined.
MapBasic global variables can be used to exchange data with other software packages. When an
application runs on Windows, other applications can use Dynamic Data Exchange to read and
modify the values of MapBasic global variables.
Scope of Variables
A sub procedure may declare a local variable which has the same name as a global variable. Thus,
even if a program has a global variable called counter, a sub procedure in that program may also
have a local variable called counter:
If a local variable has the same name as a global variable, then the sub procedure will not be able
to read or modify the global variable. Within the sub procedure, any references to the variable will
affect only the local variable. Thus, in the example above, the statement: counter = 0 has no effect
on the global counter variable.
Upon encountering a reference to a variable name, MapBasic attempts to interpret the reference
as the name of a local variable. If there is no local variable by that name, MapBasic attempts to
interpret the reference as the name of a global variable. If there is no global variable by that name,
MapBasic tries to interpret the reference as a reference to an open table. Finally, if, at runtime, the
reference cannot be interpreted as a table reference, MapBasic generates an error message.
Expressions
In this section, we take a closer look at expressions. An expression is a grouping of one or more
variables, constant values, function calls, table references, and operators.
What is a Constant?
An expression can be very simple. For example, the statement: counter = 23 assigns a simple
integer expression namely, the value 23 to the variable, counter. We refer to the expression 23 as
a numeric constant. You might think of a constant as a specific value you can assign to a variable.
The following program declares a String variable, then assigns a string constant (the name "Fred
Mertz") to the variable:
The syntax for numeric expressions is different than the syntax for string expressions: string constants
must be enclosed in double-quotation marks (for example, "Fred Mertz") whereas numeric constants
(for example, 23) are not. You cannot assign a String expression, such as "Fred Mertz," to a numeric
variable. For more information on constant expressions, see A Closer Look At Constants.
What is an Operator?
An operator is a special character (for example, +, *, >) or a word (for example, And, Or, Not) which
acts upon one or more constants, variables, or other values. An expression can consist of two or
more values that are combined through an operator. In the following example, the plus operator (+)
is used within the expression y + z, to perform addition. The result of the addition (the sum) is then
assigned to the variable, x:
Dim x, y, z As Float
y = 1.5
z = 2.7
x = y + z
In this example, the plus sign (+) acts as an operator―specifically, a numeric operator. Other numeric
operators include the minus operator (-), which performs subtraction; the asterisk (*), which performs
multiplication; and the caret (^), which performs exponentiation. A complete list of numeric operators
appears later in this chapter.
The plus operator can also be used within a String expression to concatenate separate strings into
one string. The following program builds a three-part string expression and stores the string in the
variable, full_name:
The MapBasic language supports many different function calls. Each function has a different purpose.
For example, the Sqr( ) function calculates square root values, while the UCase$( ) function converts
a text string to uppercase. When you enter a function name into your program, your program calls
the named function, and the function returns a value.
A function call can comprise all or part of an expression. For example, the following statement
assigns a value to the variable, x, based on the value returned by the Minimum( ) function:
x = Minimum( y, z )
The MapBasic function call syntax is similar to that of other modern BASIC languages. The function
name (for example, "Minimum", in the example above) is followed by a pair of parentheses. If the
function takes any parameters, the parameters appear inside the parentheses. If the function takes
more than one parameter, the parameters are separated by commas (the Minimum( ) function takes
two parameters).
A function call is different than a generic statement, in that the function call returns a value. A function
call cannot act as a stand-alone statement; instead, the value returned by the function must be
incorporated into some larger statement. Thus, the following program consists of two statements:
a Dim statement declares a variable, x; and then an assignment statement assigns a value to the
variable. The assignment statement incorporates a function call (calling the Sqr( ) function to calculate
the square root of a number):
Dim x As Float
x = Sqr(2)
Similarly, the following program uses the CurDate( ) function, which returns a Date value representing
the current date:
The CurDate( ) function takes no parameters. When you call a function in MapBasic, you must follow
the function name with a pair of parentheses, as in the example above, even if the function takes
no parameters.
MapBasic supports many standard BASIC functions, such as Chr$( ) and Sqr( ), as well as a variety
of special geographic functions such as Area( ) and Perimeter( ).
A constant is a specific value that does not change during program execution. Programmers
sometimes refer to constants as "hard-coded" expressions, or as "literals."
Numeric Constants
Different types of numeric variables require different types of constants. For instance, the constant
value 36 is a generic numeric constant. You can assign the value 36 to any numeric variable,
regardless of whether the variable is Integer, SmallInt, LargeInt, or Float. The value 86.4 is a
floating-point numeric constant.
Numeric constants may not include commas (thousand separators). Thus, the following statement
will not compile correctly
If a numeric constant includes a decimal point (decimal separator), the separator character must
be a period, even if the user's computer is set up to use some other character as the decimal
separator.
String Constants
A String constant is enclosed in double quotation marks. For example:
last_name = "Nichols"
Logical Constants
Logical constants can be either one (1) for TRUE or zero (0) for FALSE. Many MapBasic programs
refer to the values TRUE and FALSE; note that TRUE and FALSE are actually defined within the
standard MapBasic definitions file, mapbasic.def. To refer to standard definitions like TRUE and
FALSE, a program must issue an Include statement, to include mapbasic.def. For example:
Include "mapbasic.def"
Dim edits_pending As Logical
edits_pending = FALSE
Date Constants
To specify a date constant, enter an eight-digit Integer with the format YYYYMMDD. This example
specifies the date December 31, 1995:
Alternately, you can specify a string expression that acts as a date constant:
d_enddate = "12/31/1995"
When you specify a string as a date constant, the year component can be four digits or two digits:
d_enddate = "12/31/95"
You can omit the year, in which case the current year is used:
d_enddate = "12/31"
CAUTION: Using a string as a date constant is sometimes unreliable, because the results you get
depend on how the user's computer is configured. If the user's computer is configured
to use Month/Day/Year formatting, then "06/11/95" represents June 11, but if the
computer is set up to use Day/Month/Year formatting, then "06/11/95" represents the
6th of November.
If the user's computer is set up to use "-" as the separator, MapInfo Pro cannot convert string
expressions such as "12/31" into dates.
To guarantee predictable results, use the NumberToDate( ) function, which accepts the eight-digit
numeric date syntax. (Numeric date constants, such as 19951231, are not affected by how the
user's computer is configured.) If you need to use strings as date values―perhaps because you
are reading date values from a text file―use the Set Format statement to control how the strings
are interpreted. For Set Format statement details, see the MapBasic Reference or MapBasic Help.
To configure date formatting options under Microsoft Windows, use the Regional Settings control
panel.
Alias Constants
Alias variables are discussed in detail in Working With Tables. You can assign a string expression
to a variable of type Alias. For example:
Integer
i = 1234567
SmallInt
m = 90
LargeInt
n = 9223372036854775807
Float
f = 4
size = 3.31
debt = 3.4e9
Date
d_starting = 19940105
date_done = "3/23/88"
paiddate = "12-24-1993"
yesterday = CurDate() - 1
BLACK, WHITE)
MapBasic provides functions for converting data of one type to another type. For instance, given a
number, you can produce a string representing the number calling the function Str$( ):
Operators act on one or more values to produce a result. Operators can be classified by the data
types they use and the types of results they produce.
Numeric Operators
Each of the operators in the following table is a numeric operator. Two numeric values can be
combined using a numeric operator to produce a numeric result.
+ addition
x = a + b
- subtraction
x = a - b
* multiplication
x = a * b
/ division
x = a / b
\ integer division
x = a \ b
^ exponentiation
x = a ^ b
10 / 8 returns 1.25
The minus sign (-) operator can be used to negate a numeric value
x = -23
String Operators
The plus operator (+) lets you concatenate two or more string expressions into one long string
expression.
You can use the ampersand operator (&) instead of the plus operator when concatenating strings.
The & operator forces both operands to be strings, and then concatenates the strings. This is different
than the + operator, which can work with numbers or dates without forcing conversion to strings.
Note: The & character is also used to specify hexadecimal numbers (&Hnumber). When you use
& for string concatenation, make sure you put a space before and after the & so that the
MapBasic compiler does not mistake the & for a hex number prefix.
The Like operator performs string comparisons involving wild-card matching. The following example
tests whether the contents of a String variable begins with the string "North":
The Like operator is similar to the Like( ) function. For a description of the Like( ) function, see the
MapBasic Reference or MapBasic Help.
Date Operators
The plus and minus operators may both be used in date expressions, as summarized below.
Expression Returns
The following example uses the CurDate( ) function to determine the current date, and then calculates
other date expressions representing tomorrow's date and the date one week ago:
today = CurDate()
tomorrow = today + 1
one_week_ago = today - 7
' calculate days elapsed since January 1:
days_elapsed = today - StringToDate("1/1")
Comparison Operators
A comparison operator compares two items of the same general type to produce a logical value of
TRUE or FALSE. Comparison operators are often used in conditional expressions (for example, in
an If...Then statement).
= equal to
If a = b Then ...
Each of these comparison operators may be used to compare string expressions, numeric
expressions, or date expressions. Note, however, that comparison operators may not be used to
compare Object, Pen, Brush, Symbol, or Font expressions.
The Between...And... comparison operator lets you test whether a data value is within a range (for
example, X >= 500 And X <= 600). The following If...Then statement uses a Between...And...
comparison:
When you use the = operator to compare two strings, MapBasic examines the entire length of both
strings, and returns TRUE if the strings are identical. String comparisons are not case sensitive; so
this If...Then statement considers the two names ("Albany" and "ALBANY") to be identical:
If you wish to perform case-sensitive string comparison, use the StringCompare( ) function, which
is described in the MapBasic Reference.
Note: Be careful when comparing fixed-length and variable-length strings. MapBasic automatically
pads every fixed-length string with spaces, if necessary, to ensure that the string fills the
allotted space. Variable-length strings, however, are not padded in this manner. Depending
on your data and variables, this difference might mean that two seemingly-identical strings
are not actually equal.
You can use the RTrim$( ) function to obtain a non-padded version of a fixed-length string. You
then can compare the value returned by RTrim$( ) with a variable-length string, without worrying
about interference from padded spaces.
Logical Operators
Logical operators operate on logical values to produce a logical result of TRUE or FALSE:
For example, the following If...Then statement performs two tests, testing whether the variable x is
less than zero, and testing whether x is greater than ten. The program then displays an error message
if either test failed.
Geographic Operators
These operators act on Object expressions to produce a logical result of TRUE or FALSE.
Some operators have higher precedence than others. This means that in a complex expression
containing multiple operators, MapBasic follows certain rules when determining which operations
to carry out first. To understand how MapBasic processes complex expressions, you must be familiar
with the relative precedence of MapBasic's operators.
x = 2 + 3 * 4
This assignment involves two mathematical operations addition and multiplication. Note that the
end result depends on which operation is performed first. If you perform the addition first (adding 2
+ 3, to obtain 5), followed by the multiplication (multiplying 5 * 4), the end result is 20. In practice,
however, multiplication has a higher precedence than addition. This means that MapBasic performs
the multiplication first (multiplying 3 * 4, to obtain 12), followed by the addition (adding 2 + 12, to
obtain 14).
You can use parentheses to override MapBasic's default order of precedence. The following
assignment uses parentheses to ensure that addition is performed before multiplication:
x = (2 + 3) * 4
Operators appearing on the same row have equal precedence. Operators of higher priority are
processed first. Operators of the same precedence are evaluated left to right in the expression,
except exponentiation, which evaluates from right to left.
Flow-control statements affect the order in which other statements are executed. MapBasic has
three main types of flow-control statements:
• Branching statements cause MapBasic to skip over certain statements in your program (for
example, If...Then, GoTo).
• Looping statements cause MapBasic to repeatedly execute one or more designated statements
in your program (for example, For...Next, Do...While).
• Other statements provide special flow-control (for example, End Program).
If...Then Statement
MapBasic's If...Then statement is very similar to comparable If...Then statements in other languages.
The If...Then statement tests a condition; if the condition is TRUE, MapBasic executes the statements
which follow the Then keyword. In the following example, MapBasic displays an error message and
calls a sub-procedure if a counter variable is too low:
An If...Then statement can have an optional Else clause. In the event that the original test condition
was FALSE, MapBasic executes the statements following the Else keyword instead of executing
the statements following the Then keyword.
The following example demonstrates the optional Else clause.
An If...Then statement can also have one or more optional ElseIf clauses. The ElseIf clause tests
an additional condition. If the statement includes an ElseIf clause, and if the original condition turned
out to be FALSE, MapBasic will test the ElseIf clause, as in the following example:
Note: ElseIf is a single keyword. A single If...Then statement can include a succession of two or
more ElseIf clauses, subsequently testing for condition after condition. However, if you want
to test for more than two or three different conditions, you may want to use the Do...Case
Do Case Statement
The Do Case statement performs a series of conditional tests, testing whether a certain expression
is equal to one of the values in a list of potential values. Depending on which value the expression
matches (if any), MapBasic carries out a different set of instructions.
The following example tests whether the current month is part of the first, second, third, or fourth
quarter of the fiscal year. If the current month is part of the first quarter (January-February-March),
the program assigns a text string an appropriate title ("First Quarter Results"). Alternately, if the
current month is part of the second quarter, the program assigns a different title ("Second Quarter
Results"), etc.
Note: Case Else is an optional clause of the Do Case statement. If a Do Case statement includes
a Case Else clause, and if none of the previous Case clauses matched the expression being
tested, MapBasic carries out the statements following the Case Else clause. The Case Else
clause must be the final clause in the Do Case construction.
GoTo Statement
The GoTo statement tells MapBasic to go to a different part of the program and resume program
execution from that point. The GoTo statement specifies a label. For the GoTo statement to work,
there must be a label elsewhere within the same procedure. A label is a name which begins a line.
Each label must end with a colon (although the colon is not included in the GoTo statement). See
the example below.
Many programming professionals discourage the use of GoTo statements. Careful use of other
flow-control statements, such as If...Then, usually eliminates the need to use GoTo statements.
Thus, if you like, you may avoid using GoTo statements.
For...Next Statement
The For...Next statement sets up a loop that executes a specific number of times. With each iteration
of the loop, MapBasic executes all statements that appear between the For and Next clauses. When
creating a For...Next loop, you must specify the name of a numeric variable as a counter. You must
also specify that counter variable's starting and ending values. With each iteration of the loop,
MapBasic increments the counter variable by some step value. By default, this step value is one.
To use a different increment, include the optional Step clause.
The following example uses a For...Next loop to add the values from an array of numbers:
At the start of the For...Next statement, MapBasic assigns the start value to the counter variable.
In the example above, MapBasic assigns a value of one to the variable: next_one. MapBasic then
executes the statements that appear up to the Next keyword. After each iteration of the loop,
MapBasic increments the counter variable. If the counter variable is less than or equal to the end
value (for example, if next_one is less than or equal to twelve), MapBasic performs another iteration
of the loop.
A For...Next loop halts immediately if it encounters an Exit For statement. This allows you to
conditionally halt the loop prematurely.
See the MapBasic Reference for more information on the For...Next loop.
Do...Loop
The Do...Loop statement continually executes a group of statements for as long as a test condition
remains TRUE or, optionally, for as long as the condition remains FALSE.
There are different forms of the Do...Loop statement, depending on whether you want to test the
looping condition before or after the body of the statements that are executed. The following program
tests the loop condition at the end of the loop:
Note that the preceding loop always executes for at least one iteration, because the looping condition
is not tested until the end of the loop.
The following loop tests the loop condition at the start of the loop. Because the condition is tested
at the start of the loop, the statements within the body of the loop may never be executed. If the test
condition is FALSE from the beginning, the statements within the following Do...Loop will never be
executed.
In the examples above, both Do...Loop statements included the keyword While; thus, both loops
continue while the test condition remains TRUE. Alternately, a Do...Loop can use the Until keyword
instead of the keyword While. If a Do...Loop statement specifies Until, the loop will continue only
for as long as the test condition remains FALSE.
A Do...Loop statement halts immediately if it encounters an Exit Do statement. This statement allows
you to conditionally terminate a loop prematurely.
While...Wend Loop
MapBasic supports the conventional BASIC While...Wend loop syntax. A While...Wend statement
is very similar to a Do While...Loop statement.
If you are an experienced BASIC programmer, and you therefore are in the habit of using
While...Wend statements, you can continue to use While...Wend statements as you use MapBasic.
Note, however, that the Do...Loop statement syntax is in some ways more powerful than the
While...Wend syntax. You can exit a Do...Loop statement prematurely, through the Exit Do statement,
but there is no corresponding statement for exiting a While...Wend loop.
See the MapBasic Reference for more information on the While...Wend loop.
The End Program statement halts the MapBasic application, removes any custom menu items
created by the application, and removes the application from memory. End Program also closes
any files opened by the application (through the Open File statement), but it does not close any
open tables.
The End Program statement is not required. In fact, there are situations where you should be careful
not to issue an End Program statement. For example, if your application adds menu items to a
MapInfo Pro menu, you probably want your application to remain running for the duration of the
MapInfo Pro session, because you want your custom menu items to remain available for the entire
session. In such cases, you should be careful not to issue the End Program statement, because it
would halt your application and remove your application's custom menu items. For a complete
discussion of custom menus, see Creating the User Interface.
The End MapInfo statement halts the MapBasic application (much as the End Program statement
does), and then exits the MapInfo Pro software as well.
Procedures
Procedures (often referred to as sub-procedures) are an integral part of the MapBasic program
architecture. A typical MapBasic program is comprised of numerous sub-procedures; each
sub-procedure contains a group of statements that perform a specific task. By breaking your program
into several sub-procedures, you modularize your program, making program development and
maintenance easier in the long run.
Main Procedure
Every MapBasic program has at least one procedure, known as the Main procedure. When you run
a MapBasic application, MapBasic automatically calls that application's Main procedure.
The following program demonstrates the syntax for explicitly declaring the Main procedure. In this
example, the Main procedure simply issues a Note statement:
The Declare Sub statement tells MapBasic that a sub-procedure definition will occur further down.
You must have one Declare Sub statement for each sub-procedure in your program. The Declare
Sub statement must appear before the actual sub-procedure definition. Typically, Declare Sub
statements appear at or near the top of your program.
You may recall from Using the Development Environment that a MapBasic program can be as
simple as a single line. For example, the following statement:
is a complete MapBasic program which you can compile and run. Note that even a simple, one-line
program has a Main procedure. However, in this case, we say that the Main procedure is implied
rather than being explicit.
Calling a Procedure
When you run a compiled application, MapInfo Pro automatically calls the Main procedure (regardless
of whether the Main procedure is implied or explicitly defined). The Main procedure can then call
other sub-procedures through the Call statement.
The following program contains two procedures: a Main procedure, and a procedure called
announce_date.
Sub Main
Call announce_date()
End Sub
Sub announce_date
Note "Today's date is " + Str$( CurDate() )
End Sub
Like other modern BASIC languages, MapBasic lets you create sub-procedures which take
parameters. If a sub-procedure takes parameters, they are declared within parentheses which follow
the procedure name in the Sub...End Sub statement.
The following example shows a sub-procedure called check_date, which takes one parameter (a
Date value). The sub-procedure checks to see whether the value of the Date parameter is too old
(more than 180 days old). If the Date parameter value is too old, the procedure sets the Date
parameter to the current date.
Sub Main
Dim report_date As Date
report_date = "01/01/94"
Call check_date( report_date )
' At this point, the variable: report_date
' may contain the current date (depending on
' what happened in the check_date procedure).
End Sub
• The Call statement must specify the name of a variable for each by-reference parameter.
• If the called sub-procedure assigns a new value to a by-reference parameter, the new value is
automatically stored in the caller's variable. In other words, the sub-procedure can use a
by-reference parameter to return a value to the caller.
Thus, in the example above, the Call statement specifies the name of a Date variable report_date:
Then, within the check_date procedure, the parameter is known by the name last_date. When the
check_date procedure performs the assignment last_date = CurDate( ), MapBasic automatically
updates the Main procedure's report_date variable.
Sometimes, it is awkward to pass parameters by reference. For each by-reference parameter, you
must specify the name of a variable in your Call statement. At times, you may find this awkward (for
example, because you may not have a variable of the appropriate type).
Like other modern BASIC languages, MapBasic lets you specify that a procedure parameter will be
passed by value rather than by reference. To specify that a parameter be passed by value, include
the keyword ByVal before the parameter's name in the Sub...End Sub statement.
When a parameter is passed by value, the following rules apply:
• The Call statement does not need to specify the name of a variable as the parameter. The Call
statement may specify a variable name, a constant value or some other expression.
• If the called sub-procedure assigns a new value to a by-value parameter, the calling procedure is
not affected. In other words, the sub-procedure cannot use a by-value parameter to return a value
to the caller.
The following example shows a procedure (display_date_range) which takes two by-value Date
parameters.
Sub Main
Call display_date_range( "1/1", CurDate() )
End Sub
In this example, both of the parameters to the display_date_range procedure are by-value date
parameters. Thus, when the Main procedure calls display_date_range:
neither of the parameters needs to be a Date variable. The first parameter ("1/1") is a constant Date
expression, and the second parameter is a date expression derived by calling the CurDate( ) function.
The MapBasic language supports recursive function and procedure calls. In other words, a MapBasic
procedure can call itself.
Programs that issue recursive procedure or function calls may encounter memory limitations. Each
time a program makes a recursive call, MapInfo Pro must store data on the stack; if too many nested
recursive calls are made, the program may generate an out-of-memory error. The amount of memory
used up by a recursive call depends on the number of parameters and local variables associated
with the procedure or function.
Some procedure names have special meaning in MapBasic. For example, as we have seen, the
sub-procedure named Main is special, since MapBasic automatically calls the Main procedure when
you run an application.
In addition to Main, MapBasic has several other special procedure names: EndHandler,
ForegroundTaskSwitchHandler, RemoteMapGenHandler, RemoteMsgHandler,
RemoteQueryHandler( ), SelChangedHandler, ToolHandler, WinChangedHandler, WinClosedHandler,
and WinFocusChangedHandler. Each of these reserved procedure names plays a special role in
MapBasic programming. To fully understand how they work, you need to understand MapBasic's
approach to system events and event-handling.
In a Graphical User Interface environment, the user controls what happens by typing and by using
the mouse. Technically, we say that mouse-clicks and other actions taken by the user generate
system events. There are many different kinds of events; for example, when the user chooses a
menu item, we say that the user has generated a menu-choose event, and when the user closes a
window, we say the user has generated a window-close event.
An event-handler is part of a MapBasic program which responds to a system event. Once the user
has generated an event, the application must respond accordingly. For instance, when the user
generates a menu-choose event, the software may need to display a dialog box. Alternately, when
the user generates a window-close event, the software may need to gray out a menu item or hide
an entire menu.
In MapBasic, sub-procedures can act as event-handlers. In other words, you can construct your
program in such a way that MapBasic automatically calls one of your sub-procedures when and if
a certain system event occurs.
To build event-handlers that respond to menu or button-pad choices, see Creating the User
Interface. To build any other types of system event-handlers, you must define a sub-procedure with
a special name. For example, if you want your program to respond automatically whenever the user
closes a window, your application must contain a procedure named WinClosedHandler.
The following table lists all of MapBasic's special handler names. These special handlers are
discussed in more detail in the MapBasic Reference and MapBasic Help.
EndHandler Called when the application terminates or when the user exits MapInfo Pro.
EndHandler can be used to do clean-up work (for example, deleting temporary
work files).
ForegroundTaskSwitchHandler Called when MapInfo Pro gets the focus (becomes the active application) or
loses the focus.
RemoteMapGenHandler Called when an OLE Automation client calls the MapGenHandler method; used
primarily in MapInfo ProServer applications.
SelChangedHandler Called whenever the Selection table changes. Since the Selection table changes
frequently, the SelChangedHandler procedure should be as brief as possible to
avoid slowing system performance.
ToolHandler Called when the user clicks in a Map, Browser, or Layout window using the
MapBasic tool.
WinChangedHandler Called when the user pans, scrolls, or otherwise resets the area displayed in a
Mapper. Since Mapper windows can change frequently, the WinChangedHandler
procedure should be as brief as possible to avoid slowing system performance.
WinClosedHandler Called when the user closes a Mapper, Browser, Grapher, or Layout.
WinFocusChangedHandler Called when the window focus changes (i.e., when the user changes which
window is the active window).
Typically, you do not use the Call statement to call the special procedures listed above. If your
program contains one of these specially named procedures, MapBasic calls that procedure
automatically, when and if a certain type of system event occurs. For example, if your program
contains a procedure called WinClosedHandler, MapBasic automatically calls the WinClosedHandler
procedure every time the user closes a window.
All of the special handler procedures are optional. Thus, you should only include a WinClosedHandler
procedure in your application if you want your application to be notified every time a window is
closed. You should only include a SelChangedHandler procedure in your application if you want
your application to be notified each time Selection changes, etc.
The following program defines a special event-handler procedure named ToolHandler. Note that
this program does not contain any Call statements. Once this program is running, MapBasic calls
the ToolHandler procedure automatically, when and if the user selects the MapBasic tool and clicks
on a Map, Browser, or Layout window.
Include "mapbasic.def"
Sub Main
Note "The ToolHandler demonstration is now in place. "
+ "Select the MapBasic tool (+) and click on a Map "
+ "to see a printout of map coordinates."
End Sub
Sub ToolHandler
If WindowInfo( FrontWindow(), WIN_INFO_TYPE ) = WIN_MAPPER Then
Print "X: " + Str$( CommandInfo(CMD_INFO_X) )
Print "Y: " + Str$( CommandInfo(CMD_INFO_Y) )
Print " "
End If
End Sub
Within a system event handler procedure, you can call the CommandInfo( ) function to learn more
about the event that made MapBasic call the handler. In the example above, the ToolHandler
procedure calls CommandInfo( ) to determine the map coordinates where the user clicked.
The following sample SelChangedHandler procedure appears in the sample program, TextBox
(textbox.mb). This procedure automatically disables (grays out) a menu item whenever the user
de-selects all rows, and automatically re-enables the menu item whenever the user selects more
rows.
See textbox.mb for more details.
Sub SelChangedHandler
If SelectionInfo(SEL_INFO_NROWS) < 1 Then
Alter Menu Item create_sub Disable
Else
Alter Menu Item create_sub Enable
End If
End Sub
By default, a MapBasic application terminates after executing all statements in the Main procedure.
However, if an application contains one or more of the special handler procedures listed above (for
example, if an application contains a ToolHandler procedure), the application remains in memory
after the Main procedure is finished. An application in this state is said to be sleeping. A sleeping
application remains dormant in memory until an appropriate event occurs (for example, until the
user clicks with the MapBasic tool). When the event occurs, MapBasic automatically calls the sleeping
application's handler procedure.
Note: If any procedure in an application issues the End Program statement, the entire application
is removed from memory, regardless of whether the application contains special handler
procedures. You must avoid using the End Program statement for as long as you want your
program to remain available.
Custom MapBasic menus work in a similar manner. If a MapBasic application adds its own items
to the MapInfo Pro menu structure, the application goes to sleep and waits for the user to choose
one of the custom menu items. For a complete discussion of how to customize MapInfo Pro's menus,
see Creating the User Interface.
Bear in mind that some system event-handler procedures are called frequently. For example, if you
create a SelChangedHandler procedure, MapInfo Pro calls the procedure every time the Selection
table changes. In a typical MapInfo Pro session, the Selection table changes frequently, therefore,
you should make event-handler procedures, such as SelChangedHandler, as short as possible.
If you are using a Select statement, but you do not want the statement to trigger the
SelChangedHandler procedure, include the NoSelect keyword. For example:
Performing actions within a system handler procedure can sometimes cause an infinite loop. For
example, if you declare a SelChangedHandler procedure, MapInfo Pro calls that procedure whenever
the selection changes. If you issue a Select statement inside of your SelChangedHandler procedure,
the Select statement will cause MapInfo Pro to call the procedure again in a recursive call. The end
result can be an infinite loop, which continues until your program runs out of memory.
The Set Handler statement can help prevent infinite loops. At the start of your handler procedure,
issue a Set Handler...Off statement to prevent recursive calling of the handler. At the end of the
procedure, issue a Set Handler...On statement to restore the handler.
Sub SelChangedHandler
Set Handler SelChangedHandler Off
Custom Functions
The MapBasic language supports many different functions. Some are standard BASIC functions
(for example, Asc( ), Format$( ), Val( ), etc.) and some are unique to MapInfo Pro and MapBasic
(for example, Distance( ) and ObjectGeography( ) ). MapBasic also lets you define custom functions.
Once you have defined a custom function, you can call that function just as you can call any of
MapBasic's standard functions.
The body of a custom function is defined within a Function...End Function construction, which is
syntactically very similar to a Sub...End Sub construction. The general syntax of a Function...End
Function construct is as follows:
The function itself has a data type. This dictates which type of value (for example, Integer, Date,
String) the function returns when called.
Within the body of the Function...End Function construction, the function name acts like a by-reference
parameter. A statement within the Function...End Function construction can assign a value to the
function name; this is the value that MapBasic later returns to the function's caller.
The example below defines a custom function called money_format( ). The money_format() function
takes one numeric parameter (presumably representing a sum of money), and returns a string
(obtained by calling the Format$( ) function) representing the dollar amount, formatted with commas.
Scope of Functions
A program can define a custom function that has the same name as a standard MapBasic function.
When the program calls the function, the custom function is executed instead of the standard function.
Compiler Instructions
MapBasic provides two special statements which make it easier to manage large-scale application
development:
• The Define statement lets you define a shorthand identifier which has a definition; the definition
is substituted for the identifier at compile time.
• The Include statement lets you combine two or more separate program files into one compilable
program.
Through the Define statement, you can define an identifier which acts as a shorthand equivalent
for some specific value.
Use a Define statement whenever you find yourself frequently typing an expression that is difficult
to remember or to type.
For example, if your program deals extensively with objects and object colors, you might find that
you frequently need to type in the value 16711680, a numeric code representing the color red.
Typing such a long number quickly becomes tedious. To spare yourself the tedium of typing in
16711680, you could place the following Define statement in your program:
The standard MapBasic definitions file, mapbasic.def, contains many Define statements, including
statements for several commonly-used colors (BLACK, WHITE, RED, GREEN, BLUE, CYAN,
MAGENTA, and YELLOW). Use the Include statement to incorporate mapbasic.def into your program.
Through the Include statement, you can incorporate two or more separate program files into one
MapBasic application. The Include statement has the following syntax:
Include "filename"
where filename is the name of a text file containing MapBasic statements. When you compile a
program that contains an Include statement, the compiler acts as if the included text is part of the
program being compiled.
Many MapBasic applications use the Include statement to include the standard MapBasic definitions
file, mapbasic.def:
Include "mapbasic.def"
mapbasic.def provides Define statements for many standard MapBasic identifiers (TRUE, FALSE,
RED, GREEN, BLUE, TAB_INFO_NAME, etc.).
The filename that you specify can include a directory path. If the filename that you specify does not
include a directory path, the MapBasic compiler looks for the file in the current working directory. If
the file is not found in that directory, the compiler looks in the directory where the MapBasic software
is installed.
As you develop more and more MapBasic programs, you may find that you use certain sections of
code repeatedly. Perhaps you have written a library of one or more custom functions, and you wish
to use those custom functions in every MapBasic program that you write. You could put your custom
functions into a separate text file, perhaps calling the text file functs.mb. You could then incorporate
the function library into another program by issuing the statement:
Include "functs.mb"
Using Include statements also lets you work around the memory limitations of the MapBasic text
editor. As discussed in Using the Development Environment, each MapBasic Edit window is
subject to memory limits; once a program file grows too large, you can no longer add statements
to the file using a MapBasic Edit window. If this happens, you may want to break your program into
two or more separate program files, then combine the files using the Include statement. Alternately,
you could combine the separate modules using a project file; see Using the Development
Environment for details.
Program Organization
A MapBasic application can include any or all of the different types of statements described in this
chapter. However, the different pieces of a MapBasic program must be arranged in a particular
manner. For example, Global statements may not be placed inside of a Sub...End Sub definition.
The following illustration shows a typical arrangement of the various program components.
Global level statements appear at the top of the program...
Include "mapbasic.def"
other Include statements
Type...End Type statements
Declare Sub statements
Declare Function statements
Define statements
Global statements
Sub Main
Dim statements
...
End Sub
Sub ...
Dim statements
...
End Sub
Function ...
Dim statements
...
End Function
In this section
Runtime Error Behavior 89
Debugging a MapBasic Program 89
Error Trapping 91
Debugging and Trapping Runtime Errors
There are two main types of programming errors: compilation errors and runtime errors. Compilation
errors, discussed in Using the Development Environment, are syntax errors or other typographical
mistakes that prevent a program from compiling successfully.
Runtime errors are errors that occur when the user actually runs an application. Runtime errors
occur for various reasons; often, the reason has to do with precise conditions that exist at runtime.
For example, the following statement compiles successfully:
However, if there is no table named "stats," this program generates a runtime error. When a runtime
error occurs, MapInfo Pro halts the MapBasic application, and displays a dialog box describing the
error.
The error message identifies the name of the program file and the line number at which the error
occurred. In the example above, the name of the program is map_it, and the line number containing
the error is 16. This line number identifies which part of your program caused the runtime error.
Once you know the line number, you can return to the MapBasic development environment and
use the Go To Line command (on the Search menu) to locate the statement that caused the problem.
Some runtime errors are easy to correct. For example, some runtime errors can be caused by
modest typing errors (for example, in the example above, the programmer probably meant to enter
the table name as STATES instead of STATS). Other errors, however, can be harder to locate. To
help you detect and correct bugs in your program, MapBasic provides debugging tools (the Stop
and Continue statements) which work in conjunction with MapInfo Pro's MapBasic window.
If part of your program is not working correctly, you can use the following procedure to identify where
the problem occurs:
1. Within the MapBasic development environment, edit your program, and place a Stop statement
just before the part of your program that seems to be failing.
2. Recompile and run your program.
When your program reaches the Stop statement, MapBasic temporarily suspends execution of
your program and displays a debugging message in the MapBasic window (for example,
"Breakpoint at textbox.mb line 23").
4. When you are finished examining and modifying the contents of variables, type Continue in the
MapBasic window to resume program execution. In MapInfo Pro, on the HOME tab, click Tools,
and Continue MapBasic Program. Note that while a program is suspended, the Tools menu
contains a Continue MapBasic Program command instead of a Run MapBasic Program command.
In the following cases, MapBasic does not allow you to suspend a program through the Stop
statement:
• You may not use a Stop statement within a custom Function...End Function construct.
• You may not use a Stop statement within a dialog box control handler, because while the handler
is active, the dialog box is still on the screen.
• You may not use a Stop statement within a ProgressBar handler.
• You may not debug one program while another program is running.
• Through the Run Application statement, one MapBasic application can "spawn" another application.
However, you may not use the Stop statement to suspend execution of the spawned application.
Even without using the Run Application statement, it is possible to run separate MapBasic programs
at one time. For example, if you run the TextBox application, TextBox creates its own custom
menu, then remains sleeping until you choose an item from that menu. After loading TextBox, you
can run other MapBasic applications. However, you may not use the Stop statement while you
have multiple applications running simultaneously.
MapBasic's Note and Print statements are also helpful when debugging a program. For example,
if you wish to observe the contents of a variable as it changes, simply add a Print statement to your
program:
to print a message to MapBasic's Message window. The sample program AppInfo.mbx allows you
to examine the values of global variables in any MapBasic applications that are running.
Error Trapping
A well-designed program anticipates the possibility of runtime errors and includes precautions
whenever possible. Intercepting and dealing with runtime errors is known as error trapping. In
MapBasic, error trapping involves using the OnError statement.
Veteran BASIC programmers take note: in MapBasic, OnError is a single keyword.
At any point during execution, error trapping is either enabled or disabled. By default, all procedures
and functions start with error trapping disabled. The OnError statement enables error trapping.
Typically, OnError specifies a label that must appear at another location in the same procedure or
function. The statements following the label are known as the error-trapping routine. If an error
occurs while an error-trapping routine has been enabled, MapBasic jumps to the specified label and
executes the error-trapping routine instead of halting the application.
Within the error-trapping routine, you can call the Err( ) function to obtain an Integer code indicating
which error occurred. Similarly, Error$( ) returns a string describing the error message. For a complete
listing of potential MapBasic error codes and their descriptions, see the text file errors.doc which is
included with MapBasic. Each error-trapping routine ends with a Resume statement. The Resume
statement tells MapBasic which line to go to once the error-trapping routine is finished.
For more about error trapping, see OnError, Resume, Err( ) and Error$( ) in the MapBasic Reference.
Note: MapBasic can only handle one error at a time. If you enable error-trapping and then an error
occurs, MapBasic jumps to your error-handling routine. If another error occurs within the
error-handling routine (i.e., before the Resume statement), your MapBasic application halts.
The program below opens a table called orders and displays it in Map and Browse windows. An
error-trapping routine called bad_open handles any errors that relate to the Open Table statement.
A second error-trapping routine called not_mappable handles errors relating to the Map statement.
Sub orders_setup
' At the start, error trapping is disabled
OnError Goto bad_open
' At this point, error trapping is enabled, with
' bad_open as the error-handling routine.
Open Table "orders.tab"
OnError Goto not_mappable
last_exit:
Exit Sub
' The Exit Sub prevents the program from
' unintentionally executing the error handlers.
bad_open:
' This routine called if Open statement had an error.
Note "Couldn't open the table Orders... Halting."
Resume last_exit
not_mappable:
' This routine called if the Map statement had an error
Note "No map data; data will only appear in Browser."
Resume Next
End Sub
The statement OnError Goto bad_open enables error trapping. If an error occurs because of the
Open Table statement, MapBasic jumps to the error-trapping routine at the label bad_open. The
error-trapping routine displays an error message, then issues a Resume statement to resume
execution at the label last_exit.
If the Open Table statement is successful, the program then issues the statement OnError Goto
not_mappable. This line resets the error trapping, so that if the Map statement generates an error,
MapBasic jumps to not_mappable. The not_mappable error-trapping routine displays a message
telling the user why no Map window was presented, and then executes a Resume Next statement.
The Resume Next statement tells MapBasic to skip the line that generated the error, and resume
with the following statement.
The OnError Goto 0 statement disables error trapping. Thus, if an error occurs as a result of the
Browse statement, that error is not trapped, and program execution halts.
In this section
Introduction to MapBasic User Interface Principles 95
Event-Driven Programming 95
Menus 97
Standard Dialog Boxes 110
Custom Dialog Boxes 112
Windows 122
ButtonPads (Toolbars) 136
Cursors 145
Integrating Your Application Into MapInfo Pro 146
Loading Applications Through the Startup Workspace 147
Manipulating Workspaces through MapBasic 147
Creating the User Interface
By writing a MapBasic program, you can create a custom user interface for MapInfo Pro. A MapBasic
program can control the following elements of the user interface:
• Menus: MapBasic programs can add custom menu items to existing menus, remove menus from
the menu bar, and create entirely new menus.
• Dialog boxes: MapBasic programs can display custom dialog boxes, tailored to fit the users' needs.
• Windows: MapBasic programs can display standard types of MapInfo Pro windows (for example,
Map and Browse windows) and customize the contents of those windows. MapBasic can also
display messages in a special window (the Message window) and on the MapInfo Pro status bar.
• ButtonPads (also known as toolbars): MapBasic programs can add custom buttons to existing
ButtonPads, or create entirely new ButtonPads. MapInfo Pro includes a special ButtonPad, Tools,
to provide a place where MapBasic utilities can add custom buttons. For example, the ScaleBar
application adds its custom button to the Tools pad.
The sample application, OverView, demonstrates many aspects of a custom interface created in
MapBasic. When the user runs OverView, MapBasic adds custom items to the Tools menu. If the
user chooses the custom Setup Overview menu item, MapBasic displays a custom dialog box. If
the user chooses a table from this dialog box, MapBasic opens a new Map window to display the
table.
Note: MapInfo Pro 64-bit has a new Ribbon-Based Interface instead of menus that we have in the
32-bit version. Because of this the MapBasic commands related to ButtonPads and Menus
behave differently in the MapInfo Pro 64-bit. They create a new tab called LEGACY in the
MapInfo Pro Ribbon and any modifications made using these commands are visible only on
this tab.
For customizing the Ribbon Interface of MapInfo Pro 64-bit, see Getting Started with Ribbon
Interface (MapInfo Pro 64-bit).
Event-Driven Programming
What Is an Event?
In a Graphical User Interface environment, the user controls what happens by typing and by using
the mouse. Technically, we say that mouse-clicks and other actions taken by the user generate
events. There are many different kinds of events; for example, when the user chooses a menu item,
we say that the user has generated a menu-choose event, and when the user closes a window, we
say the user has generated a window-close event.
When the user generates an event, the software must respond accordingly. Thus, when the user
chooses a menu item, the software may need to display a dialog box or, depending on which menu
item the user chooses, the software may need to take some other action, such as opening or closing
a table or a window. In general, when the user generates an event, we say that the software handles
the event.
If a MapBasic application creates a custom menu, and the user chooses an item from that menu,
the MapBasic application handles the menu-choose event. Typically, the MapBasic application
handles the event by calling a procedure. In this situation, we say that the procedure acts as an
event-handler, or handler for short.
Thus, creating custom menu items is typically a two-step process:
1. Customize the MapInfo Pro menu structure, using statements such as Create Menu or Alter
Menu.
2. Specify a handler for each custom menu item. A handler can be a sub-procedure that appears
elsewhere in your program. Set up each handler procedure to perform whatever tasks are
appropriate for the corresponding menu item(s). Alternately, instead of specifying a procedure
as the menu item's handler, you can specify that the menu item call a standard MapInfo Pro
command. Thus, you could create a custom menu item that invokes the Create Thematic Map
command (from MapInfo Pro's Map menu).
As noted in Using the Development Environment, the Call statement lets you call a sub-procedure.
However, when a sub-procedure acts as an event-handler, you do not issue any Call statements.
Instead of issuing Call statements, you include a Calling clause within the Create Menu statement.
For example, the TextBox application issues the following Create Menu statement:
This statement creates a custom menu with several menu items, each of which contains a Calling
clause (for example, Calling create_sub). Each Calling clause identifies the name of a procedure
that appears elsewhere in the TextBox.mb program. Thus, create_sub, Bye, and About are all
sub-procedure names.
When and if the user chooses the Create Text Boxes item from the TextBox menu, MapBasic
automatically calls the create_sub procedure. Thus, the create_sub procedure acts as the handler
for that menu item.
Each button on a custom MapBasic ButtonPad has a handler procedure. Like the Create Menu
statement, the Create ButtonPad statement contains a Calling clause which lets you designate a
handler procedure. When the user works with a custom button, MapBasic calls the sub-procedure
that you named in the Create ButtonPad statement.
MapBasic lets you create different types of custom buttons. With custom PushButtons, MapBasic
calls the button's handler the moment the user chooses the button. With custom ToolButtons,
MapBasic only calls the button's handler if the user chooses the tool and then clicks on a window.
For more information, see ButtonPads (Toolbars).
Custom MapBasic dialog boxes can call handler procedures. Thus, if you create a custom dialog
box that contains a check-box, MapBasic can call a handler procedure each time the user checks
or clears the check-box. However, depending on your application, you may not need to create
handlers for your dialog boxes. For a discussion of custom dialog boxes, see Custom Dialog Boxes.
Menus
Menus are an essential element of the graphical user interface. Accordingly, the MapBasic language
lets you control every aspect of MapInfo Pro's menu structure. With a few lines of code, you can
customize any or all of MapInfo Pro's menus or menu items.
Menu Fundamentals
The menu bar is the horizontal bar across the top of the MapInfo Pro work area. The default MapInfo
Pro menu bar contains words such as File, Edit, Objects, Query, etc.
A menu is a vertical list of commands that drops down if you click on the menu bar. For example,
most applications include a File menu and an Edit menu.
A menu item is an individual command that appears on a menu. For example, the File menu typically
contains menu items such as Open, Close, Save, and Print. Menu items are sometimes referred to
as commands (for example, the FileSave command.
Figure 2: A menu bar with the selected menu shown highlighted in blue.
The concepts of menu, menu bar, and menu item are interrelated. Each menu is a set of menu
items. For example, the File menu contains items such as Open, Close, Save, etc. The menu bar
is a set of menus.
When the user chooses a menu item, some sort of action is initiated. Different menu items invoke
different types of actions; some menu items cause dialog boxes to be displayed, while other menu
items produce an immediate effect.
The action associated with a menu item is referred to as the menu item's handler. A menu item
handler can either be a standard MapInfo Pro command code or a custom MapBasic sub-procedure
name. In other words, when the user chooses a menu item, MapInfo Pro "handles" the menu-choose
event, either by running a standard command code or by calling a sub-procedure from your
application.
To add one or more custom items to an existing menu, use the Alter Menu statement.
For example, the following statement adds two custom menu items to the Query menu (one item
called Annual Report, and another item called Quarterly Report):
For each of the custom menu items, the Alter Menu statement specifies a Calling clause. This clause
specifies what should happen when and if the user chooses the menu item. If the user chooses the
Annual Report item, MapInfo Pro calls the sub-procedure report_sub.
If the user chooses the Quarterly Report item, MapInfo Pro calls the sub-procedure report_sub_q.
These sub-procedures (report_sub and report_sub_q) must appear elsewhere within the same
MapBasic application.
You also can create custom menu items that invoke standard MapInfo Pro commands, rather than
calling MapBasic sub-procedures. The definitions file menu.def contains a list of definitions of menu
codes (for example, M_FILE_NEW and M_EDIT_UNDO). Each definition in that file corresponds
to one of the standard MapInfo Pro menu commands (for example, M_EDIT_UNDO corresponds
to the Edit menu's Undo command). If a menu item's Calling clause specifies one of the menu codes
from menu.def, and the user chooses that menu item, MapInfo Pro invokes the appropriate MapInfo
Pro command.
For example, the following statement defines a "Color Coded Maps" menu item. If the user chooses
Color Coded Maps, MapInfo Pro runs the command code M_MAP_THEMATIC. In other words, if
the user chooses the menu item, MapInfo Pro displays the Create Thematic Map dialog box, just
as if the user had chosen the Add Theme command (on the MAP tab).
An application can remove individual menu items. The following statement removes the Delete
Table item from MapInfo Pro's TableMaintenance menu. Note that the identifier M_TABLE_DELETE
is a code defined in the menu definitions file, menu.def.
If you want to remove several items from a menu, there are two techniques you can use: you can
issue an Alter Menu...Remove statement which lists all the items you wish to remove; or you can
issue a Create Menu...statement which redefines the menu entirely, including only the items you
want.
For example, the following statement creates a simplified version of the Map menu that includes
only three items (Layer Control, Previous View, and Options):
To create an all-new menu, use the Create Menu statement. For example, the sample application,
TextBox, issues the following Create Menu statement:
The Create Menu statement creates a new "TextBox" menu. However, the act of creating a menu
does not cause the menu to appear automatically. To make the new menu become visible, you
must take an additional step.
You could make the TextBox menu visible by adding it to the menu bar, using the Alter Menu Bar
statement:
The Alter Menu Bar Add statement adds the menu to the right end of the menu bar. The menu
produced would look like this:
In practice, adding menus onto the menu bar is sometimes problematic. The amount of space on
the menu bar is limited, and every time you add a menu to the menu bar, you fill some of the
remaining space. Therefore, for the sake of conserving space on the menu bar, the TextBox
application uses a different technique for displaying its menu: instead of adding its menu directly
onto the menu bar, the TextBox application uses an Alter Menu statement to add its menu as a
hierarchical sub-menu, located on the Tools menu.
As a result of this statement, the TextBox menu appears as a hierarchical menu located on the
Tools menu. The resulting Tools menu looks like this:
Sample programs that are provided with MapInfo Pro, such as ScaleBar and OverView, follow the
same convention (placing their menu items on hierarchical menus located off of the Tools menu).
Thus, if you run the TextBox application, the ScaleBar application, and the OverView application,
all three applications add their commands to the Tools menu.
If each of the sample programs (ScaleBar, etc.) added a menu directly onto the menu bar, the menu
bar would quickly become over-crowded. Stacking hierarchical menus onto the Tools menu (or any
other menu) is one way of conserving space on the menu bar. Note, however, that some users find
hierarchical menus significantly harder to use.
How you design and organize your menus will depend on the nature of your application. Depending
on your application, you may need to add one, two, or even several menus to the menu bar.
Regardless of whether you attach your menus to the menu bar or to other menus, MapInfo Pro is
limited to 96 menu definitions. In other words, there can never be more than 96 menus defined at
one time, including MapInfo Pro's standard menus. This limitation applies even when you are not
displaying all of the menus.
The MapBasic language lets you perform the following operations on individual menu items:
• You can disable (gray out) a menu item, so that the user cannot choose that menu item.
The Pick Frame Style menu item is initially disabled. (Whenever the name of a menu item begins
with the "(" character, that menu item is automatically disabled when the menu first appears.)
When and if the user sets up an overview window, the OverView application enables the Pick Frame
Style menu item, using the following statement:
If the user closes the overview window, the application once again disables the Pick Frame menu
item, by issuing the following statement:
PickFrame is the name of a sub-procedure in overview.mb. Note that PickFrame appears in both
the Create Menu statement (in the Calling clause) and in the Alter Menu Item statements. When
you issue an Alter Menu Item statement, you must specify which menu item you want to alter. If you
specify the name of a procedure (for example, PickFrame), MapInfo Pro modifies whatever menu
item calls that procedure.
Similarly, to enable the Suspend Tracking menu item, issue the following statement:
You also can use Alter Menu Item to change the name of a menu item. For example, the OverView
application has a menu item that is initially called Suspend Tracking. If the user chooses Suspend
Tracking, the application changes the menu item's name to Resume Tracking by issuing the following
statement:
Note that MapInfo Pro enables and disables its own standard menu items automatically, depending
on the circumstances. For example, the Map command (on the HOME tab in the Document Windows
group) is only enabled when and if a mappable table is open. Because MapInfo Pro automatically
alters its own standard menu items, a MapBasic application should not attempt to enable or disable
those menu items.
To remove an entire menu from the menu bar, use the Alter Menu Bar statement. For example, the
following statement causes the Query menu to disappear:
You also can use Alter Menu Bar to add menus to the menu bar. For example, the following statement
adds both the Map menu and the Browse menu to the menu bar. (By default, those two menus
never appear on the menu bar at the same time. The Map menu ordinarily appears only when a
Map is the active window, and the Browse menu ordinarily appears only when a Browser window
is active.)
The Alter Menu Bar Add statement always adds menus to the right end of the menu bar. One minor
disadvantage of this behavior is the fact that menus can end up located to the right of the Help
menu. Most software packages arrange the menu bar so that the last two menu names are Window
and Help. Therefore, you may want to insert your custom menu to the left of the Window menu. The
following statements show how to insert a menu to the left of the Window menu:
The first statement removes the Window menu (ID 6) and Help menu (ID 7) from the menu bar. The
second statement adds the Tools menu, the Window menu, and the Help menu to the menu bar.
The end result is that the Tools menu is placed to the left of the Window menu.
For complete control over the menu order, use the Create Menu Bar statement. For example, this
statement re-defines the menu bar to include the File, Edit, Map, Query, and Help menus (in that
order):
For a list of MapInfo Pro's standard menu names ("File", "Query" etc.) see Alter Menu in the MapBasic
Reference or MapBasic Help. To restore MapInfo Pro's standard menu definitions, issue a Create
Menu Bar As Default statement.
Most of the preceding examples refer to menus by their names (for example, "File"). There is an
alternate syntax for referring to MapInfo Pro's standard menus: you can identify standard menus by
ID numbers. For example, in any menu-related statement where you might refer to the File menu
as "File", you could instead refer to that menu as ID 1. Thus, the following statement removes the
Query menu (which has ID number 3) from the menu bar:
If your application will be used in more than one country, you may want to identify menus by their
ID numbers, rather than by their names. When the MapInfo Pro software is localized for non-English
speaking countries, the names of menus are changed. If your application tries to alter the "File"
menu, and you run your application on a non-English version of MapInfo Pro, your application may
generate an error (because in a non-English version of MapInfo Pro, "File" may not be the name of
the menu). For a listing of the ID numbers that correspond to MapInfo Pro's standard menus, see
Alter Menu in the MapBasic Reference or MapBasic Help.
MapInfo Pro provides shortcut menus. These menus appear if the user clicks the right mouse button.
To manipulate shortcut menus, use the same statements you would use to manipulate conventional
menus: Alter Menu, Alter Menu Item, and Create Menu.
Each shortcut menu has a unique name and ID number. For example, the shortcut menu that
appears when you right-click a Map window is called "MapperShortcut" and has an ID of 17. For a
listing of the names and ID numbers of the shortcut menus, see Alter Menu in the MapBasic
Reference or MapBasic Help.
To destroy a shortcut menu, use the Create Menu statement to re-define the menu, and specify the
control code "(-" as the new menu definition. For example:
The Create Menu and Alter Menu statements provide an optional ID clause, which lets you assign
a unique ID number to each custom menu item you create. Menu item IDs are optional. However,
if you intend to have two or more menu items calling the same handler procedure, you will probably
want to assign a unique ID number to each of your custom menu items.
In situations where two or more menu items call the same handler procedure, the handler procedure
generally calls CommandInfo( ) to determine which item the user chose. For example, the following
statement creates two custom menu items that call the same handler:
Both menu items call the procedure report_sub. Because each menu item has a unique ID, the
handler procedure can call CommandInfo( ) to detect which menu item the user chose, and act
accordingly:
Sub report_sub
If CommandInfo(CMD_INFO_MENUITEM) = 201 Then
'
' ... then the user chose Annual Report...
'
ElseIf CommandInfo(CMD_INFO_MENUITEM) = 202 Then
'
' ... then the user chose Quarterly Report...
'
End If
End Sub
Menu item IDs also give you more control when it comes to altering menu items. If an Alter Menu
Item statement identifies a menu item by the name of its handler procedure, MapBasic modifies all
menu items that call the same procedure. Thus, the following statement disables both of the custom
menu items defined above (which may not be the desired effect):
Depending on the nature of your application, you may want to modify only one of the menu items.
The following statement disables only the Annual Report menu item, but has no effect on any other
menu items:
To activate a MapInfo Pro command as if the user had chosen that menu item, use the Run Menu
Command statement. For example, the following statement displays MapInfo Pro's Open Table
dialog box, as if the user had chosen FileOpen Table:
Shortcut keys are keystroke combinations that let the user access menus and menu items directly
from the keyboard, without using the mouse. Typically, a shortcut key appears as an underlined
letter in the name of the menu or menu item when the Alt key is pressed. For example, in Windows,
the shortcut keystroke to activate the MapInfo Pro File menu is Alt+F, as indicated by the underlined
letter, F after the Alt key is pressed. To assign a shortcut key to a menu item, place an ampersand
(&) directly before the character that you want to define as the shortcut key.
The following program fragment shows how a MapBasic for Windows program defines the C key
(in Create Text Boxes) as a shortcut key.
Hot keys are keystroke combinations that let the user execute menu commands without activating
the menu. Unlike shortcut keys that let you traverse through the menu structure using the keyboard,
hot keys let you avoid the menu completely. The following program fragment adds the hot key
combination Ctrl+Z to a custom menu item:
The instruction + Chr$(9) tells MapBasic to insert a tab character. The tab character is used for
formatting, so that all of the menu's hotkey descriptions appear aligned.
The text CTRL+Z appears on the menu, so that the user can see the menu item has a hot key.
The instruction /w^%122 defines the hot key as Ctrl+Z. The code /w^%122 is a hot key code
recognized by MapInfo Pro: /w specifies that the code is for MapInfo Pro for Windows; the caret (^)
specifies that the user should hold down the Ctrl key; and %122 specifies the letter "z" (122 is the
ASCII character code for `z').
The default menu structure of MapInfo Pro is controlled by the MapInfo Pro menus file. If you want
to customize MapInfo Pro's menu structure, you can do so by altering the menus file.
With MapInfo Pro, the menus file is called MAPINFOPRO.MNU.
Since the menus file is a text file, you can view it in any text editor. If you examine the menus file,
you will see that it bears a strong resemblance to a MapBasic program. If you change the menu
definitions in the menus file, the menus will look different the next time you run MapInfo Pro. In other
words, altering the menus file gives you a way of customizing the menu structure without using a
compiled MapBasic application.
CAUTION: Before you make any changes to the menus file, make a backup of the file. If the menus
file is corrupted or destroyed, you will not be able to run MapInfo Pro (unless you can
restore the menus file from a backup). If you corrupt the menus file, and you cannot
restore the file from a backup, you will need to re-install MapInfo Pro.
The menus file contains several Create Menu statements. These statements define MapInfo Pro's
standard menu definitions (File, Edit, etc.). If you wish to remove one or more menu items from a
menu, you can do so by removing appropriate lines from the appropriate Create Menu statement.
For example, MapInfo Pro's TableMaintenance menu usually contains a Delete Table command,
as shown below.
If you examine the menus file, you will see that the Maintenance menu is defined through a Create
Menu statement that looks like this:
Because the Delete Table command is potentially dangerous, you might want to re-define the
Maintenance menu to eliminate Delete Table. To eliminate the Delete Table command from the
menu, remove the appropriate lines ("&Delete Table..." through to calling 409) from the menus file.
After you make this change, the Create Menu statement will look like this:
The next time you run MapInfo Pro, the TableMaintenance menu will appear without a Delete Table
item.
Similarly, if you wish to remove entire menus from the MapInfo Pro menu bar, you can do so by
editing the Create Menu Bar statement that appears in the menus file.
If MapInfo Pro is installed on a network, and you modify the menus file in the directory where MapInfo
Pro is installed, the changes will apply to all MapInfo Pro users on the network. In some
circumstances, you may want to create different menu structures for different network users. For
example, you may want to eliminate the Delete Table command from the menu that appears for
most of your users, but you may want that command to remain available to your network system
administrator.
To assign an individual user a customized menu structure, place a customized version of the menus
file in that user's "home" directory. For Windows users, the home directory is defined as the user's
private Windows directory (i.e., the directory where WIN.INI resides).
To assign an individual user a customized menu structure, place a customized version of the menus
file in that user's "home" directory/folder. The menus file can be placed directly in the System
directory, or in the Preferences directory within the System directory.
When a user runs MapInfo Pro, it checks to see if a copy of the menus file exists in the user's home
directory. If a copy of the menus file is present in the user's home directory, MapInfo Pro loads that
set of menus. If there is no menus file in the user's home directory, MapInfo Pro loads the menus
file from the directory where it is installed.
Thus, if you want different users to see two different versions of the menu structure, create two
different versions of the menus file. Place the version that applies to most of your users in the
directory where MapInfo Pro is installed. Place the version that applies only to individual users in
the home directories of the individual users.
Dialog boxes are an essential element of the user interface. MapBasic provides several different
statements and functions that let you create dialog boxes for your application.
Displaying a Message
Use the Note statement to display a simple dialog box with a message and an OK button.
Use the Ask( ) function to display a dialog box with a prompt and two buttons. The two buttons
usually say OK and Cancel, but you can customize them to suit your application. If the user chooses
the OK button, the function returns a TRUE value, otherwise, the function returns FALSE.
Selecting a File
Call the FileOpenDlg( ) function to display a standard File Open dialog box. If the user chooses a
file, the function returns the name of the chosen file. If the user cancels out of the dialog box, the
function returns an empty string.
The FileOpenDlg( ) function produces a dialog box that looks like this:
The FileSaveAsDlg() function displays a standard File Save As dialog box, and returns the file
name entered by the user.
Use the ProgressBar statement to display a standard percent-complete dialog box, containing a
progress bar and a Cancel button.
MapInfo Pro does not provide a standard dialog box that displays one row from a table. However,
you can use MapInfo Pro's Info window to display a row. For instructions on managing the Info
window, see Customizing the Info window.
For more information about the statements and functions listed above, see the MapBasic Reference.
If none of the preceding statements meets your needs, use the Dialog statement to create a custom
dialog box, as described below.
The Dialog statement lets you create custom dialog boxes. When you issue a Dialog statement,
MapInfo Pro displays the dialog box and lets the user interact it. When the user dismisses the dialog
box (for example, by clicking the OK or Cancel button), MapInfo Pro executes any statements that
follow the Dialog statement. After the Dialog statement, you can call the CommandInfo( ) function
to tell whether the user chose OK or Cancel.
Everything that can appear on a dialog box is known as a control. For example, every OK button is
a control, and every Cancel button is also a control. To add controls to a dialog box, include Control
clauses within the Dialog statement. For example, the following statement creates a dialog box with
four controls: a label (known as a StaticText control); a box where the user can type (known as an
EditText control); an OK push-button (known as OKButton control) and a Cancel push-button
(CancelButton control).
Dialog
Title "Search"
Control StaticText
If you want to change the size of a dialog box control, you can include the optional Width and Height
clauses within the Control clause. If you want to change the position of a dialog box control, you
can include the optional Position clause.
For example, you might not like the default placement of the buttons in the dialog box shown above.
To control the button placement, you could add Position clauses, as shown below:
Because two of the Control clauses include Position clauses, the dialog box's appearance changes:
Positions and sizes are stated in terms of dialog box units, where each dialog box unit represents
one quarter of a character's width or one eighth of a character's height. The upper-left corner of the
dialog box has the position 0, 0. The following Position clause specifies a position in the dialog box
five characters from the left edge of the dialog box, and two characters from the top edge of the
dialog box:
Position 20, 16
A horizontal position of 20 specifies a position five characters to the right, since each dialog box
unit represents one fourth of the width of a character. A vertical position of 16 specifies a position
two characters down, since each dialog box unit spans one eighth of the height of a character.
You can include a Position clause for every control in the dialog box. You also can specify Width
and Height clauses to customize a control's size.
Control Types
The previous examples contained four types of controls (StaticText, EditText, OKButton, and
CancelButton). The following illustration shows all of MapBasic's dialog box control types.
Each control type shown in the previous dialog box is named in the following list:
• StaticText box – The Enter Map Title box.
• GroupBox – The Level of Detail panel.
• RadioGroup – The Full Details and the Partial Details radial buttons.
• ListBox – The Show Results For list box.
• PopupMenu – The scope of Map drop-down list.
• Button – The Reset button.
• OKButton – The OK button.
• EditText box – The Enter Map Title box, where the user can type their input.
• Picker (SymbolPicker) – The Show Franchises As button, which displays a symbol on it.
• MultiListBox – The Include Map Layers scrolling list box.
• Checkbox – The Include Legend checkbox.
• CancelButton – The Cancel button.
StaticText
A StaticText control is a non-interactive control that lets you include labels in the dialog box. For
example:
Control StaticText
Title "Enter map title:"
Position 5, 10
EditText
An EditText control is a boxed area where the user can type. For example:
Control EditText
Value "New Franchises, FY 95"
Into s_title
ID 1
Position 65, 8 Width 90
GroupBox
A GroupBox control is a rectangle with a label at the upper left corner. Use GroupBoxes for visual
impact, to convey that other dialog box controls are related. For example:
Control GroupBox
Title "Level of Detail"
Position 5, 30 Width 70 Height 40
RadioGroup
A RadioGroup control is a set of "radio buttons" (i.e., a list of choices where MapBasic only allows
the user to select one of the buttons at a time). For example:
Control RadioGroup
Title "&Full Details;&Partial Details"
Value 2
Into i_details
ID 2
Position 12, 42 Width 60
Picker
There are four types of Picker controls: PenPicker, BrushPicker, FontPicker, and SymbolPicker.
Each Picker control lets the user select a graphical style (line, fill, font, or symbol). The illustration
shown above includes a SymbolPicker control, showing a star-shaped symbol. For example:
Control SymbolPicker
Position 95, 45
Into sym_variable ID 3
ListBox
A ListBox control is a scrollable list from which the user can select one item. MapBasic automatically
appends a vertical scroll bar to the right edge of the ListBox if there are too many list items to be
displayed at one time. For example:
Control ListBox
Title "First Qrtr;2nd Qrtr;3rd Qrtr;4th Qrtr"
Value 4
Into i_quarter
ID 4
Position 5, 90 Width 65 Height 35
MultiListBox
A MultiListBox is similar to a ListBox, except that the user can Shift+click or Ctrl+click to select two
or more items from the list. For example:
Control MultiListBox
Title "Streets;Highways;Towns;Counties;States"
Value 3
ID 5
Position 95, 90 Width 65 Height 35
PopupMenu
A PopupMenu appears as a text item with a down arrow at the right edge. As the user clicks on the
control, a menu pops up, allowing the user to make a selection. For example:
Control PopupMenu
Title "Town;County;Territory;Entire state"
Value 2
Into i_scope
ID 6
Position 5, 140
CheckBox
A CheckBox is a label with a box. The user can check or clear the box by clicking on the control.
For example:
Control CheckBox
Title "Include &Legend"
Into l_showlegend
ID 7
Position 95, 140
Buttons
Button controls are perhaps the most common type of control that you will use, since almost every
dialog box has at least one button. MapBasic provides special control types OKButton and
CancelButton for creating OK and Cancel buttons.
Control Button
Title "&Reset"
Calling reset_sub
Position 10, 165
Control OKButton
Position 65, 165
Calling ok_sub
Control CancelButton
Position 120, 165
Each dialog box should have no more than one OKButton or CancelButton control. Both controls
are optional. However, as a general rule, every dialog box should have at least one OK and/or a
Cancel button, so that the user has a way of dismissing the dialog box. If either control has a handler,
MapBasic executes the handler procedure and then resumes executing the statements that follow
the Dialog statement.
Every type of control is described in detail in the MapBasic Reference and MapBasic Help. For
example, to read about ListBox controls, see Control Listbox.
Most types of controls have an optional Value clause. This clause specifies how the control is set
when the dialog box first appears. For example, if you want the fourth item in a ListBox control to
be selected when the dialog box first appears, add a Value clause to the ListBox clause:
Value 4
If you omit the Value clause, MapInfo Pro uses a default value. For example, CheckBox controls
are checked by default. For more information about setting a Value clause, see the appropriate
Control description (for example, Control CheckBox) in the MapBasic Reference.
Most types of controls allow an optional Into clause. This clause associates a program variable with
the control, so that MapInfo Pro can store the dialog box data in the variable. If you create a control
with an Into clause, and if the user closes the dialog box by clicking the OK button, MapInfo Pro
stores the control's final value in the variable.
The Into clause must name a local or global variable in your program. The variable that you specify
must be appropriate for the type of control. For example, with a CheckBox control, the variable must
be Logical (TRUE meaning checked, FALSE meaning clear). See the MapBasic Reference for more
information about the type of variable appropriate for each control.
Note: MapInfo Pro only updates the Into variable(s) after the dialog box is closed, and only if the
dialog box is closed because the user clicked OK. If you need to read the value of a control
from within a dialog box handler procedure, call the ReadControlValue( ) function.
Most types of controls can have handlers. A handler is a sub-procedure that MapBasic calls
automatically when and if the user clicks that control. The optional Calling handler clause specifies
a control's handler; handler must be the name of a sub-procedure that takes no parameters. When
the user clicks on a control that has a handler procedure, MapBasic calls the procedure. When the
procedure finishes, the user can continue interacting with a dialog box (except in the case of OKButton
and CancelButton controls, which automatically close the dialog box).
Handler procedures allow your program to issue statements while the dialog box is on the screen.
For example, you may want your dialog box to contain a Reset button. If the user clicks on the Reset
button, your program resets all controls in the dialog box to their default values. To create such a
dialog box, you would need to assign a handler procedure to the Reset Button control. Within the
handler procedure, you would issue Alter Control statements to reset the dialog box's controls.
A ListBox or MultiListBox control handler can be set up to respond one way to single-click events
while responding differently to double-click events. The handler procedure can call the
CommandInfo(CMD_INFO_DLG_DBL) function to determine whether the event was a single- or
double-click. For an example of this feature, see the Named Views sample program (nviews.mb).
The Named Views dialog box presents a list of names; if the user double-clicks on a name in the
list, the handler procedure detects that there was a double-click event, and closes the dialog box.
In other words, the user can double-click on the list, rather than single-clicking on the list and then
clicking on the OK button.
If two or more controls specify the same procedure name in the Calling clause, the named procedure
acts as the handler for both of the controls. Within the handler procedure, call the TriggerControl( )
function to determine the ID of the control that was used.
Most dialog box controls can have handler procedures (only GroupBox, StaticText, and EditText
controls cannot have handlers). You also can specify a special handler procedure that is called once
when the dialog box first appears. If your Dialog statement includes a Calling clause that is not part
of a Control clause, the Calling clause assigns a handler procedure to the dialog box itself.
The Alter Control statement may only be issued from within a handler procedure. Use Alter Control
to disable, enable, show, hide, rename, or reset the current setting of a control. The Alter Control
statement can also set which EditText control has the focus (i.e., which control is active). For more
information, see Alter Control in the MapBasic Reference or MapBasic Help.
When a control first appears, it is either enabled (clickable) or disabled (grayed out). By default,
every control is enabled. There are two ways to disable a dialog box control:
• Include the optional Disable keyword within the Dialog statement's Control clause. When the dialog
box appears, the control is disabled.
• From within a handler procedure, issue an Alter Control statement to disable the control. If you
want the control to be disabled as soon as the dialog box appears, assign a handler procedure to
the dialog box itself, by including a Calling clause that is not within a Control clause. This handler
will be called once, when the dialog box first appears. Within the handler, you can issue Alter
Control statements. This technique is more involved, but it is also more flexible. For example, if
you want a control to be disabled, but only under certain conditions, you can place the Alter Control
statement within an If...Then statement.
Note: If you are going to use an Alter Control statement to modify a dialog box control, you should
assign an ID number to the control by including an ID clause in the Dialog statement. For
an example, see Alter Control in the MapBasic Reference or MapBasic Help.
The ListBox control presents a list of choices. There are two ways you can specify the list of items
that should appear in a ListBox control:
• Build a String expression that contains all of the items in the list, separated by semicolons. For
example:
Control ListBox
Title "First Qrtr;2nd Qrtr;3rd Qrtr;4th Qrtr;Year in Review"
• Declare an array of String variables, and store each list item in one element of the array. In the
Control clause, specify the keywords From Variable. For example, if you have created a String
array called s_list, you could display the array in a ListBox control using this syntax:
Control ListBox
Title From Variable s_list
You can use the From Variable syntax in all three of MapBasic's list controls (ListBox, MultiListBox,
and PopupMenu).
If your dialog box contains a MultiListBox control, you must use a handler procedure to determine
what list item(s) the user selected from the list. In most cases, a dialog box with a MultiListBox
control contains an OKButton control with a handler procedure. The OKButton's handler procedure
calls the ReadControlValue( ) function within a loop. The first ReadControlValue( ) call returns the
number of the first selected list item; the next call returns the number of the next selected list item,
etc. When ReadControlValue( ) returns zero, the list of selected items has been exhausted. If
ReadControlValue( ) returns zero the first time you call it, none of the list items are selected.
Within a handler procedure, you can de-select all items in a MultiListBox control by issuing an Alter
Control statement, and assigning a value of zero to the control. To add a list item to the set of
selected items, issue an Alter Control statement with a positive, non-zero value. For example, to
select the first and second items in a MultiListBox control, you could issue the following statements:
Note that both the ReadControlValue( ) function and the Alter Control statement require a control
ID. To assign a control ID to a MultiListBox control, include the optional ID clause in the Control
MultiListBox clause.
When a MapBasic application runs on MapInfo Pro, the application dialog boxes can assign shortcut
keys to the various controls. A shortcut key is a convenience that lets the user activate a dialog box
control using the keyboard instead of the mouse.
To specify a shortcut key for a control, include the ampersand character (&) in the control's title
immediately before the character that is to be used as a shortcut key character. For example, the
following Control clause creates a Button control with R as the shortcut key:
Control Button
Title "&Reset"
Calling reset_sub
Because an ampersand appears in the Button control's title, the user is able to activate the Reset
button by pressing Alt+R. If you want to display an ampersand character in a control, use two
successive ampersand characters (&&).
You cannot specify a shortcut key for an EditText control. However, if you place a StaticText label
to the left of an EditText control, and you specify a shortcut key for the StaticText label, the user
can set the focus on the EditText control by pressing the shortcut key of the StaticText label.
Basic, and call that application from within your MapBasic program (for example, using the Run
Program statement).
After a MapBasic program issues a Dialog statement, it will continue to be displayed until one of
four things happens:
• The user clicks the dialog box's OKButton control (if the dialog box has one).
• The user clicks the dialog box's CancelButton control (if the dialog box has one).
• The user otherwise cancels the dialog box (for example, by pressing the Esc key).
• The user clicks a control that has an associated handler procedure that issues a Dialog Remove
statement.
Ordinarily, a dialog box terminates when the user clicks an OKButton or CancelButton control. There
are times when the user should be allowed to continue using a dialog box after pressing OK or
Cancel. For example, in some dialog boxes if the user presses Cancel, the application asks the
user to verify the cancellation (Are you sure you want to lose your changes?). If the user's response
is No, the application should resume using the original dialog box.
The Dialog Preserve statement lets you allow the user to continue using a dialog box after the OK
or Cancel Button is clicked. You can only issue a Dialog Preserve statement from within the handler
sub-procedure of either the OKButton or CancelButton control.
The Dialog Remove statement halts a dialog box prematurely. When a control's handler procedure
issues a Dialog Remove statement, the dialog box halts immediately. Dialog Remove is only valid
from within a dialog box control's handler procedure. Dialog Remove can be used, for instance, to
terminate a dialog box when the user double-clicks a ListBox control. The Named Views sample
program (NVIEWS.MB) provides an example of allowing the user to double-click in a list.
Windows
A MapBasic application can open and manipulate any of MapInfo Pro's standard window types (Map
windows, Browse windows, etc.).
To open a new document window, issue one of these statements: Map, Browse, Graph, Layout, or
Create Redistricter. Each document window displays data from a table, so you must have the proper
table(s) open before you open the window.
To open one of MapInfo Pro's other windows (for example, the Help window or the Statistics
window), use the Open Window statement.
Many window settings can be controlled through the Set Window statement. For example, you could
use the Set Window statement to set a window's size or position. There are also other statements
that let you configure attributes of specific window types. For example, to control the order of layers
in a Map window, you would issue a Set Map statement. To control the display of a grid in a Browse
window, you would issue a Set Browse statement.
Each document window (Map, Browser, Layout, Graph, Layer Control, Browser, or Redistrict)
has an Integer identifier, or window ID. Various statements and functions require a window ID as a
parameter. For example, if two or more Map windows are open, and you want to issue a Set Map
statement to modify the window, you should specify a window ID so that MapInfo Pro knows which
window to modify.
To obtain the window ID of the active window, call the FrontWindow( ) function. Note that when you
first open a window (for example, by issuing a Map statement), that new window is the active window.
For example, the OverView sample program issues a Map statement to open a Map window, and
then immediately calls the FrontWindow( ) function to record the ID of the new Map window.
Subsequent operations performed by the OverView application refer to the ID.
Note: A window ID is not a simple, ordinal number, such as 1, 2, etc. The number 1 (one) is not a
valid window ID. To obtain a window ID, you must call a function such as FrontWindow( ) or
WindowID( ). For example, to obtain the window ID of the first window that is open, call
WindowID(1). To determine the number of open windows, call NumWindows( ).
The WindowInfo( ) function returns information about an open window. For example, if you want to
determine whether the active window is a Map window, you can call FrontWindow( ) to determine
the active window's ID, and then call WindowInfo( ) to determine the active window's window type.
To close a window, issue a Close Window statement.
• Issue a Set Window statement to control a window's size or position after the window is open.
Note that the Set Window statement requires an Integer window ID.
Map Windows
A Map window displays mappable objects from one or more tables. When opening a Map window,
you must specify the tables that you want to display; each table must already be open.
The following statement opens a Map window:
This example maps the objects from the World, Worldcap, and Grid30 tables.
To add layers to a Map window, issue an Add Map Layer statement. To remove map layers from a
Map window, issue a Remove Map Layer statement. If you want to temporarily hide a map layer,
you do not need to remove it from the map; instead, you can use the Set Map statement to set that
layer's Display attribute to off.
The Set Map statement is a very powerful statement that can control many aspects of a Map window.
By issuing Set Map statements, your program can control map attributes that the user would control
through the MapLayer Control and MapOptions commands. For more information, see Set Map in
the MapBasic Reference.
Use the Shade statement to create a thematic map (a map that uses color coding or other graphical
devices to display information about the data attached to the map). The Shade statement lets you
create the following of MapInfo Pro's styles of thematic maps: ranges, bar charts, pie charts,
graduated symbols, dot density, or individual values. When you create a thematic map, MapInfo
Pro adds a thematic layer to the affected window. To modify a thematic map, use the Set Shade
statement.
Use the Create Grid statement to create a thematic type that enables analysis unconstrained by
pre-existing geographic boundaries. Surface themes provide a continuous color visualization for
point data sets that you previously looked at as a point thematic or graduated symbol. An inverse
distance weighted interpolator populates the surface values from your MapInfo Pro point table. This
powerful thematic can be used in many industries like telco, retail analysis, insurance, traditional
GIS areas, and many more. This new theme and grid format is supported by open APIs for additional
grid formats and interpolators which allows customization by our developer community. Refer to the
Create Grid statement in the MapBasic Reference. To modify a surface thematic, use the Inflect
clause of the Set Map statement.
To change a Map window's projection, you can issue a Set Map statement with a CoordSys clause.
Alternately, you can display a map in a specific projection by saving your table(s) in a specific
projection (using the Commit Table...As statement).
To control whether scroll bars appear on a Map window, issue a Set Window statement.
If the Add Map Layer statement includes the Animate keyword, the layer becomes a special layer
known as the animation layer. When an object in the animation layer is moved, the Map window
redraws very quickly, even if the map is very complex.
The animation layer is useful in realtime applications, where map features are updated frequently.
For example, you can develop a fleet-management application that represents each vehicle as a
point object. You can receive current vehicle coordinates by using GPS (Global Positioning Satellite)
technology, and then update the point objects to show the current vehicle locations on the map. In
this type of application, where map objects are constantly changing, the map redraws much more
quickly if the objects being updated are stored in the animation layer instead of a conventional layer.
The following example opens a table and makes the table an animation layer:
However, you now have a problem: the Trucks layer now appears in the Map window twice―once
as a conventional map layer, and once as an animation layer. Because the Trucks layer is still being
displayed as a conventional layer, MapInfo Pro will not be able to perform fast screen updates. In
other words, updates to the Map window will redraw as slowly as before, which defeats the purpose
of the animation layer feature.
The following example demonstrates how to handle this situation. Before you add the Trucks layer
as an animation layer, turn off the display of the "conventional" Trucks layer:
Browser Windows
A Browser window displays columns of table data. The following statement opens a simple Browser
window that displays all the columns in the World table:
The asterisk specifies that every column in the table should appear in the Browser. To open a
Browser window that displays only some of the columns, replace the asterisk with a list of column
expressions. For example, the following statement opens a Browser window that shows only two
columns:
The Browse statement can specify column expressions that calculate derived values. For example,
the following statement uses the Format$( ) function to create a formatted version of the World
table's Population column. As a result, the second column in the Browser contains commas to make
the population statistics more readable.
If the Browse statement specifies a simple column name (for example, country), the Browser window
allows the user to edit the column values (unless the table is read-only). However, if the Browse
statement specifies an expression that is more complex than just a column name, the corresponding
column in the Browser window is read-only. Thus, if you want to create read-only columns in a
Browser window, you can do so by browsing an expression, rather than a simple column name.
The expressions that you specify in the Browse statement appear as column headers across the
top of the Browser window. The following statement shows how you can override the default column
expression with an alias column header:
Because the String expression "Pop" appears after the column expression, "Pop" will be the column
header that appears on the Browser window.
You can also set the initial default position of the Browser window. The following example positions
the initial display so that the second column of the fifth row is in the upper left position of the Browser
window display:
Graph Windows
A Graph window contains a graph containing labels and values computed from a table. This sample
displays a graph using one column for labels and another for data:
The first item after the keyword Graph is the name of the column that provides labels for the data.
Each following item is an expression that provides the graph with data. The example above is a
simple expression in which the data is one column of the table. You can use any valid numeric
expression.
A Layout window represents a page layout. To open a Layout window, use the Layout statement.
Most Layout windows contain one or more frame objects. To create a frame object, issue a Create
Frame statement. Layout windows also can contain any type of Map object. For example, to place
a title on the page layout, create a text object by issuing a Create Text statement.
A Layout window can be treated as a table. For example, you can add objects to a Layout by issuing
an Insert statement that refers to a table name such as "Layout1." However, strictly speaking, the
objects that appear on a layout are not saved in table format (although they are saved in workspace
files). For more information on accessing a Layout window as if it were a table, see Working With
Tables.
Objects stored on Layout windows must use a Layout coordinate system, which defines object
coordinates in terms of "paper" units such as inches or millimeters. For more information on Layout
coordinates, see Graphical Objects.
A Layout window represents a page layout. To open a Layout window, use the Layout statement.
For a discussion about the differences between a classic Layout window and the regular Layout
window, see Key Differences between Historic and Modern Layout Windows.
To zoom in, zoom out, or re-center a layout, use the Set Layout statement. The following example
resets the layout zoom level to the default (100%) and scrolls the window to the top left:
Some of the clauses in the Set Layout statement apply only to classic Layout windows, and have
no effect on the regular Layout windows; see the MapBasic Help for details.
Once you have the window ID of a Layout window, you can query its status using the LayoutInfo( )
function. You can query the status of specific frames on a Layout using the LayoutItemInfo( )
function. For details on these functions, see the MapBasic Help.
Each map frame has an ID number that identifies it, just as each Map window does. After you create
a map frame, you can call WindowID(0) to obtain the ID number of the most recently-opened map.
Once you know a map frame’s ID number, you can manipulate that map the same way you would
manipulate a Map window. For example, to change the settings on a layer, or to pan or zoom the
map, use the Set Map statement.
Some Map Window operations cannot be performed on map frames. For example, you can maximize
a Map window using a Set Window … Max statement, but you cannot maximize a map frame.
A map frame can be activated (in which case it has a blue border) or inactive. Map tools, such as
the Label tool and the Select tool, only work on a map frame when the frame is active. Users can
activate a map frame by double-clicking or pressing ALT+click on the frame. To activate a map
frame via MapBasic, use the Set Window… Front statement:
When the user switches to a different window, the map frame automatically de-activates. Users can
also deactivate by pressing ALT+click again on the frame, or clicking elsewhere in the Layout
window.
If a Map window is already open, and you want to clone that map into a new map frame in your
Layout, use the Create Frame statement:
Include "mapbasic.def"
Declare Sub Main
Declare Sub WinFocusChangedHandler
Sub Main
Print "Ready to detect Layout Frame activation."
End Sub
Sub WinFocusChangedHandler
Dim winID, layoutID As Integer
winID = FrontWindow()
If (winID = 0) Then
Exit Sub
End If
if (WindowInfo(winID, WIN_INFO_TYPE) <> WIN_MAPPER) Then
Browser frames are more restrictive than Browser windows. Browser frames do not allow the user
to select rows or edit cells. Also, the browser toolbar (at the top of each Browser window) is not
included in browser frames, because layouts are used primarily for output and printing, and images
of toolbars do not add value to printouts.
You can sort or filter browser Frames, using the Set Browse statement, just as you would sort or
filter Browser windows.
Browser frames can be activated like Map frames, using the Set Window… Front syntax, or by
double-clicking or pressing ALT+click mouse gestures.
Although workspaces preserve image frame settings, a .WOR file does not include a copy of the
image; instead, the .WOR file saves the path to the image file. If you share your .WOR files with
others, make sure you also provide copies of any image files that you display in image frames.
If the image file is in the same directory as the .WOR file (or in a subdirectory of that directory), the
.WOR file stores a relative path in the Add Image Frame statement.
Layout Designer
Set CoordSys Layout Units "in"
Create Text Into Window FrontWindow( )
"Title goes here\nSubtitle goes here"
(0.3, 0.3) (8.2, 1.2)
Font ("Times New Roman",1,16,255)
Justify Center
Some aspects of the Font clause, such as halo color, expanded text, and shadow text are ignored
by Layout.
Layout Designer
Set CoordSys Layout Units "in"
Create Rect
Into Window FrontWindow()
(0.25, 0.2) (8.25, 1.5)
Pen(1,2,0) Brush(2,14737632,14737632)
The shape-creation statements let you include an optional Pen clause to specify the line style for
lines and borders. Except for the Create Line statement, they also let you include a Brush clause
to specify a fill style. If you omit these style clauses, then the objects are created using MapInfo
Pro’s current styles.
Note: The Layout supports only simple, solid line and fill styles. If the Pen or Brush clause specifies
non-solid patterns, then those patterns are ignored and the resulting shape will still use a
simple, solid style. (This restriction does not apply to the contents of map frames. You can
use complex line and fill styles in your map layers, and those styles will work correctly in a
map frame in Layout).
To create the object in front of or on top of other layout frames, specify a larger Priority value. Priority
values are integers of 1 or larger. If you do not specify a Priority when creating a legend frame, then
the frame is automatically placed on top of other frames.
Frames may be created with duplicate Priority values. The render order places the most recently
created item over the others of equal priority. No adjustment to the existing object z-order attributes
are made as a result of processing a Priority n clause.
Note: There is no support for modifying the z-order of a frame via MapBasic.
Redistrict Windows
Use the Create Redistricter statement to begin a redistricting session. The Create Redistricter
statement lets your program control all redistricting options that the user might configure through
the WindowNew District Window dialog box.
Once a redistricting session has begun, you can control the Districts Browser by issuing Set
Redistricter statements. To perform actions from the Redistrict menu, use the Run Menu Command
statement.
For example, to assign objects to a district (as if the user had chosen RedistrictAssign Selected
Objects), issue the following statement:
To end a redistricting session, close the Districts Browser by issuing a Close Window statement.
Note that values in the base table change as objects are re-assigned from district to district. After
a redistricting session, you must save the base table if you want to retain the map objects' final
district assignments. To save a table, issue a Commit statement.
For more information about redistricting, see the MapInfo Pro documentation.
Message Window
You can use MapBasic's Print statement to print text to the Message window. For example, the
following statement prints a message to the Message window:
The following program creates the customized Info window shown above.
Include "mapbasic.def"
Open Table "World" Interactive
Select
Country, Capital, Inflat_Rate + 0 "Inflation"
From World
Into World_Query
Set Window Info
Title "Country Data"
Table World_Query Rec 1
Font MakeFont("Arial", 1, 10, BLACK, WHITE)
Width 3 Units "in" Height 1.2 Units "in"
Select
Country, Capital, Inflat_Rate + 0 "Inflation"
1. In the Set Window Info statement, use the Table... Rec clause to specify which record is displayed.
Specify a row from the query table, as in the example above. When a column in the query table
is defined with an expression, the corresponding box in the Info window is read-only. (In the
example above, the Inflation field is read-only.)
2. When the user types a new value into the Info window, MapInfo Pro automatically stores the
new value in the temporary query table, and in the base table on which the query was based.
You do not need to issue additional statements to apply the edit to the table. (However, you do
need to issue a Commit statement if you want to save the user's edits.)
To make all fields in the Info window read-only, issue the following statement:
Note: All of the fields in the Info window are read-only when you display a table that is a join (such
as a StreetInfo table) or a query table that uses the Group By clause to calculate aggregate
values.
ButtonPads (Toolbars)
A ButtonPad is a resizable, floating window which contains one or more buttons. The user can
initiate various types of actions by choosing buttons from a ButtonPad.
The terms "ButtonPad" and "toolbar" mean exactly the same thing. The MapInfo Pro user interface
refers to toolbars. For example, MapInfo Pro's Options menu has a Toolbars command, which lets
the MapInfo Pro user show or hide toolbars. Meanwhile, the MapBasic language syntax refers to
toolbars as ButtonPads. For example, use the Alter ButtonPad statement to show or hide a toolbar.
MapInfo Pro provides several standard ButtonPads, such as the Main ButtonPad. A MapBasic
program can add custom buttons to existing ButtonPads, or create entirely new ButtonPads.
Like menu items, custom buttons have handler procedures. When a user works with a custom
button, MapBasic automatically calls that button's handler procedure. Thus, if you want MapBasic
to display a custom dialog box each time the user clicks on a button, create a sub procedure which
displays the dialog box, and make that procedure the handler for the custom button.
A MapBasic program can create three different types of buttons: ToolButtons, ToggleButtons, and
PushButtons. The button type dictates the conditions under which MapBasic calls that button's
handler.
• PushButton: When the user clicks on a PushButton, the button springs back up, and MapBasic
calls the PushButton's handler procedure.
The Layer Control button is an example of a PushButton. Clicking on the Layer Control button has
an immediate effect (a dialog box displays), but there is no lasting change to the status of the
button.
• ToggleButton: When the user clicks on a ToggleButton, the button toggles between being checked
(pushed in) and being unchecked (not pushed in). MapBasic calls the button's handler procedure
each time the user clicks on the ToggleButton.
The Show/Hide Legend Window button is an example of a ToggleButton. Clicking on the button
has an immediate effect: showing or hiding the Legend Window. Furthermore, there is a lasting
change to the button's status: the button toggles in or out.
• ToolButton: When the user clicks on a ToolButton, that button becomes the active tool, and remains
the active tool until the user chooses a different tool. MapBasic calls the button's handler procedure
if the user clicks in a Map, Browse, or Layout window while the custom button is the selected tool.
The Magnify tool is an example of a ToolButton. Choosing the tool does not produce any immediate
effects; however, choosing the tool and then clicking in a Map window does have an effect.
The following statements and functions let you create and control custom buttons and ButtonPads:
Create ButtonPad
This statement creates a new ButtonPad and provides a custom icon for a button. You have to
define both small and large sized buttons with resource file ids of n and n+1 respectively.
Alter ButtonPad
After creating a custom ButtonPad, your program can alter various attributes of the ButtonPad. The
Alter ButtonPad statement lets you reposition, show, or hide a ButtonPad, or add or remove buttons
to or from a ButtonPad.
The Alter ButtonPad statement lets you modify any ButtonPad, even standard pads, such as Main.
If your application needs only one or two custom buttons, you may want to add those buttons to the
standard Main ButtonPad, instead of creating a new ButtonPad.
Alter Button
This statement modifies the status of a single button. Use the Alter Button statement to disable
(de-activate) or enable (activate) a button, or to change which button is currently selected.
CommandInfo( )
Use the CommandInfo( ) function within a button's handler procedure to query information about
how the user has used the custom button. For example, if the user chooses a ToolButton and then
clicks in a Map window, the CommandInfo( ) function can read the x- and y-coordinates of the
location where the user clicked.
If you create two or more buttons that call the same handler procedure, that procedure can call
CommandInfo(CMD_INFO_TOOLBTN) to determine which button is in use.
Thus, within a button's handler procedure, you might call CommandInfo( ) several times: Once to
determine which button the user has chosen; once to determine the x-coordinate of the location
where the user clicked; once to determine the y-coordinate; and once to determine whether or not
the user held down the Shift key while clicking.
ToolHandler
ToolHandler, a special procedure name, gives you an easy way to add one button to the Main
ButtonPad. If your MapBasic program includes a procedure named ToolHandler, MapBasic
automatically adds one ToolButton to the Main ButtonPad. Then, if the user chooses the ToolButton,
MapBasic automatically calls the ToolHandler procedure each time the user clicks in a Map, Browse,
or Layout window.
A MapBasic program cannot customize the button icon or draw mode associated with the ToolHandler
procedure; the icon and cursor always use a simple + shape. If you need to specify a custom icon
or cursor, use the Create ButtonPad or Alter ButtonPad statement instead of a ToolHandler procedure.
If the user runs multiple MapBasic applications at one time, and each application has its own
ToolHandler, each application adds its own button to the Main ButtonPad.
The following program creates a custom ButtonPad containing a PushButton. The button_prompt
procedure is the button's handler; therefore, whenever the user clicks the custom PushButton,
MapBasic automatically calls the button_prompt procedure.
Include "icons.def"
Declare Sub Main
Declare Sub button_prompt
Sub Main
Create ButtonPad "Custom" As
PushButton
Icon MI_ICON_ZOOM_QUESTION
Calling button_prompt
HelpMsg "Displays the query dialog\nQuery"
Show
End Sub
Sub button_prompt
' This procedure called automatically when
' the user chooses the button.
' ...
End Sub
The Main procedure contains only one statement: Create ButtonPad. This statement creates a
custom ButtonPad, called "Custom," and creates one custom button on the ButtonPad.
The PushButton keyword tells MapBasic to make the custom button a PushButton.
The Icon clause tells MapBasic which icon to display on the custom button. The identifier,
MI_ICON_ZOOM_QUESTION, is defined in the file icons.def. To see a list of standard MapInfo Pro
icon identifiers, examine icons.def.
The Calling clause tells MapBasic to call the button_prompt procedure whenever the user clicks on
the custom button.
The HelpMsg clause defines both a status bar help message and a ToolTip help message for the
button. Help messages are discussed in Assigning Help Messages to Buttons.
See the Create ButtonPad statement in the MapBasic Reference for image size considerations.
The preceding example used the Create ButtonPad statement to create an all-new ButtonPad.
MapBasic can also add custom buttons to MapInfo Pro's default ButtonPads, such as Main. To add
a button to an existing ButtonPad, use the Alter ButtonPad statement, instead of the Create ButtonPad
statement, as shown in the following example:
The Add PushButton clause adds a custom button to the Main ButtonPad, while the Add Separator
clause places an empty space between the new button and the previous button. The Add Separator
clause is optional; use it when you want to separate buttons into distinct groups.
MapInfo Pro includes a special ButtonPad, called Tools, so that MapBasic utility programs will have
a place where they can add custom buttons. For example, the ScaleBar utility adds its button to the
Tools ButtonPad.
The preceding examples created custom PushButtons. MapBasic also can create custom
ToolButtons, which act like MapInfo Pro tools, such as the Magnify and Line tools. If a program
creates a custom ToolButton, the user can choose that tool, and then use that tool to click, and
sometimes drag, on a Map, Browse, or on an active map frame in a Layout window.
The following example creates a custom ToolButton. After selecting the tool, the user can click and
drag in a Map window. As the user drags the mouse, MapInfo Pro displays a dynamically-changing
line connecting the current cursor position to the location where the user clicked.
Include "icons.def"
Include "mapbasic.def"
Declare Sub Main
Calling draw_via_button
HelpMsg "Draws a line on a Map window\nDraw Line"
Show
End Sub
Sub draw_via_button
Dim x1, y1,x2, y2 As Float
If WindowInfo(FrontWindow(),WIN_INFO_TYPE) <> WIN_MAPPER Then
Note "This tool may only be used on a Map window. Sorry!"
Exit Sub
End If
' Here, you could create objects based on x1, y1, x2, and y2.
End Sub
In this example, the Create ButtonPad statement includes the ToolButton keyword instead of the
PushButton keyword. This tells MapBasic to make the custom button act like a drawing tool.
The button definition includes a DrawMode clause, which tells MapBasic whether the user can drag
after clicking with the tool. The example above uses the DM_CUSTOM_LINE drawing mode;
therefore, the user is able to click and drag with the custom tool, just as you can click and drag when
using MapInfo Pro's standard Line tool. When a tool uses the DM_CUSTOM_POINT mode, the
user cannot drag after clicking. For a listing of all available drawing modes, see Alter ButtonPad in
the MapBasic Reference or MapBasic Help.
The DrawMode clause also controls what the user sees while dragging. With the DM_CUSTOM_LINE
mode, MapBasic draws a line between the cursor location and the point where the user first clicked.
With the DM_CUSTOM_RECT mode, MapBasic draws a rectangular marquee while the user drags
the mouse. Regardless of which DrawMode is used with a ToolButton, MapInfo Pro calls the button's
handler procedure after the user clicks and releases the mouse button. The handler procedure can
call CommandInfo( ) to determine where the user clicked.
Note: If the user cancels the operation by pressing the Esc key, MapInfo Pro does not call the
handler procedure.
When you define a custom button, you control the icon that appears on the button. To specify which
icon you want to use, use the Icon clause.
The keyword Icon is followed by a code from ICONS.DEF. For example, the following statement
defines a custom button that uses the icon for MapInfo Pro's Info button. The code MI_ICON_INFO
is defined in ICONS.DEF.
Note: MapInfo Pro provides many built-in icons, most of which are not used in MapInfo Pro's
standard user interface. To see a demonstration of the built-in icons, run the sample program
Icon Sampler (ICONDEMO.MBX) and then choose an item from the Icon Sampler menu.
To see the code for a particular icon, position the mouse over that icon.
The button's ToolTip shows you the icon code. You also can copy an icon's code to the clipboard:
1. Run the Icon Sampler application (ICONDEMO.MBX).
2. Choose an item from the Icon Sampler menu. A custom ButtonPad appears.
3. Click on the button whose icon you want to use. A dialog box appears.
If the user chooses a custom ToolButton and then clicks on a map object, the object is not selected;
instead, MapInfo Pro calls the custom ToolButton's handler procedure. If you need to select the
object on which the user clicked, issue a Select statement from within the handler procedure.
The following handler procedure selects the town boundary region where the user clicked. To
determine the coordinates where the user clicked, call CommandInfo( ). Then, to select objects at
that location, issue a Select statement with a Where clause, and specify a geographic operator such
as Contains. The following example selects all the town regions that contain the location where the
user clicked.
Sub t_click_handle
Dim fx, fy As Float
fx = CommandInfo(CMD_INFO_X)
fy = CommandInfo(CMD_INFO_Y)
Select * From towns
Where obj Contains CreatePoint(fx, fy)
End Sub
Note: Instead of using a Select statement, you could call the SearchPoint( ) or SearchRect( )
function to perform a search, and then call SearchInfo( ) to process the search results. For
an example of this technique, see SearchInfo( ) in the MapBasic Reference or MapBasic
Help.
Another approach would be to define a procedure called SelChangedHandler. If the user is running
an application that contains a SelChangedHandler procedure, MapInfo Pro automatically calls that
procedure every time the selection changes. The user could select objects by pointing and clicking
with MapInfo Pro's standard Select tool (the arrow-shaped icon at the upper left corner of MapInfo
Pro's Main ButtonPad), and your application could respond by issuing statements within the
SelChangedHandler procedure.
You can include any of MapInfo Pro's standard buttons (such as the Select button) on custom
ButtonPads. For example, the following statement creates a custom ButtonPad containing two
buttons: The standard MapInfo Pro Select button, and a custom button.
Calling M_TOOLS_SELECTOR
HelpMsg "Select objects for editing\nSelect"
' Here is a custom ToolButton...
ToolButton
Icon MI_ICON_LINE
DrawMode DM_CUSTOM_LINE
Calling sub_procedure_name
HelpMsg "Draw New Delivery Route\nNew Route"
The first button's Calling clause specifies M_TOOLS_SELECTOR, which is a numeric code defined
in MENU.DEF. This code represents MapInfo Pro's Select button. Every standard MapInfo Pro
button has a corresponding code in MENU.DEF. Because the second button is a custom button, its
Calling clause specifies the name of a procedure, rather than a numeric code.
Note that the custom button includes a DrawMode clause, but the Select button does not. When
you place a standard button on a custom pad, you should omit the DrawMode clause, because each
of MapInfo Pro's standard buttons already has a pre-defined draw mode. You should only specify
a DrawMode clause when creating a custom ToolButton.
CAUTION: ToolButtons and ToggleButtons are not interchangeable. You cannot convert one type
of button to another type merely by replacing the ToolButton keyword with the
ToggleButton keyword (or vice versa). ToolButtons return x/y coordinates in response
to the user clicking on a window. ToggleButtons, however, do not return coordinates,
and they respond as soon as the user clicks on the button.
If you include standard MapInfo Pro buttons in your custom ButtonPads, make sure that you do not
accidentally change a ToolButton to a ToggleButton. To see how MapInfo Pro's standard buttons
are defined, view the MapInfo Pro menus file, MAPINFOW.MNU. The menus file contains the Create
ButtonPad statements that define MapInfo Pro's ButtonPads.
Note: You can copy button definitions out of MAPINFOW.MNU and paste them into your programs.
Your users may not understand the purpose of a toolbar button just by looking at its icon. Therefore,
MapBasic lets you create two types of on-screen help messages to assist your users:
• Status bar help. Used to show a brief description of the button, this type of help message appears
on the MapInfo Pro status bar (assuming that the status bar is currently visible).
• ToolTip help. Used to show the name of the button, this type of help message appears next to the
mouse cursor.
In earlier versions of MapInfo Pro, status bar help only appeared when the user clicked on a button.
In version 4.0 and later, both the status bar help and ToolTip help appear when the user leaves the
mouse cursor positioned over a toolbar button.
Both types of help messages are defined through the HelpMsg clause, in the Create ButtonPad and
Alter ButtonPad statements. Within the HelpMsg clause, you specify one string that contains the
status bar help message, followed by the letters \n, followed by the ToolTip message.
For example:
In this example, the custom button's status bar help message is "This button generates reports"
and its ToolTip message is "Generate Report." To show or hide the status bar, use the StatusBar
statement.
Use the Alter ButtonPad statement to attach a toolbar to the top edge of the screen. (This is
sometimes known as "docking" the toolbar.) For example, the following statement docks the Main
toolbar:
The keyword Fixed specifies that the pad should be docked to the top of the screen. To change a
toolbar from docked to floating, specify Float instead of Fixed. The Fixed and Float keywords can
also be used within the Create ButtonPad statement, so that you can set the docked status at the
moment you create the toolbar.
To determine whether a toolbar is currently docked, call the ButtonPadInfo( ) function.
The MapBasic development environment does not include a resource editor. However, MapBasic
programs can incorporate bitmaps and cursors created using other resource editors. For more
information about creating custom icons and cursors, see Integrated Mapping.
Cursors
MapInfo Pro users can change the crosshair cursor style by pressing the X key. Cursors in the
MapInfo Pro application are independent of cursors in the MapBasic application, so changing the
cursor style in MapInfo Pro does not change the cursor style in MapBasic and vice versa.
There is no MapBasic support for changing the crosshair cursor style for MapInfo Pro tools, and
there is no MapBasic support for changing cursor style by pressing the X key within a MapBasic
application. However, you can access the crosshair cursor styles for use within your MapBasic
applications. The icons.def file defines the following crosshair cursors.
MapBasic provides you options to switch between 1-bit and 32-bit per pixel cursors. Use them
interchangeably to eliminate delays in the rendering of cursors in environments like Citrix.
The icons.def contains information about 1-bit per pixel cursors for all the cursors except for the
windows default cursors. The cursors MI_CURSOR_ARROW, MI_CURSOR_IBEAM,
MI_CURSOR_CROSS, MI_CURSOR_PLUS, and MI_CURSOR_WAIT do not have a value of 1-bit
per pixel. The rest of the cursors have both 1-bit and 32-bit per pixel values.
For example, the cursor MI_CURSOR_FINGER_LEFT will have a corresponding 1-bit per pixel
cursor in addition to the already existing 32-bit per pixel cursor. The new 1-bit per pixel cursor is
named MI_CURSOR_FINGER_LEFT_1BPP.
The code
will call the 32-bit per pixel cursor MI_CURSOR_FINGER_LEFT. This will switch if you switch the
cursors using the Enable True Color Cursors check box in the System Settings Preferences dialog
box in MapInfo Pro or via a MapBasic command such as the one described above.
However, if you want to use the corresponding 1-bit per pixel cursor explicitly, you need to execute
The preceding sections have discussed how a MapBasic application can customize the user interface
by creating custom menus, dialog boxes, windows, and ButtonPads. Once you have completed
your application, however, one issue will remain: what steps does the user have to take to run your
application, so that your customized user-interface will take effect?
Any MapInfo Pro user can run a MapBasic application by choosing ToolsRun MapBasic Program.
However, you may want to set up your application so that it runs automatically, instead of forcing
your users to choose FileRun MapBasic Program every time they run MapInfo Pro. If you are creating
what is known as a turn-key system, you probably want your application to run automatically, as
soon as the user launches MapInfo Pro.
Using Windows, you can change the command line of a shortcut icon in a similar manner. Right-click
the shortcut icon, choose Properties, and click on the Shortcut tab.
Ordinarily, MapInfo Pro displays the Quick Start dialog box as soon as the user runs it (unless the
user has cleared the Display Quick Start dialog box check box in the Startup Preferences dialog
box). However, if you add the name of a MapBasic application to the command that launches MapInfo
Pro, then the Quick Start dialog box will not appear. Depending on the nature of your application,
this behavior may or may not be desirable. If you want your application to run automatically, without
disabling the Quick Start dialog box, you may need to use a different method for loading your
application. Instead of modifying the MapInfo Pro command line, you may want to create a special
workspace, called the Startup workspace.
"Startup" is a special name for a workspace. If a startup workspace exists on the user's system,
MapInfo Pro loads the workspace automatically. If the startup workspace contains a Run Application
statement, MapInfo Pro runs the specified application.
For example, if you want to run the ScaleBar application, you could create a startup workspace that
looks like this:
!Workspace
!Version 600
!Charset Neutral
Run Application "scalebar.mbx"
The first three lines are required for MapInfo Pro to recognize the file as a workspace. The fourth
line, in this example, launches a MapBasic application by executing a Run Application statement.
The presence of a startup workspace has no effect on the display of the Quick Start dialog box.
MapInfo Pro loads the startup workspace (if there is one), and then displays the Quick Start dialog
box (unless the user has configured the system so that the Quick Start dialog box never displays).
On Windows, the startup workspace has the name STARTUP.WOR and can be located in the
directory in which MapInfo Pro is installed or in the user's private Windows directory (the directory
where WIN.INI is stored). If a STARTUP.WOR exists in both directories, both workspaces will be
executed when the user starts MapInfo Pro.
In a networked environment, if you want the startup workspace to apply to all MapInfo Pro users on
the network, you should place the startup workspace file in the directory where MapInfo Pro is
installed. If you do not want all the network users to run the same startup workspace file, you should
use the alternate location for the startup workspace (for example, on Windows, place the workspace
in the users' private Windows directories).
Since workspaces are simply text files, you can create and edit a startup workspace using any text
editor. Furthermore, since a MapBasic program can perform file input/output, your MapBasic program
can automate the maintenance of the startup workspace.
To see how a MapBasic program can manipulate a workspace file, try this:
1. Choose MapInfo Pro's ToolsRun MapBasic Program command to run the TextBox application.
2. Choose ToolsTextBoxAbout TextBox to display the About TextBox dialog box.
3. Click on the Auto-Load button on the About TextBox dialog box. MapInfo Pro displays a dialog
box that lets you activate automatic the loading of the TextBox application.
4. Choose OK on the Enable Automatic Loading dialog box. MapInfo Pro displays a message
indicating that the TextBox application is now configured to run automatically. Choose OK on the
About TextBox dialog box.
5. Exit MapInfo Pro, then restart it. Note that in this new MapInfo Pro session, the TextBox application
runs automatically; you do not need to choose ToolsRun MapBasic Program application.
When you choose OK in step 4, the TextBox application adds a Run Application statement to
the startup workspace file. If the startup workspace file does not exist, the TextBox application
creates it.
The maintenance of the startup workspace is handled by functions and procedures in the program
module auto_lib.mb. Many of the sample programs that are bundled with MapInfo Pro contain the
same functionality; for example, a MapInfo Pro user can set up the ScaleBar application to run
automatically by choosing the Auto-Load button on the About ScaleBar dialog box.
The auto_lib.mb program module is one of the sample programs included with MapBasic. If you
want your application to include the Auto-Load feature, follow the instructions that appear in the
comments at the top of auto_lib.mb.
If you are making frequent updates to objects in a Map window, using an Animation Layer can make
the window redraw more quickly. Animation Layers are described in Using Animation Layers to
Speed Up Map Redraws.
Whenever your application alters a Map window (or alters an object in the window), MapInfo Pro
redraws the window. If your application makes several alterations, the Map window will redraw
several times, which can annoy your users.
There are two ways to suppress unnecessary window redraws:
• To suppress unnecessary redrawing of one Map window, use the Set Map...Redraw Off statement.
Then issue all statements that affect the Map window. When you are finished updating the map,
issue a Set Map...Redraw On statement to allow the window to redraw. The window will redraw
once, showing all changes you made.
• To suppress unnecessary redrawing of all MapInfo Pro windows, use the Set Event Processing
Off statement. When you are finished updating various windows, issue a Set Event Processing
On statement, and the screen will redraw once.
If your program prints large amounts of text to the Message window, you should periodically clear
the Message window by issuing a Print Chr$(12) statement.
If your application minimizes MapInfo Pro, you should suppress progress bars by using the Set
ProgressBars Off statement.
When a progress bar displays while MapInfo Pro is minimized, the progress bar is frozen for as long
as it is minimized. If you suppress the display of progress bars, the operation can proceed, even if
MapInfo Pro is minimized.
In this section
Ribbon 152
Status Bar 153
Mini Toolbar 153
User Control 154
Context Menu 154
BackStage 155
Ribbon
A Ribbon in MapInfo Pro is a command bar located at the top of the screen that replaces the traditional
menus and toolbars. The Ribbon provides quick access to commonly used tasks through a series
of tabs, which lays out commands in logical groups. The Ribbon also contains drop-down galleries,
split lists, contextual tabs and mini toolbars.
The basic Ribbon components are:
1. Tabs sit across the top of the Ribbon. Each tab represents core tasks you perform in a given
program.
2. Groups are sets of related commands, displayed under a tab on the Ribbon. They pull together
all the commands you are likely to need for a type of task, and they remain on display and readily
available, giving you rich visual aid.
3. Commands are arranged in groups on the Ribbon. A command can be a button, a split list, or a
box where you enter information.
4. Icons - User can add icons in the Ribbon. Users can use same icons for different functions while
adding the components.
The MapInfo Ribbon includes Home, Table, Map, Spatial and Layout tabs that each displays a
different set of commands when selected.
The following sample code demonstrates how to customize a Ribbon in MapInfo Pro. This code
snippet adds a new Ribbon tab, a new Ribbon group under this tab and a new button control in the
group.
Status Bar
A MapInfo Pro status bar is a graphical control element which poses an information area typically
found at the window's bottom. It can be divided into sections to group information. Its job is primarily
to display information about the current state of its window.
The following sample code demonstrates how to customize a status bar in MapInfo Pro. This code
snippet adds a new text block to the status bar.
Mini Toolbar
The Mini Toolbar in MapInfo Pro is a smaller version of the full toolbar found near the top of the
application window. The Mini Toolbar appears when you right-click inside any map window.
The following sample code demonstrates how to customize a Mini Toolbar in MapInfo Pro. This
code snippet adds a new button to the Mini Toolbar.
User Control
In MapInfo Pro, you can create your own custom, reusable controls using .Net and MapBasic code.
These are called user controls.
For a detailed sample refer to the Docking Support sample under
Samples\RIBBONINTERFACE\DotNet Directory on page 294
Context Menu
The context menu (also called contextual, shortcut, and popup or pop-up menu) is a menu in MapInfo
Pro that appears upon a right-click mouse operation. The context menu offers a limited set of choices
that are available in the current state, or context, of MapInfo Pro.
The following sample code demonstrates how to customize a context menu in MapInfo Pro. This
code snippet adds a new context menu item to an existing context menu.
BackStage
The BackStage view is accessible by clicking on the "PRO" tab at the top left corner of the application
window.
In MapInfo Pro it gives you the options to set the preferences for the map window, browser window,
explorer window, Legend window and devices. You can also set the behavior of the MapInfo Pro,
access the licensing options and the Exit command.
The BackStage view is fully extensible by using XML to define the structure, components, and
callback procedures to add or edit the functionality.
The following sample code demonstrates how to customize BackStage in MapInfo Pro. This code
snippet adds a new tab item to the BackStage.
In this section
Opening Tables Through MapBasic 158
Reading Row-And-Column Values From a Table 160
Writing Row-And-Column Values to a Table 166
Creating New Tables 166
Accessing the Cosmetic Layer 171
Accessing Classic Layout Windows 172
Multi-User Editing 173
Files that Make Up a Table 177
Raster Image Tables 177
Working With Metadata 179
Working With Seamless Tables 182
Working With Data in a GeoPackage 184
Accessing DBMS Data 188
Accessing/Updating Remote Databases with Linked Tables 191
Using Data Files in Any Language or Character Set 193
Performance Tips for Table Manipulation 194
Working With Tables
A table must be open before a MapBasic application can access the table. Use the Open Table
statement to open a table. For example, the following statement opens the World table:
Notice that the Browse statement identifies the table by its alias (Earth). The table's alias name
remains in effect for the as long as the table is open. The table has not been permanently renamed.
To permanently rename a table, use the Rename Table statement.
If you include the optional Interactive clause in the Open Table statement, and if the table you specify
cannot be located in the directory that you specify, MapInfo Pro displays a dialog prompting the
user to locate the table. If you omit the Interactive keyword and the table cannot be located, the
Open Table statement generates an error.
When referring to a table in MapBasic, you can either use a string expression or hard-code the table
name into your program. For example, if the tables States, Pipeline, and Parcels are open when
your program is run, you can specify their names explicitly in your program:
You may or may not want to limit your program to work with specific table names. For example, you
might want to prompt the user to choose a table from a list of open tables. Since you wouldn't know
the name of the selected table ahead of time, you couldn't hard-code it into the program.
You can use a string variable to store the name of a table. Assuming that a table called Zoning is
open, you can do the following:
MapInfo Pro assigns a non-default table alias if you attempt to open two tables that have the same
alias. For example, if you open the table "C:\data1994\sites", MapInfo Pro assigns the table its
default alias ("sites"); but if you then attempt to open a different table that has an identical default
alias (for example, "C:\backup\sites"), MapInfo Pro must assign a non-default alias to the second
table, so that the two tables can be differentiated. In this example, MapInfo Pro might assign the
second table an alias such as "sites_2."
If you include the optional Interactive keyword in the Open Table statement, MapInfo Pro will display
a dialog box to let the user specify the table's non-default alias. If you omit the Interactive keyword,
MapInfo Pro assigns the alias table name automatically.
As a result of this behavior, you may not be able to make assumptions about the alias name with
which a table was opened.
However, you can use the TableInfo( ) function to determine the alias under which a table was
opened, as shown in the following example:
Include "mapbasic.def"
Dim s_filename As String
Open Table "states" Interactive
s_filename = TableInfo(0, TAB_INFO_NAME)
Browse * from s_filename
The function call TableInfo(0, TAB_INFO_NAME) returns the alias name of the most recently opened
table.
You can access "non-native" files (dBASE, Lotus, Excel, or text files) as tables, even though they
are not stored in the MapInfo table format. However, before you access a non-native file through
MapBasic, you must register the file. When you register a file, MapInfo Pro builds a table (.tab) file
to accompany the non-native file. You only need to register each file once. After you have registered
a file, you can treat the file as a table.
The following statement registers a dBASE file:
After you have registered a file, the file is considered a table, and you can open it the same way
you would open any MapInfo table, by issuing an Open Table statement.
MapInfo Pro's ability to query a table is not affected by the table's source. For example, you can
issue a SQL Select statement to extract data from a table, regardless of whether the table was
based on a spreadsheet or a database file.
However, MapInfo Pro's ability to modify a table does depend in part on the table's source. If a table
is based on a .dbf file, MapInfo Pro can modify the table; when you update such a table in MapInfo
Pro, you are actually modifying the original .dbf file. However, MapInfo Pro cannot modify tables
that are based on spreadsheets or ASCII (text) files. If you need to modify a table, but MapInfo Pro
cannot modify the table because it is based on a spreadsheet or ASCII file, make a copy of the table
(using the Commit Table...As statement) and modify the copy.
MapBasic programs can access specific column values from specific rows in a table, through the
following procedure:
1. Use a Fetch statement to specify which row in the table you want to query. This action sets which
row is current.
2. Use a table-reference expression (for example, tablename.columnname) to access a specific
column in the current row.
For example, the following program reads the contents of the Country column from the first row of
the World table:
Every open table has a current-row setting; this setting is known as the row cursor (not to be confused
with the mouse cursor, which is the shape that moves across the screen as you move the mouse).
When you issue a Fetch statement, you position the row cursor on a specific row in the table.
Subsequent table references (for example, world.country) extract data from whichever row is specified
by the cursor.
The Fetch statement provides several different ways of positioning the cursor. You can move the
cursor forward or backward one row at a time, position the cursor on a specific row number, or set
the cursor on the first or last row in the table. To determine whether a Fetch statement has attempted
to read past the end of a table, call the EOT( ) function. For more information on the Fetch statement
or the EOT( ) function, see the MapBasic Reference.
The MapBasic language recognizes three different types of expressions that reference specific
column values:
The preceding example used the tablename.columnname syntax (for example, world.country).
Another type of column reference is tablename.col#. In this type of expression, a column is specified
by number, not by name (where col1 represents the first column in the table). Since Country is the
first column in the World table, the assignment statement above could be rewritten as follows:
s_name = world.col1
A third type of column reference takes the form tablename.col(numeric expression). In this type of
reference, the column number is specified as a numeric expression within parentheses. The preceding
assignment statement could be rewritten as follows:
Dim i As Integer
i = 1
s_name = world.col(i)
tablename.columnname world.country
tablename.COLn world.COL1
tablename.COL(n) world.COL(i)
Using this syntax, you can write a MapBasic program that determines, at runtime, which column to
reference.
The tablename in a table reference is optional in statements in which the table name is already part
of the statement. For instance, in the Browse statement you are required to specify column names
and then the table name. Since the table name is explicitly specified in the statement (in the From
clause), the column references at the beginning of the line do not need to include the tablename.
The Select statement also has a From clause, where you name the table(s) to be queried. Column
names that appear within a Select statement do not need the tablename. prefix if the Select statement
queries a single table. However, if a Select statement's From clause lists two or more tables, column
references must include the tablename. prefix. For a general introduction to using the SQL Select
statement, see the MapInfo Pro User Guide, or see Select in the MapBasic Reference.
There are instances in which you must use the COLn or the COL(n) column referencing method.
In the example above, the Select statement identifies two columns; the latter of these columns is
known as a derived column, since its values are derived from an equation (Population/1000000).
The subsequent Browse statement can refer to the derived column only as col2 or as col(2), because
the derived expression Population/1000000 is not a valid column name.
The preceding examples have used explicit, "hard-coded" column names. For example, the following
statement identifies the Country column and the Population column explicitly:
In some cases, column references cannot be specified explicitly, because your application will not
know the name of the column to query until runtime. For example, if your application lets the user
choose a column from a list of column names, your application will not know until runtime what
column the user chose.
MapBasic provides a variable type, Alias, that you can use to store column expressions that will be
evaluated at runtime. As with String variables, you can assign a text string to an Alias variable.
MapBasic interprets the contents of the Alias variable as a column name whenever an Alias variable
appears in a column-related statement.
For example:
MapBasic substitutes the contents of val_col (the alias, Inflat_Rate) into the Select statement in
order to select all the countries having an inflation rate greater than 4 percent.
Note: The maximum length of the alias is 32 characters.
In the example below, the sub-procedure MapIt opens a table, maps it, and selects all records from
a specified column that have a value greater than or equal to a certain value. MapIt uses an Alias
variable to construct column references that will be evaluated at runtime.
Include "mapbasic.def"
Declare Sub Main
Declare Sub MapIt( ByVal filespec As String,
ByVal col_name As String,
ByVal min_value As Float )
Sub Main
Call MapIt("C:\MAPINFOW\MAPS\WORLD.TAB", "population", 15000000)
End Sub
Sub MapIt( ByVal filespec As String,
ByVal col_name As String,
ByVal min_value As Float )
In the MapIt procedure, a Select statement specifies an Alias variable (a_name) instead of an explicit
column name. Note that the col_name parameter is not an Alias parameter; this is because MapBasic
does not allow by-value Alias parameters. To work around this limitation, the column name is passed
as a by-value String parameter, and the contents of the String parameter are copied to a local Alias
variable (a_name).
The example above demonstrates how an Alias variable can contain a string representing a column
name ("population"). An Alias variable also can contain a full column reference in the form
tablename.columnname. The following example demonstrates the appropriate syntax:
The preceding Note statement has the same effect as the following statement:
Note world.COL1
Scope
The syntax tablename.columnname (for example, world.population) is similar to the syntax used to
reference an element of a custom Type. MapBasic tries to interpret any name.name expression as
a reference to an element of a Type variable. If the expression cannot be interpreted as a type
element, MapBasic tries to interpret the expression as a reference to a column in an open table. If
this fails, MapBasic generates a runtime error.
RowID is a a special column name that represents the row numbers of rows in the table. You can
treat RowID as a column, although it isn't actually stored in the table. Think of RowID as a virtual
column, available for use, but not visible. The first row of a table has a RowID value of one, the
second row has a RowID value of two, and so on.
The following example selects the first row from the World table:
The following example uses RowID to Select all of the states with a 1990 population greater than
the median.
Since the TableInfo( ) function returns the total number of rows in the virtual table bypop, the variable
median_row contains the record number of the state with the median population. The last Select
statement selects all the states that come after the median in the ordered table bypop.
If you delete a row from a table, the row is not physically deleted until you perform a pack operation.
(Rows that have been deleted appear grayed in a Browse window.) Any deleted row still has a
RowID value. Thus, deleting a row from a table does not affect the RowID values in the table;
however, if you delete a row, save your changes, and then pack the table, the table's RowID values
do change. To pack a table, choose MapInfo Pro's Pack Table command (on the TABLE tab, in the
Maintenance group, from the Table list), or issue the MapBasic statement Pack Table.
The Obj column is a special column name that refers to a table's graphical objects. Any table that
has graphical objects has an Obj column (although the Obj column does not appear in any Browser
window). If a row does not have an associated graphic object, that row has an empty Obj value.
The following example selects all rows that do not have a graphic object:
This is useful, for instance, in situations where you have geocoded a table and not all of the records
matched, and you want to select all of the records that did not match.
The following example copies a graphical object from a table into an Object variable:
MapInfo Pro users can find addresses in maps by using the Find command (located on the TABLE,
MAP, and SPATIAL tabs). MapBasic programs can perform similar queries by issuing Find statements
and Find Using statements. The Find Using statement specifies the table to be queried; the Find
statement tries to determine the geographic coordinates of a location name (for example, "23 Main
St"). The Find statement also can locate the intersection of two streets, given a string that includes
a double-ampersand (for example, "Pawling Ave && Spring Ave").
After issuing a Find statement, call CommandInfo( ) to determine whether the address was located,
and call CommandInfo( ) again to determine the location's geographic coordinates. Unlike MapInfo
Pro's Find command, the MapBasic Find statement does not automatically re-center a Map window.
If you want to re-center the Map window to show the location, issue a Set Map statement with a
Center clause. Also, the Find statement does not automatically add a symbol to the map to mark
where the address was found. If you want to add a symbol, use the CreatePoint( ) function or the
Create Point statement. For a code example, see Find in the MapBasic Reference or MapBasic
Help.
Geocoding
If you need to perform high-volume geocoding, you may want to purchase MapMarker, a dedicated
geocoding product that is sold separately. MapMarker geocodes faster than MapInfo Pro and allows
single-pass geocoding across the entire United States. MapBasic applications can control MapMarker
through its programming interface. For more information on MapMarker, contact Pitney Bowes Inc.
sales. The phone numbers appear at the beginning of this and other MapInfo product manuals.
MapInfo Pro users can perform sophisticated queries by using MapInfo Pro's SQL Select dialog
box. All of the power of the SQL Select dialog box is available to MapBasic programmers through
MapBasic's Select statement. You can use the Select statement to filter, sort, sub-total, or perform
relational joins on your tables. For information, see Select in the MapBasic Reference.
MapBasic cannot resolve references to tables and columns at compile time. For instance, if your
program references a column called states.pop, the MapBasic compiler cannot verify whether the
states table actually has a column called pop. This means that typographical errors in column
references will not generate errors at compile time. However, if a column reference (such as
states.pop) contains a typographical error, an error will occur when you run the program.
Try the following to minimize the possibility of generating runtime errors. Use the Interactive clause
with the Open Table statement, when appropriate. If the table cannot be located, a dialog box will
prompt the user to locate the table. Do not assume that the table was opened under its default alias.
After you issue an Open Table statement, call TableInfo(0, TAB_INFO_NAME) to determine the
alias assigned to the table. For more information on opening tables, see Open Table in the MapBasic
Reference.
To add new rows to a table, use the Insert statement. To change the values stored in the columns
of existing rows, use the Update statement. Both statements are described in the MapBasic Reference
and MapBasic Help .
If you add new rows to a table or modify the existing rows in a table, you must save your changes
by issuing a Commit statement. Alternately, to discard any unsaved edits, issue a RollBack statement.
Use the Create Table statement to create a new, empty table. Use the Create Index statement to
add indexes to the table, and use Create Map to make the table mappable.
The following example creates a mappable table with a name, address, city, amount, order date,
and customer ID columns. The name field and the customer ID field are indexed.
File "C:\customer\Cust.tab"
Create Map For CUST CoordSys Earth
You can also create a table by saving an existing table (for example, a selection) as a new table
using the Commit statement, or by importing a table using the Import statement.
Every table has a structure. The structure refers to issues such as how many columns are in the
table, and which of the columns are indexed. A MapInfo Pro user can alter a table's structure by
choosing MapInfo Pro's Modify Structure command (on the TABLE tab, in the Maintenance group,
click Table, and then Modify Structure). A MapBasic program can alter a table's structure by issuing
statements such as Alter Table and Create Index.
As a rule, a table's structure cannot be modified while the table has unsaved edits. If you have added
rows to a table, but you have not saved the table, the table has unsaved edits. If a table has unsaved
edits, you must save the edits (by issuing a Commit statement) or discard the edits (by issuing a
Rollback statement) before modifying the table's structure.
The Alter Table statement modifies a table's structure. The following example renames the Address
column to ShipAddress, lengthens the Name column to 25 characters, removes the Amount column,
adds new ZIP Code and Discount columns, and re-orders the columns.
You cannot change the structure of tables that are based on spreadsheets or delimited ASCII files,
and you cannot change the structure of the Selection table.
Use the Add Column statement to add a temporary column to a table. The Add Column statement
lets you create a dynamic column that is computed from values in another table. Add Column can
also perform advanced polygon-overlay operations that perform proportional data aggregation,
based on the way one table's objects overlap another table's objects. For example, suppose you
have one table of town boundaries and another table that represents a region at risk of flooding.
Some towns fall partly or entirely within the flood-risk area, while other towns are outside the risk
area. The Add Column statement can extract demographic information from the town-boundaries
table, then use that information to calculate statistics within the flood-risk area. For information about
the Add Column statement, see the MapBasic Reference Guide.
Table indexes help MapInfo Pro to optimize queries. Some operations, like MapInfo Pro's Find and
Geocode menu items, require an index to the field to be matched against. For instance, before you
can use the Find command to locate a customer in your database by name, you must index the
name column. Select statements execute faster for many queries when you use columns with
indexes. SQL joins create a temporary index if the fields specified in the Where clause are not
indexed. There is no limit to the number of columns that can be indexed. The Obj column is always
indexed.
To create an index in MapBasic, use the Create Index statement. To remove an index, use the Drop
Index statement. MapBasic cannot use indexes created in other packages and MapBasic cannot
index on an expression. An index does not change the order of rows in a Browser window. To
control the order of rows in a Browser, issue a Select statement with an Order By clause, and browse
the selection.
The functions TableInfo( ), ColumnInfo( ) and NumTables( ) let you determine information about the
tables that are currently open.
• TableInfo( ) returns the number of rows in the table, the number of columns, and whether or not
the table is mappable.
• ColumnInfo( ) returns information about a column in a table, such as the column's name, the
column's data type, and whether the column is indexed.
• NumTables( ) returns the number of currently open tables (including temporary tables such as
Query1).
The following program determines which tables are open and copies the table names into an array.
Include "mapbasic.def"
Dim i, table_count As Integer
Dim tablenames() As String
Next
Selection is a special table name that represents the set of rows that are currently selected. A
MapBasic program (or an end-user) can treat the Selection table like any other table.
For example, you can browse the set of currently-selected rows by issuing the following statement:
When you access the Selection table in this way, MapInfo Pro takes a snapshot of the table and
names the snapshot QueryN, where N is a integer value of one (1) or greater. Like Selection, QueryN
is a temporary table. The SelectionInfo( ) function lets you determine the table alias MapInfo Pro
will assign to the current Selection table (i.e., to learn whether the current Selection table will be
known as Query1 or as Query2). SelectionInfo( ) also lets you determine other information about
the Selection, such as the number of selected rows.
obj_copy = Selection.obj
Use the Select statement to change which rows are selected. The Select statement is a very powerful,
versatile statement. You can use the Select statement to filter, sort, or sub-total your data, or to
establish a relational join between two or more tables. All of the power of MapInfo Pro's SQL Select
command (located on the TABLE tab) is available to MapBasic programmers through the Select
statement.
If you issue a Select statement, and if you do not want the results table to have a name such as
Query1, you can assign another name to the results table. The Select statement has an optional
Into clause that lets you specify the name of the results table. For example, the following statement
makes a selection and names the results table "Active."
For an introduction to the capabilities of SQL Select queries, see the MapInfo Pro User Guide. For
detailed information about the Select statement, see the MapBasic Reference Guide.
You can use the Update statement to modify the Selection table. If you modify the Selection table,
the changes that you make are applied to the base table on which the selection is based.
For example, the following Select statement selects some of the rows from the employees table.
After the Select statement, an Update statement modifies the data values of the selected rows.
Update Selection
Set salary = salary * 1.15
The Update statement will alter the values of rows in the employees table, because the selection
is based on the employees table.
The Selection process is part of the user interface. Some applications are arranged so that the user
selects one or more rows, then chooses an appropriate menu item. When the user makes a selection,
the user is specifying an object (a noun). When the user chooses a menu item, the user is specifying
an action (a verb) to apply to that object.
The sample program, TextBox, is based on this noun/verb model. The user selects one or more
text objects, then chooses the Create Text Boxes command. The TextBox application then queries
the Selection table, and draws boxes around the text objects that the user selected.
To query the current selection, use the SelectionInfo( ) function. By calling SelectionInfo( ), you can
determine how many rows are selected (if any) at the present time. If rows are currently selected,
you can call SelectionInfo( ) to determine the name of the table from which rows were selected. You
then can call TableInfo( ) to query additional information about the table.
If your application includes a sub-procedure called SelChangedHandler, MapInfo Pro calls that
procedure every time the selection changes. For example, you may want some of your application's
custom menu items to only be enabled when rows are selected. To perform that type of
selection-specific menu maintenance, create a SelChangedHandler procedure. Within the procedure,
call SelectionInfo(SEL_INFO_NROWS) to determine if any rows are selected. Based on whether
any rows are selected, issue an Alter Menu Item statement that enables or disables appropriate
menu items. For more information on menu maintenance, see Creating the User Interface.
Each Map window has one Cosmetic layer, a special-purpose layer which is the top layer in the
map. If the user performs a Find operation, MapInfo Pro places a symbol at the "found" location.
Such symbols are stored in the Cosmetic layer. in See Graphical Objects for more information on
labeling.
To control the Cosmetic layer through MapBasic, issue table-manipulation statements (such as
Select, Insert, Update, or Delete) and specify a table name such as CosmeticN (where N is an
Integer, one or larger). For example, the table name Cosmetic1 corresponds to the Cosmetic layer
of the first Map window on the screen. The following statement selects all objects in that Map
window's Cosmetic layer:
To determine a Cosmetic layer's exact table name, call WindowInfo( ) with the code
WIN_INFO_TABLE. For example, the following statement deletes all objects from the Cosmetic
layer of the active Map window (assuming that the active window is a Map window):
This section applies to the classic Layout window. For a description of what classic Layout windows
are, see About Layout Windows. For a description of how to work with the current Layout window,
see Working with Layout Windows.
MapBasic's object-manipulation statements can be applied to the objects on a classic Layout
window. To manipulate a classic Layout window, issue statements that use the table name LayoutN
(where N is an integer, one or larger).
For example, the table name Layout1 corresponds to the first Layout window that you open. The
following statement selects all objects from that Layout window:
You can determine a Layout window's exact table name by calling the WindowInfo( ) function with
the WIN_INFO_TABLE code.
Note: Objects stored on a Layout window use a special coordinate system, which uses "paper"
units (units measured from the upper-left corner of the page layout). Any MapBasic program
that creates or queries object coordinates from Layout objects must first issue a Set CoordSys
statement that specifies the Layout coordinate system.
For example, the TextBox sample program draws boxes (rectangle objects) around any
currently-selected text objects, regardless of whether the selected text objects are on a Map window
or a Layout window. If the selected objects are Layout objects, TextBox issues a Set CoordSys
Layout statement.
When you are using MapInfo Pro interactively, MapInfo Pro's Statistics window gives you an easy
way of determining the table name that corresponds to a Layout window or to a Map window's
Cosmetic layer. If you select an object in a Map's Cosmetic layer, and then show the Statistics
window (for example, on the HOME tab, in the Tools Windows group, clicking Statistics), the
Statistics window displays a message such as, "Table Cosmetic1 has 1 record selected." Similarly,
if you select an object from a Layout window, the Statistics window displays, "Table Layout1 has
1 record selected."
Multi-User Editing
If your MapBasic program works with tables in a multiple-user environment, you may encounter
file-sharing conflicts. Sharing conflicts occur because MapInfo Pro only allows one user to modify
a table at a time.
This section spells out the rules that govern MapInfo Pro's multi-user editing behavior. Read this
section if you want to write a MapBasic program that allows multiple users to modify the same table
at the same time.
Rule 1
A table may only be edited by one user at a time.
Imagine two hypothetical users: User A and User B. Both users are attempting to use the same
table, which is stored on a network.
User A begins editing the table. (For example, User A adds new rows to the table.) Moments later,
User B attempts to edit the same table. MapInfo Pro prevents User B from editing the table, and
displays the message, "Cannot perform edit. Someone else is currently editing this table." If User
B is trying to edit the table through a MapBasic application, a runtime error occurs in the application.
As long as User A continues to edit the table, MapInfo Pro prevents User B from editing the same
table. This condition remains until User A performs Save, Revert (discarding the edits), or Close
Table.
Note: User B is allowed to read from the table that User A is editing. For example, User B can
display the table in a Map window. However, User B will not "see" the edits made by User
A until User A performs a Save.
Rule 2
Users cannot read from a table while it is being saved.
After editing the table, User A chooses the Save Table command (on the TABLE tab, in the Content
group, from the Save list). Then, while the save operation is still underway, User B attempts to read
data from the table. As long as the Save is underway, MapInfo Pro prevents User B from accessing
the table at all. MapInfo Pro displays a dialog box (on User B's computer) with the message, "Cannot
access file <tablename>.DAT for read." The dialog box contains Retry and Cancel buttons, with the
following meaning:
Retry
If User B clicks Retry, MapInfo Pro repeats the attempt to read from the file. The Retry attempt will
fail if the Save is still underway. The user can click the Retry button repeatedly. After the Save
operation finishes, clicking the Retry button succeeds.
Cancel
If User B clicks Cancel, MapInfo Pro cancels the operation, and the Retry/Cancel dialog box
disappears.
Note: If User B was loading a workspace when the sharing error occurred, clicking Cancel may
halt the loading of the rest of the workspace. For example, a workspace contains Open Table
statements. If the Open Table statement was the statement that caused the sharing conflict,
and if the user cancels the Retry/Cancel dialog box, MapInfo Pro will not open the table.
Subsequent statements in the workspace may fail because the table was not opened.
Rule 3
A Save cannot be started while the table is being read by other users.
If other users are reading the table at the exact moment that User A chooses the Save Table
command, the Save Table command cannot proceed. MapInfo Pro displays the message, "Cannot
open file <tablename>.DAT for writing." The dialog box contains Retry and Cancel buttons, with the
following meaning:
Retry
If User A clicks Retry, MapInfo Pro repeats the attempt to save the table. The user can click the
Retry button repeatedly. Clicking the Retry button will only succeed if the other users have finished
reading from the table.
Cancel
If User A clicks Cancel, MapInfo Pro cancels the Save operation, and the Retry/Cancel dialog box
disappears. At this point, the table has not been saved, and the edits will not be saved unless User
A chooses the Save Table command again.
The Set File Timeout statement sets a time limit; in this example, the time limit is 100 seconds. In
other words, MapInfo Pro will automatically retry any table operations that produce a sharing conflict,
and MapInfo Pro will continue to retry the operation for up to 100 seconds. Note that MapInfo Pro
retries the table operations instead of displaying a Retry/Cancel dialog box. If the sharing conflict
still occurs after 100 seconds of retries, the automatic retry stops, and MapInfo Pro displays the
Retry/Cancel dialog box.
Several MapBasic statements alter the contents of a table. For example, the Insert statement adds
new rows to a table. If your program attempts to alter the contents of a table, and a sharing conflict
occurs, a MapBasic runtime error occurs. To trap this error, use the OnError statement. For example,
if you have a procedure that inserts new rows into a table (as in the example below), you should
create an error-handling routine, and place an OnError statement at the top of the procedure to
enable error trapping. (Error-handling is discussed in more detail in Debugging and Trapping
Runtime Errors.)
CAUTION: Use the Set File Timeout statement and the OnError statement exclusively. In places
where an error handler is enabled, the file-timeout value should be zero. In places
where the file-timeout value is non-zero, error handling should be disabled. The following
example demonstrates this logic.
'enable error-trapping
OnError Goto trap_the_error
exit_ramp:
When you open a table in a multiple-user environment, there is a chance that MapInfo Pro will open
the table with read-only access, even if the files that comprise the table are not read-only. If a
MapBasic program issues an Open Table statement at the exact moment that the table is being
accessed by another user, MapInfo Pro may open the table with a read-only status. The read-only
status prevents successive statements from modifying the table.
The following example shows how to prevent MapInfo Pro from opening shared tables with a
read-only status. Instead of simply issuing an Open Table statement, issue the statement within a
loop that iterates until the file is opened read/write.
Retry_point:
A table consists of several files: one file contains information about the table structure (column
names, etc.); another file contains the table's row-and-column values; another file contains the
table's graphic objects (if any); and the remaining files contain indexes. The file containing the
row-and-column data can be in any format supported by MapInfo Pro: .dbf, Lotus .wks or .wk1
format, delimited ASCII file format, or Excel (.XLS or .XLSX) file format.
• filename.tab: Describes the structure of your table.
• filename.dat or filename.dbf or filename.wks: Contains tabular (row-and-column) data.
• filename.map: Contains the table's graphic objects.
• filename.id: Contains a geographic index.
• filename.ind: Contains indexes for columns in the table.
Because each table consists of several component files, you must be very careful when renaming
a table. To rename a table, choose MapInfo Pro's Rename Table command (located on the TABLE
tab from the Table list), or issue the MapBasic Rename Table statement.
Raster image tables (tables that display only raster image data, not vector data) do not have all of
the component files listed above, because raster image tables do not contain tabular data. Every
raster image table consists of at least two files: a .tab file (which stores the image's control points)
and the file or files that store the raster image. For example, if a raster image table is based on the
file photo.tif, the table might consist of two files: photo.tif and photo.tab.
In many ways, a raster image table is just like any other table. To open a raster image table, use
an Open Table statement. To display a raster image table in a Map window, issue a Map statement.
To add a raster image table to an existing map, issue an Add Map Layer statement. However, you
cannot perform a Select operation on a raster image table. To determine if a table is a raster table,
call TableInfo( ) with the TAB_INFO_TYPE code. If the table is a raster table, TableInfo( ) returns
the code TAB_TYPE_IMAGE. As a rule, MapInfo Pro does not alter the original image file on which
a raster table is based. Therefore:
• If you use the Drop Table statement to delete a raster table, MapInfo Pro deletes the table file,
but does not delete the image file on which the table is based.
• If you use the Rename Table statement on a raster table, MapInfo Pro renames the table file, but
does not rename the image file on which the table is based.
• If you use the Commit statement to copy a raster table, MapInfo Pro copies the table file but does
not copy the image file on which the table is based.
A raster image table's .tab file is created when a user completes MapInfo Pro's Image Registration
dialog box. If you need to create a .tab file for a raster image through a MapBasic program, create
the file using standard file input/output statements: create the file using the Open File statement,
and write text to the file using the Print # statement; see example below.
The following program creates a table file to accompany a raster image file. This program assigns
"dummy" coordinates, not true geographic coordinates. Therefore, the final table will not be suitable
for overlaying vector map layers. However, if the raster image is a non-map image (as a company
logo), the use of non-geographic coordinates is not a problem.
Include "mapbasic.def"
Declare Sub Main
Declare Function register_nonmap_image(ByVal filename As String,
ByVal tablename As String) As Logical
Sub Main
Dim fname, tname As String
fname = "c:\data\raster\photo.gif" 'name of an existing image
tname = PathToDirectory$(fname)
+ PathToTableName$(fname) + ".tab" 'name of table to create
If FileExists(tname) Then
Note "The image file is already registered; stopping."
Else
If register_nonmap_image(fname, tname) Then
Note "Table file created for the image file: "
+ fname + "."
Else
Note "Could not create table file."
End If
End If
End Sub
Function register_nonmap_image( ByVal filename As String,
ByVal tablename As String) As Logical
register_nonmap_image = FALSE
OnError GoTo handler
Open File tablename For Output As #1 FileType "MIta"
Print #1, "!Table"
Print #1, "!Version 300"
Print #1, "!charset Neutral"
Print #1
Print #1, "Definition Table"
Print #1, " File """ + filename + """"
Print #1, " Type ""RASTER"" "
Print #1, " (1,1) (1,1) Label ""Pt 1"", "
Print #1, " (5,1) (5,1) Label ""Pt 2"", "
Print #1, " (5,5) (5,5) Label ""Pt 3"" "
Print #1, " CoordSys NonEarth Units ""mm"" "
Print #1, " Units ""mm"" "
Print #1, " RasterStyle 1 45" ' Brightness; default is 50
Print #1, " RasterStyle 2 60" ' Contrast; default is 50
Close File #1
register_nonmap_image = TRUE ' set function return value
last_exit:
Exit Function
handler:
Close File #1
Resume last_exit
End Function
What is Metadata?
Metadata is data that is stored in a table's .TAB file, instead of being stored as rows and columns.
For example, if you want to record summary information about who edited a table or when they
performed the edits, you could store that information as metadata.
Metadata is not displayed in the standard MapInfo Pro user interface. Users cannot see a table's
metadata (unless they display the .TAB file in a text editor or run the TableMgr sample MBX).
However, MapBasic applications can read and write metadata values.
Each table can have zero or more metadata keys. Each key represents an information category,
such as an author's name, a copyright notice, etc. For example, a key named "\Copyright" might
have the value "Copyright 2005 Acme Corp."
Each metadata key has a name, which always starts with the "\" (backslash) character. The key
name never ends with a backslash character. Key names are not case-sensitive.
The key's value is always a string, up to 239 characters long.
The following table provides samples of metadata keys and key values.
"\Info\Date\Start" "12/14/01"
"\Info\Date\End" "12/31/01"
"\IsReadOnly" "FALSE"
The GetMetadata$( ) function allows you to query a table's metadata, but only if you already know
the exact name of the metadata key. If you know that a table has a key called "\Copyright" then the
following function call returns the value of that key:
The Metadata statement allows you to create, modify, or query a table's metadata, even if you do
not know the names of the keys. The following examples demonstrate the various actions that you
can perform using the Metadata statement.
Note: In the following examples, table_name represents a string variable that contains the name
of an open table.
The following example stores a key value in a table. If the key already exists, this action changes
the key's value; if the key does not already exist, this action adds the key to the table's metadata.
The following statement deletes the "\Info\Author" key from the table.
The following statement deletes an entire hierarchy of keys at one time. All keys whose names start
with "\Info\" will be deleted.
When you use the Metadata statement to write or delete metadata, the changes take effect
immediately. You do not need to perform a Save operation.
You also can use the Metadata statement to read the metadata from a table, even if you do not
know the names of the keys. To read a table's metadata:
1. Issue a Metadata Table...SetTraverse statement to initialize a traversal.
2. Issue a Metadata Traverse...Next statement to retrieve a key. This statement retrieves the key's
name into one string variable, and retrieves the key's value into another string variable.
3. Continue to issue Metadata Traverse...Next statements to retrieve additional keys. Typically, this
statement is issued from within a loop. Once you have exhausted the keys, Metadata
Traverse...Next returns an empty string as the key name.
4. Terminate the traversal by issuing a Metadata Traverse...Destroy statement. This action releases
the memory used by the traversal.
The following example shows how to traverse a table's metadata.
End Sub
For a complete listing of the syntax of the Metadata statement, see the MapBasic Reference or
MapBasic Help.
Seamless tables allow you to group multiple tables together and treat them as a single table. Once
you have grouped your tables into a seamless table, you can add the entire group of tables to a
very easily, simply by adding the seamless table (in the Layer Control window). For an introduction
to working with seamless tables, see the MapInfo Pro User Guide.
MapInfo Pro includes a MapBasic program, Seamless Manager (seammgr.mbx), that allows you to
create and manipulate seamless tables. To see how a seamless table is composed, you need to
turn the table's "seamless behavior" off, as follows:
1. Open a seamless table, such as USRaster.
2. Run the Seamless Manager application.
3. Choose Seamless Manager and then select Turn Seamless Off to turn off the seamless attribute
for the DCMetroA table. (The Seamless Manager is on the HOME tab. Click Tools and select it
from the Registered tab.)
4. Open a Browser window: on the HOME tab, in the Document Windows group, select Browser.
Like ordinary tables, a seamless table has rows and columns. Each row corresponds to a base table
that is included in the seamless table.
Figure 5: ...appear in the list if the user browses the seamless table.
The first column in a seamless table contains table names. The second column contains descriptions,
which appear in the user interface. The table names in the first column may contain directory paths.
You can omit the directory paths if the base tables are in the same directory as the seamless table,
or if the base tables can be located by the Search Directories path (which is specified as a Preference,
in the Directory Preferences dialog box).
Every row in a seamless table has a map object attached to it, just as objects are attached to rows
in conventional tables. However, the objects in a seamless table are not intended for display. Each
row in a seamless table has a rectangle object, which defines the minimum bounding rectangle
(MBR) for the table named in the first column. When a user displays a seamless table in a Map
window, MapInfo Pro compares the Map window's current extents against the MBRs stored in the
table. MapInfo Pro only opens the base tables when necessary (i.e., when the area currently visible
in the Map window intersects the table's MBR).
Use the Set Table statement to turn a seamless table into a conventional table. For example, if you
want to edit the descriptions in a seamless table, you could issue the following statement:
All of the base tables in a seamless table must have the same structure (i.e., the same number of
columns, the same column names, etc.).
Note that some MapInfo Pro operations cannot be used on seamless tables. For example:
• You cannot simultaneously select objects from more than one base table in a seamless table.
• The MapBasic Find statement cannot search an entire seamless table; the Find statement can
only work with one base table at a time.
• You cannot make a seamless table editable in a Map window.
• You cannot create a thematic map for a seamless table.
MapInfo Pro supports opening and working with data stored in a GeoPackage (GPKG) format file.
Support for GeoPackage tables is similar to that for SQLite tables.
A GeoPackage can have multiple number of tables inside it. If you are accessing the data using
MapBasic, you must register the table first by using the Register Table statement. When you register
a file, MapInfo Pro builds a table (.tab) file and any update made to the table is saved over this new
TAB file.
The following example registers a table named "asia_regions" from a GeoPackage file named
"asia.gpkg":
About Indexes
When a GeoPackage table is registered, MapInfo Pro does not write any index or field definition to
the associated TAB file. MapInfo Pro does not create indexes on GeoPackage tables by default,
because these indexes can get out of synch with the index in the GeoPackage file.
To create indexes for fields within the GeoPackage table, use the Create Index statement. After
creating indexes, the field definitions and indexes are written to the TAB file. You can remove the
index from the GeoPackage table by using the Drop Index statement.
MapInfo Pro supports deleting only one open GeoPackage table at a time from the same GeoPackage
(GPKG) file. To delete multiple tables from a single GPKG file, open and delete each table in turn.
If you delete multiple open tables, then each of the tables is unavailable for use by MapInfo Pro,
but the table data remains in the GPKG file.
You can delete an open GeoPackage table by issuing the Drop Table statement from the MapBasic
window in MapInfo Pro or by using the Delete Table command on the TABLE tab in MapInfo Pro.
Deleting a GeoPackage table deletes the TAB file and all associated component files. If a
GeoPackage has only one table, using this command or MapBasic statement will delete only the
table and associate files, not the GeoPackage file.
MapInfo tables always assume rows one to n are sequential. However, GeoPackage tables do not
always have sequential data; there may be empty rows, rows that start after one (1), and gaps in
row IDs. This must be taken into consideration when using MapBasic operations to fetch data from
GeoPackage tables.
For GeoPackage tables, the MapBasic RowId value is a table's primary key value and not the row
enumeration value. A Fetch Rec 3 command returns the row with primary_key value of three (3) if
it exists. It does not return the third record in the table. Do not fetch using a specific row ID. Instead,
use Fetch First, Fetch Next, Fetch Last instead of Fetch Rec #.
MapInfo Pro supports deleting only one open Geopackage table at a time from the same GeoPackage
(GPKG) file. To delete multiple tables from a single GPKG file, open and delete each table in turn.
If you delete multiple open tables, then each of the tables is unavailable for use by MapInfo Pro,
but the table data remains in the GPKG file.
You can delete an open GeoPackage table by issuing the Drop Table statement from the MapBasic
window in MapInfo Pro or by using the Delete Table command on the TABLE tab in MapInfo Pro.
Deleting a GeoPackage table deletes the TAB file and all associated component files. If a
GeoPackage has only one table, using this command or MapBasic statement will delete only the
table and associate files, not the GeoPackage file.
Some MapBasic tools (such as Coordinate Extractor) create new columns in open MapInfo Native
(TAB) tables. You cannot alter the table structure of open GeoPackage tables in MapInfo Pro, so
you cannot create new columns on these tables. Make sure any columns you need to update are
in the table before working with it in MapInfo Pro.
There are tools available to alter the structures of GeoPackage tables outside of MapInfo Pro, such
as www.sqliteexpert.com). If you alter the structure of a GeoPackage table, then you must reopen
the GeoPackage file (*.gpkg) in MapInfo Pro to re-generate a new MapInfo table that is aware of
the new table structure.
Warning: Use a tool to alter a GeoPackage table at your own risk.
As per the standard global GeoPackage specification, the name of a GeoPackage table created by
MapInfo Pro is in lower case. For reference, see www.geopackage.org/spec/#_base. GeoPackage
files created by other software may not always follow this specification. If you are using the Register
Table statement in MapBasic to open a GeoPackage table created by another product, you will
need to pass the table name in the correct case. Otherwise, MapInfo Pro returns an error.
MapInfo Pro supports only reading of Z and M values from GeoPackage files. If a GeoPackage
table is opened that supports Z or M values, MapInfo Pro, will set it to "read-only" in order to protect
Z or M values within the data from being overwritten by MapInfo Pro. GeoPackage tables also
support use of Multipoint and Collection objects which may have Z or M values.
Support for Z and M values within a GeoPackage table is provided through following existing
MapBasic functions:
Note: These functions also work with ESRI *.SHP format files opened in MapInfo Pro that contain
Z and M values.
The preceding discussions showed you how to work with local MapInfo tables, tables on your hard
disk, or perhaps on a network file-server. This section describes how MapBasic can access DBMS
tables, such as Oracle or SQL Server databases.
MapBasic's remote-data statements and functions all begin with the keyword Server, with the
exception of the Unlink statement. For details on the syntax, see the MapBasic Reference or
MapBasic Help.
MapInfo Pro allows a MapBasic application to connect to multiple databases at one time and issue
multiple intermixed SQL statements. This is done through connection handles and statement handles.
Connection handles (or numbers) identify information about a particular connection. MapBasic
defines connection handles as variables of type integer (i.e., a connection number). An application
receives a connection handle upon connecting to a data source. The connection handle is used to
associate subsequent statements with a particular connection.
Statement handles (or numbers) identify information about an SQL statement. MapBasic defines
statement handles as variables of type integer (i.e., a statement number). An application must
receive a statement handle upon calling the Server_Execute( ) function to submit an SQL request.
The statement handle is used to associate subsequent SQL requests, like the Fetch and Close
operations, to a particular Select statement.
Before a MapBasic application can begin executing SQL statements to remote databases, it must
request a connection using the Server_Connect function. Once a successful connection is established,
the function returns a connection handle (hdbc) for use with subsequent SQL DataLink calls.
The supported servers are SQL Server, Oracle, Postgres with PostGIS, SQLite, and Access. This
next example connects to an Oracle database:
When the driver performs a commit or rollback, it resets all statement requests associated with that
connection. The Driver Manager handles the work associated with switching connections while
transactions are in progress on the current connection.
Use the following statement to disconnect:
This statement closes the connection and frees all resources associated with it.
The following chart describes the sequence in which SQL MapBasic Server statements can be
issued. There are some statements that require no connection information (for example,
Server_NumDrivers( )), some that require only a connection handle (for example, Server Commit),
and some that require a statement handle (for example, Server Fetch).
You can download an entire table, some rows and columns, or a result set from an ODBC data
source using the Into feature of the MapBasic statement Server Fetch. However, any updates applied
to the downloaded table are not applied back to the server database table. Updating remote
databases is accomplished by the Save File statement.
If you try to save a map with unsupported spatial geometry types in PostGIS, these are the results:
• Spatial Geometry Types with All Unsupported Objects: If you have created a map that might
contain all of the unsupported objects and you are trying to save to PostGIS, this message displays:
Click Yes to convert the unsupported objects to regions or polylines; you would select No to decline
to convert the unsupported objects. If you decline, you cannot save the map you have created to
the PostGIS database.
• Spatial Geometry types with Region Objects Only: If you have created a map that contains region
objects only and you are trying to save to PostGIS, this message displays:
Click Yes to convert the unsupported objects to regions; you would select No to decline to convert
the unsupported objects. If you decline, you cannot save the map you have created to the PostGIS
database.
• For Spatial Geometry types with Line Objects Only: If you have created a map that contains line
objects only and you are trying to save to PostGIS, this message displays:
Click Yes to convert the unsupported objects to polylines; you would select No to decline to convert
the unsupported objects. If you decline, you cannot save the map you have created to the SQL
Server Spatial database.
• For Spatial Geometry of type Rectangle: If you have created a map that contains rectangle objects
and you are trying to save to PostGIS, this message displays:
Click OK. You cannot save the map you have created to the PostGIS database.
A linked table is a special kind of MapInfo table that retains links to a remote database. Edits can
be made over multiple MapInfo Pro sessions. Because the linked table updates are occurring outside
of an RDBMS transaction, other RDBMS users can update the same rows in the same tables. An
optimistic concurrency control mechanism is used to prevent data corruption. Concurrency control
is accomplished with the Automatic/Interactive clause of the Commit Table statement. When the
data is saved, a connection with the remote database is re-established, editing conflicts are resolved,
and the changed data is written to the RDBMS. A linked table is created with the MapBasic statement
Server Link Table.
Linked tables contain information to re-establish connections and identify the remote data to be
updated. This information is stored as metadata in the tab file.
An unedited linked table can be refreshed with current data from the remote database without
respecifying the connection data, query, and table. A linked table is refreshed with the MapBasic
statement Server Refresh.
A linked table can be unlinked with the MapBasic statement Unlink. Unlinking a table removes the
link to the remote database. The end product is a normal MapInfo base table.
Using MapInfo Pro's spatial indexing, users will be able to store and retrieve points in any database;
or spatial objects in supported spatial objects. See Making a Remote Table Mappable.
The following example opens a linked table from a SQLite (FDO) database. This example:
1. Connects to a SQLite database named MIPRO71252.sqlite.
2. Opens a table named EN_STATE, so that the open table is linked to the database, in NativeX
(MapInfo Extended) format, and uses the UTF-8 character set. In this example, username is the
Windows user account.
3. Opens a Map window to display the EN_STATE data.
dim i as integer
i = Server_Connect("FDO",
"File=C:\Data\MIPRO71252.sqlite;PROVIDER=OSGeo.SQLite;SCROLL=NO")
This example opens a linked table from a SQLite (FDO) database, so that it is in Native (MapInfo)
format. Omitting the Charset clause causes the table to use the default system character set from
the Windows operating system. It then opens a Browser window to display the EN_STATE data.
Note: MapInfo Pro installs a Feature Data Object (FDO) to access a SQLite database with. You
do not need to obtain the FDO.
You can access data live from remote databases with the Register Table statement. When you
specify the Type as ODBC, the Register Table statement tells MapInfo Pro to examine the ODBC
table and build a corresponding table file (filename.TAB).
2. Registers a table named EN_STATE, indicates that it uses the UTF-8 character set, and opens
it in NativeX (MapInfo Extended) format. In this example, username is the Windows user account.
3. Opens the EN_STATE table in interactive mode, so that changes are made live (directly to the
table in the database).
4. Opens a Map window to display the EN_STATE data.
dim i as integer
i = Server_Connect("FDO",
"File=C:\Data\MIPRO71252.sqlite;PROVIDER=OSGeo.SQLite;SCROLL=NO")
Register Table "EN_STATE" Type ODBC Charset "UTF-8" Table "select * from
EN_STATE" Connection Handle i ToolKit "FDO" Cache ON TYPE NATIVEX Into
"C:\Users\username\Documents\EN_STATE.tab"
Omitting the Charset and TYPE clauses when registering a table causes it to open in Native (MapInfo)
format using the default system character set from the Windows operating system.
Replacing the Handle clause with the path to the SQLite database opens the table without prior
connection to the database (so you do not need the dim . . . Server_Connect statement).
Register Table "EN_STATE" Type ODBC Charset "UTF-8" Table "select * from
""EN_STATE""" Connection
"File=C:\temp2\MIPRO71252.sqlite;PROVIDER=OSGeo.SQLite;SCROLL=NO" ToolKit
"FDO" Cache ON TYPE NATIVEX Into
"C:\Users\username\Documents\EN_STATE.tab"
Note: MapInfo Pro installs a Feature Data Object (FDO) to access a SQLite database with. You
do not need to obtain the FDO.
You can work with characters from any language in your data files, so that multi-language tables
display properly in maps, browsers, the Info tool, and other locations. MapInfo Pro can open tables,
files, or workspaces with Unicode characters in the file name or path name regardless of the locale
of MapInfo Pro or which localized version of MapInfo Pro you are running.
MapBasic supports writing, compiling, and linking of applications that use strings other than the
system character set. You can create applications that use localized string variable and method
names and contents in multiple languages.
Source code, project files, and include files can be encoded in UTF-8 to support multiple languages.
All modules (MBO) must also be compiled in UTF-8 character set (charset) to be linked. A new
–utf8 token compiles and links via the command-line.
If using localized variable or method names in an application, the length of these names is measured
in bytes, so it takes two bytes for each character when using localized names. MapBasic limits
variable and method names to 32 characters (bytes), so localized variable and method names using
double bytes are truncated to 16 characters.
Set the default view for a remote database table, so that only the data you are interested in opens
in a map or browser. This improves data access speed for large tables.
The default view is stored in the MAPINFO_MAPCATALOG in four columns that hold the bounds:
VIEW_X_LL, VIEW_Y_LL, VIEW_X_UR AND VIEW_Y_UR. The MapCatalog is a registry table that
contains metadata about remote tables. If there is no entry in the MapCatalog for the table, MapBasic
retrieves the entire bounds.
To set the new default view, open the remote table (the entire bounds will display), adjust the view
as desired and run the MapBasic tool Window Manager to call Set Default View. The new bounds
will be updated in the MapCatalog and used the next time the table is opened.
When using the Save Copy As command to upload a table to a remote database data source, the
default view for the original table is also used by the newly created table.
If the remote table has no default view entry in the MAPINFO_MAPCATALOG, the remote database
user (as identified in the database connection) must have ALTER permission to the MapCatalog in
order to change the default view from the original setting. Without this permission, a warning message
displays and the default view change fails.
Ordinarily, when a user edits a MapInfo table, MapInfo Pro stores the edits in a temporary file known
as a transaction file. As the user performs more and more edits, the transaction file grows larger. A
large transaction file can slow down some operations, therefore, if your MapBasic program performs
table editing, you may want to take one of the following steps to prevent the transaction file from
growing too large:
• Save your edits (i.e., perform a Commit statement) regularly. For example, you might set up your
program so that it performs a commit after every 100 edits. Saving your edits empties out the
transaction file.
• Use a Set Table...FastEdit statement to turn on FastEdit mode. In FastEdit mode, edits are saved
immediately to a table, instead of being stored in a transaction file. For details, see the MapBasic
Reference or MapBasic Help. See also Set Table...Undo Off.
Some queries are faster if you index one or more columns in your table. For example, Select
statements can be faster if you index the columns used in Where, Order By, or Group By clauses.
However, you may not want to index every single column in your table. Indexing every column can
slow down some operations because MapInfo Pro must spend more time maintaining indices.
If your application performs intensive table manipulation that does not involve queries, you may be
able to improve speed by doing the following:
1. Delete the indices from your table (using the Drop Index statement).
2. Perform table edits as necessary.
3. Save your edits.
4. Use the Create Index statement to re-create the indices.
This strategy can speed up heavy-duty table manipulation, because MapInfo Pro no longer needs
to maintain indices during the editing operations.
Using Sub-Selects
The Select statement can include a Where clause that performs a sub-select, as described in the
MapBasic Reference. However, you may find it faster to perform two non-nested Select statements,
instead of one nested Select...Where (Select ...) statement.
If you perform a sub-select of this type:
then MapInfo Pro does optimize the query performance, but only if column x is indexed.
Some types of Select queries are optimized for fast performance. See Select in the MapBasic
Reference or MapBasic Help.
MapBasic allows you to update map objects one at a time, by performing an Alter Object statement
and then an Update statement on individual rows, often within a loop. However, this type of table
manipulation can be very slow, because you are issuing several statements for every row that you
modify.
In some cases, you can obtain much faster performance by issuing a single Update statement that
affects an entire table, rather than updating one row at a time. For an example, see the topic "Updating
Symbols Quickly" in the MapBasic Help.
In this section
Overview of File Input/Output 198
Sequential File I/O 200
Platform-Specific & International Character Sets 202
File Input/Output
File input/output (usually abbreviated file i/o) is a process of reading information from files (input)
and/or writing information to files (output). The MapBasic language provides a set of standard BASIC
input/output statements and functions to let you read and/or write text or binary files. Furthermore,
because MapInfo Pro and MapBasic are designed to accommodate different hardware platforms,
MapBasic's file i/o statements provide mechanisms that let you ensure seamless sharing of data.
There are three different types of file access: sequential, random, and binary. Which mode you
should use depends on the nature of the data in the file(s) you need to access. The three modes
are summarized below:
• Use sequential file i/o to read text from variable-length text files. For example, if one line of a text
file is fifty characters long, and subsequent lines in the text file are longer or shorter than fifty
characters, then the file is variable-length. Use sequential file i/o for accessing such files.
• Use random file i/o to read from text files that are fixed-length. If every line in a file is exactly 80
characters long, the file is fixed-length, and you can access the file using random file i/o.
• Use binary file i/o to access binary (non-text) file data. If you use binary file i/o to store data in a
file, MapInfo Pro stores numeric data in an efficient storage format. Binary files containing numerical
data cannot be viewed or edited in a text editor, however, they provide a more efficient format for
storing numerical data than text files.
Regardless of which type of file i/o you will perform, the first step to performing file i/o is to open the
file you want to use. In MapBasic, you open a file using the Open File statement. This statement
has several optional clauses; which clauses you need to use depends on your specific situation.
The following statement opens a text file for sequential input:
When you open a file, you specify a file number; in the example above, the number is one (1). Later
statements in your program refer to the same number that you specified in the Open File statement.
For example, to read text from the file into a String variable, you could issue a Line Input statement,
and the Line Input statement would refer to the same file number (#1) as the Open File statement:
If you need to have two or more files open at the same time, make sure that each file is opened
under a different number.
In some situations, you may need to create a new file in which to store your data. To create a new
file, issue an Open File statement that includes the For Output clause:
Alternately, you can specify For Append in the Open File statement. With Append mode, MapBasic
creates the file if it does not already exist, or MapBasic lets you append data to the file if it already
does exist. When you are finished reading from or writing to a file, issue a Close File statement. For
example:
Close File #1
The number parameter is the same identification number assigned to the file in the Open File
statement. The pound sign (#) is optional. You do not need to execute a "save" command to save
a file that was created or modified through file input/output. You are done modifying the file as soon
as you issue the Close File statement. (MapBasic does provide a Save File statement, but its purpose
is to let you copy a file, not save changes to a file.)
There are many ways in which programs can generate runtime errors during file i/o. If the Open File
statement specifies the wrong file name, or if you attempt to open a file for output, but the file is
flagged as read-only, a runtime error will occur. If your program writes data to a file, the program
could generate a runtime error if the program runs out of disk space. If you try to open a file for
output, but that file is currently being modified by another network user, your program will generate
a runtime error. If you are developing an application that performs file input/output, you should build
error-handling routines into your program to detect and correct error conditions, and you should test
your application under conditions likely to cause problems (for example, out of disk space). For
information on how to create an error handler, see Debugging and Trapping Runtime Errors.
In some circumstances, you can prevent errors from happening by calling appropriate functions.
For example, before you issue an Open File statement, you can call the FileExists( ) function to
determine whether the file exists. Also, if your program needs to create a temporary, working file,
but you do not know what name or directory path to assign to the file (because you do not know the
names of your users' directories), call the TempFileName$( ) function. Other statements that are
related to file i/o:
• The Kill statement deletes a file.
• The Save File statement saves a copy of a file.
• The Rename File statement changes the name of a file.
• Functions such as ProgramDirectory$( ), HomeDirectory$( ) and ApplicationDirectory$( ) let you
determine different directory paths at runtime. For example, to build a string representing the name
of a file that exists in the MapInfo Pro directory (for example, the Startup workspace), when you
do not know the name of the directory, call ProgramDirectory$( ), to determine where MapInfo Pro
is installed.
If you intend to perform sequential file i/o (reading/writing of variable-length text files), there are
three different options you can specify in the Open File statement's For clause: Input, Output, or
Append.
Use the For Input clause if you intend to read from an existing file. For example, the Named Views
sample program (nviews.mb) issues the following statement to open an existing text file for input:
Each line of the text file contains four values: a name, an x-coordinate, a y-coordinate, and a zoom
distance. The Named Views application uses the following Input # statement to read each line into
four separate variables:
To create a file that contains a comma-separated list of expressions, issue an Open File statement
with the For Output clause or the For Append clause. After opening the file, use the Write # statement
to write data to the file. In the Write # statement, you can specify a comma-separated list of
expressions to be written to each line in the file. For example, the Named Views application issues
the following Write # statement (within a loop) to create a file with the four values (name, x, y, and
zoom) shown above:
The Write # statement encloses each string expression in double-quotation marks within the file,
as shown in the example above ("New York"...). In some situations, using the Write # statement
may be inappropriate, because you may not want text to be enclosed in quotation marks. To write
text to a file without quotation marks, use Print # instead of Write #.
If you want to read an entire line into one String variable, use the Line Input # statement. Use the
Print # statement to create a file that can later be read using the Line Input # statement. For an
example of using Print # and Line Input # to read or write an entire line at once, see the sample
program auto_lib.mb. The auto_lib program reads and writes MapInfo workspace files (specifically,
the startup workspace file).
You cannot write to a sequential file that was initially opened for input and you cannot read from a
sequential file that was initially opened for output.
To perform random-access file i/o, specify the For Random clause in the Open File statement:
When you open a file in Random mode, you include a Len clause that indicates the number of bytes
in each line in the file. Note that any text file contains end-of-line terminators; invisible characters
that are embedded in the file to mark the end of each line. The line length specified in the Len clause
(80 in the example above) specifies the exact number of characters in each record, including any
end-of-line terminators (for example, carriage-return/line-feed characters).
After you have opened a file for random access, you can read from or write to the file using the Get
and Put statements. See the MapBasic Reference for more information about these statements.
Binary files are files that contain numeric values stored in binary format. The following statement
demonstrates how to open a file for binary access:
After you have opened a file for binary access, you can read from or write to the file using the Get
and Put statements; see the MapBasic Reference.
Numerical data stored in binary format is stored very efficiently. For example, each Integer value is
stored using exactly four bytes of the file, regardless of how large the Integer value is. By contrast,
if an Integer value is nine digits long (for example, 111,222,333), and you store the value in a text
file, the value will occupy nine bytes of the file. Binary storage provides a more efficient format for
the storage of non-text data. However, if you need to be able to view your files in a text editor, you
should store your data in text files rather than binary files.
The records in a binary file can include character strings, but they must be of fixed length.
If you encounter problems reading text files that originated on another hardware platform or in
another country, you may need to use the Open File statement's optional CharSet clause. Every
character on a computer keyboard corresponds to a numeric code. For example, the letter "A"
corresponds to the character code 65. A character set is a set of characters that appear on a
computer, and a set of numeric codes that correspond to those characters.
Different character sets are used in different countries. For example, in the version of Windows for
North America and Western Europe, character code 176 corresponds to a degree symbol; however,
if Windows is configured to use another country's character set, character code 176 may represent
a different character. The fact that different countries use different character sets may cause problems
if you need to read a file that originated in a different country.
To correct character set-related misinterpretations, include a CharSet clause in your Open File
statement. The CharSet clause lets you explicitly state the character set with which the file was
originally created. If you include a CharSet clause which correctly identifies the file's origin, MapInfo
Pro will correctly interpret data while reading from (or writing to) the file. For a listing of character
set names that can be used in a CharSet clause, see CharSet in the MapBasic Reference.
In this section
Using Object Variables 205
Using the "Obj" Column 205
Querying An Object's Attributes 207
Creating New Objects 216
Creating Objects Based On Existing Objects 219
Modifying Objects 221
Working With Map Labels 224
Coordinates and Units of Measure 228
Advanced Geographic Queries 230
Graphical Objects
MapBasic's Object variable type allows you to work with both simple objects, like lines, and complex
objects, like regions. (Visual Basic programmers take note: MapBasic's Object type represents
graphical shapes, not OLE objects.)
MapBasic Object variables can be treated much like other variables. You can assign values to object
variables, pass object variables as arguments to functions and procedures, and store the values of
object variables in a MapInfo table.
Use the Dim statement to define an object variable:
You do not have to specify the specific type of object that you want the variable to contain. An object
variable can contain any type of map or layout object.
Use the equal sign (=) to assign a value to an object variable, as shown in the next example:
You can assign objects from other object variables, functions that return objects, or table expressions
of the form tablename.Obj. However, there is no syntax for specifying a literal ("hard-coded") object
expression.
An object variable holds all of the information that describes a map object. If you store a line object
in an object variable, the variable contains both geographic information about the line (for example,
the line's starting and ending coordinates) and display information (the line's color, thickness, and
style). MapBasic also provides four style variable types (Pen, Brush, Symbol, and Font) that can
store styles without storing object coordinates.
The column named Obj is a special column that refers to a table's graphical objects. Any table that
has graphical objects has an Obj column, although the Obj column typically does not appear in any
Browser window.
To access the contents of the Object column, use an expression of the form tablename.obj (or of
the form tablename.object). The following example declares an object variable (current_state), then
copies an object from the states table into the variable.
You can perform the same kinds of operations with object columns that you can with regular columns.
You can use SQL queries that reference the object column, update the values (objects) in the
column, and read its contents into variables.
The following statement creates a query table with state abbreviations and the area of each state;
the Obj column is used as one of the parameters to the Area( ) function:
The next example creates a one-row table with the total miles of highway in California:
Some rows do not contain map objects. For example, if you open a database file as a MapInfo table
and geocode the table, the geocoding process attaches point objects to the rows in the table.
However, if some of the rows were not geocoded, those rows will not have map objects. To select
all the rows that do not have objects, use the condition Not obj in the Select statement's Where
clause. The next statement selects all rows that do not have map objects:
Select *
From sites
Where Not obj
Not all tables are "mappable." For example, if you base a table on a spreadsheet or database file,
the file initially cannot be displayed in a map. To make the table mappable, you must use the Create
Map statement, which adds an object column to the table.
To remove the Object column from a table, use the Drop Map statement. Note that Drop Map
removes the object column completely. In some cases, you may want to delete individual objects
from a table, without deleting the entire Object column; this is sometimes referred to as "un-geocoding"
a table. To delete individual object values without removing the Object column, use the Delete Object
statement.
To determine whether a table has an Object column, call the TableInfo( ) function with the
TAB_INFO_MAPPABLE code.
Object columns have some restrictions that do not apply to other column types. For example, you
can only have one object column per table. When you perform a selection that joins two tables, and
both tables have object columns, the results table contains only one of the table's objects (the objects
from the first table listed in the Select statement's From clause).
The next example performs a query involving two mappable tables: the states table, and an outlets
table, which contains point objects representing retail outlets. The Select statement's From clause
lists both tables. Because the states table is listed first, the results table will contain objects from
the states table.
Select *
From states, outlets
Where states.state = outlets.state
Map From selection
If you list the outlets table first in the From clause, as shown below, the Select statement's results
table will contain point objects (outlets), rather than state regions:
Select *
From outlets, states
Where outlets.state = states.state
Map From selection
Each row in a table can contain only one object. Note, however, that an individual object can contain
multiple parts. A region object can contain many polygons; thus, a group of islands can be represented
as a single region object. Similarly, a polyline object can contain many sections. To determine the
number of polygons in a region object or the number of sections in a polyline object, select the
object, and choose MapInfo Pro's Info command, located on the MAP tab in the Analyze group. To
determine the number of sections or polygons from within a program, call the ObjectInfo( ) function
with the OBJ_INFO_NPOLYGONS code.
A MapInfo table can contain a mixture of different types of objects. For example, a street map might
contain a mixture of lines and polylines. You can call the ObjectInfo( ) function with the
OBJ_INFO_TYPE code to determine the object's type. For details, see ObjectInfo( ) in the MapBasic
Reference or MapBasic Help.
If you are using the MapBasic window interactively, there are various other ways you can display
an object's type. For example, you could issue the following statements from the MapBasic window
to display a message describing the object's type:
The following statement selects all Text objects from a classic Layout window. For background on
what classic Layout windows are, see About Layout Windows.
Select *
From Layout1
Where Str$(obj) = "Text"
Note that labels are not the same as text objects. To query a text object, you call functions such as
ObjectInfo( ). To query a label, you call functions such as Labelinfo( ). Labels are discussed in
Working With Map Labels.
Every object has one or more style settings. For example, every line object has a Pen style, which
defines the line's color, thickness, and pattern (for example, solid vs. dot-dash), and every Point
object has a Symbol style, which defines the point's shape, color, and size. Enclosed objects such
as regions have both a Pen style and a Brush (fill) style.
The following table summarizes the four object styles.
Font Font name, style, size, text color, background color; applies only to text objects
Symbol For MapInfo Pro symbols: Shape, color, and size attributes.
For symbols from TrueType Fonts: Shape, color, size, font name, font style (for example,
bold, italic, etc.), and rotation attributes.
For custom symbols based on bitmap files: File name, color, size, and style attributes.
For detailed information on the four styles, see Brush clause, Font clause, Pen clause, and Symbol
clause in the MapBasic Reference and MapBasic Help.
The MapBasic language provides various statements and functions that allow you to create objects
(for example, the Create Text statement, the CreateLine( ) function, etc.). Each of the object creation
statements has optional clauses to let you specify the style(s) for that object. For example, the
Create Line statement includes an optional Pen clause that lets you specify the line's style. If you
issue an object creation statement that does not specify any style settings, MapInfo Pro assigns the
current styles to the object.
Note: You cannot use the = operator to compare two style values. For example, the following
program, which attempts to compare two Brush variables, will generate a runtime error.
b1 = MakeBrush(2, 255, 0)
b2 = CurrentBrush()
If b1 = b2 Then
Note "The two brush styles are equal."
End If
If you need to compare two styles, use the Str$( ) function to convert each style into a string
expression. For example, the following statement compares two Brush values:
If you need to compare specific elements of a style (for example, to see whether two Symbol styles
have the same point size), use the StyleAttr( ) function to extract individual style elements (color,
etc.), and then compare the individual elements.
Every text object has a Font style. A Font style defines the type face (for example, Times Roman
vs. Helvetica), text style (for example, bold, italic, etc.), and text color. A Font style also identifies
how large the text is, in terms of point size. However, the point size is sometimes ignored. The
following list summarizes how a Font's point size affects different types of text.
• When you create a text frame in a Layout window (or a text object in a classic Layout window),
the Font's point size controls the text height. If the Font style specifies 10-point text, the text object
is defined with 10-point text.
On a classic Layout window, the text might not display at 10 points, depending on whether you
zoom in or out on the layout; but when you print the layout, the text height will be 10 points. For
background on what classic Layout windows are, see About Layout Windows.
• When you use the Create Text statement to create a text object in a mappable table, the current
font's point size is ignored. In this situation, the text height is controlled by map coordinates, which
you specify in the Create Text statement. When you issue a Create Text statement, you specify
two pairs of x- and y-coordinates that define a rectangular area on the map; the text object fills
the rectangular area. Because of this design, text objects stored in a mappable table will grow
larger as you zoom in, and grow smaller as you zoom out.
• When you use the CreateText( ) function to create a text object in a mappable table, the current
font's point size controls the initial size of the text. However, zooming in on the map will cause the
text to grow larger.
• When you create a label in a Map window, the Font's point size controls the text height. The text
displays and prints at the height specified by the Font style. Note that labels behave differently
than text objects stored in a table. Labels are discussed in Working With Map Labels.
A Font style includes a font name, such as "Courier" or "Helvetica." Font names may be different
on each hardware platform; for example, Helv and TmsRmn (or Times New Roman) in the Microsoft
Windows environment are called Helvetica and Times on the Sun platforms. Helvetica, Times and
Courier are recognized in a MapBasic Font clause regardless of the platform that is in use at runtime.
Stacked Styles
You can stack styles for a layer, so that they become a list of styles drawn on top of each other, to
create a more complex or interesting looking map feature. You can stack styles for points, polylines,
and polygon features. This is especially useful for polyline styles.
Figure A shows a sample line using one of MapInfo's interleaved line styles. Figure B shows the
same sample using a stacked line style.
Stacked styles create more meaningful display styles for your application without having to add your
data as multiple layers in a map. You can define as many styles in a stacked style as you want.
However, the more styles you define the more you will impact the map's rendering performance.
Typically, most cartographic maps would use two or three styles in a stacked style to draw features.
To use this as a global style override for your map layer, you would add it to the Global clause in a
Set Map statement:
The first Line clause encountered in MapBasic is drawn first, followed by the next Line clause if
there is a comma, and so on.
To create stacked styles for Layer Display Overrides using MapBasic, see the MapBasic Reference
for the Set Map statement. To query stacked style attributes, refer to new functions in the What's
New section of the MapBasic Reference.
Style Variables
MapBasic provides style variable types-Pen, Brush, Symbol, and Font-that correspond to object
style attributes. There are several ways you can assign a style to a style variable:
The MakePen( ) function's arguments define the pen style: 1 signifies that the style is one pixel
wide, 10 signifies a pattern (dotted), and the RGB( ) function call specifies a color. For more
information about the three parameters that make up a pen style (including a chart of all available
line patterns), see Pen clause in the MapBasic Reference or MapBasic Help. Similarly, for more
information about Brush, Font, or Symbol options, see Brush clause, Font clause, or Symbol clause.
The following example demonstrates how to read an existing object's Pen style into a Pen variable:
Once you have stored a Pen expression in a Pen variable, you can use the Pen variable within an
object creation statement:
The function StyleAttr( ) returns one component of a particular style. For example, the TextBox
sample program displays a dialog box that lets the user choose a pen style; the selected style is
stored in the Pen variable, pstyle. TextBox then issues the following statement to read the Pen
style's color component into an Integer variable (line_color):
Colors are stored internally as integer numbers. For instance, black is 0 and blue is 255. The RGB( )
function calculates the color value from quantities of red, green, and blue that you specify. For
instance, the function call RGB(0, 255, 0) returns the color value for green.
Use the RGB( ) function where a color is called for. For example:
Alternately, instead of calling RGB( ) you can use one of the standard color definition codes (BLACK,
WHITE, RED, GREEN, BLUE, YELLOW, CYAN, and MAGENTA) defined in mapbasic.def.
The ObjectInfo( ) function lets you extract a Pen, Brush, Symbol, or Font value from an object. Once
you have a Pen, Brush, Symbol or Font, you can call the StyleAttr( ) function to examine individual
elements (for example, to determine the color of a Symbol style).
You can use the Select statement to select objects based on styles. As the following example shows,
the Select statement's Where clause can call the ObjectInfo( ) and StyleAttr( ) functions, so that
MapInfo Pro selects only those objects that have certain attributes (for example, objects of a certain
color).
The following example adds a custom button to the Tools toolbar. If you select a point object and
then click the custom button, this program selects all point objects in the same table that have the
same color.
Include "mapbasic.def"
Declare Sub Main
Declare Sub SelectPointsByColor()
Sub Main
' Add a custom button to the Tools toolbar.
Alter ButtonPad "Tools" Add
PushButton
Calling SelectPointsByColor
HelpMsg "Select points of same color\nSelect By Color"
End Sub
Sub SelectPointsByColor
Dim i_color, i_open As Integer
Dim symbol_style As Symbol
Dim object_name, table_name As String
Exit Sub
End If
' See whether the selected object is a Point.
' If it is a Point, determine its Symbol and Color.
Fetch First From Selection
object_name = Str$(Selection.obj)
If object_name = "Point" Then
symbol_style = ObjectInfo(Selection.obj,OBJ_INFO_SYMBOL)
i_color = StyleAttr(symbol_style, SYMBOL_COLOR)
End If
End Sub
This example works with point objects, but the same techniques could be used with other object
types. For example, to work with region objects instead, you would test for the object name "Region"
instead of "Point", and call ObjectInfo( ) with OBJ_INFO_BRUSH instead of OBJ_INFO_SYMBOL,
etc.
MapBasic contains a set of statements and functions through which you can create graphical objects.
This section provides an introduction to object-creation statements and functions; for more, see the
MapBasic Reference Guide.
Object-Creation Statements
The following statements can be used to create new objects. All of the statements may be used to
create objects on Layout windows. All of the statements except for Create Frame may be used to
create objects on Map windows.
• Create Arc statement: Creates an arc.
• Create Ellipse statement: Creates an ellipse or a circle. (A circle is simply a special case of an
arc-an arc with equal width and height.)
• Create Frame statement: Creates a frame. Frames are special objects that exist only on Layout
windows; each frame can display the contents of an open window. Thus, if you want to place two
maps on your page layout, create two frames.
• Create Line statement: Creates a line.
• Create Point statement: Creates a point.
• Create Pline statement: Creates a polyline.
• Create Rect statement: Creates a rectangle.
• Create Region statement: Creates a region.
• Create RoundRect statement: Creates a rounded rectangle.
• Create Text statement: Creates a text object.
• AutoLabel statement: This statement "labels" a Map window by drawing text objects to the Cosmetic
layer. This statement does not create labels, it creates text objects. To create labels, use the Set
Map statement.
Object-Creation Functions
In some ways, object-creation functions are more powerful than the corresponding object-creation
statements, because a function call can be embedded within a larger statement. For example, the
following Update statement uses the CreateCircle( ) function to create a circle object for every row
in the table:
Update sites
Set obj = CreateCircle(lon, lat, 0.1)
This example assumes that the sites table has a lon column containing longitude values (x
coordinates) and a lat column containing latitude values (y coordinates).
Polyline objects and region objects are more complex than other objects in that polylines and regions
can have variable numbers of nodes (up to 32,763 nodes per object).
You can create a region object using the Create Region statement. In the Create Region statement,
you can explicitly state the number of nodes that the object will contain. However, there are situations
where you may not know in advance how many nodes the object should contain. For example, a
program might read object coordinates from a text file, then build a region object that contains one
node for each pair of coordinates read from the file. In that situation, the program cannot know in
advance how many nodes the object will contain, because the number of nodes depends on the
amount of information provided in the file.
If your program will create region or polyline objects, you may want to create those objects in two
steps:
1. Issue a Create Region statement or a Create Pline statement to create an empty object (an object
that has no nodes).
2. Issue Alter Object statements to add nodes to the empty object. The Alter Object statement is
usually placed within a loop, so that each iteration of the loop adds one node to the object.
The following example demonstrates this process:
Include "mapbasic.def"
Type Point
x As Float
y As Float
End Type
For i = 1 to numnodes
Alter Object myobj Node Add (objcoord(i).x,objcoord(i).y)
Next
After you create an object and store it in an Object variable, you usually will want to store the new
object in a table. The user will not be able to see the object unless you store the object in a table.
To store an object value in a table, use the Insert statement or the Update statement. Which statement
you should use depends on whether you want to attach the object to an existing row or create a
new row to store the object.
Use the Update statement to attach an object to an existing row in a table. If that row already has
an object, the new object replaces the old object. The Update statement can update any column in
a table; to update a row's graphical object, refer to the special column name Obj.
For example, the following statement stores a point object in the Obj column of the first row in the
Sites table:
Update sites
Set Obj = CreatePoint(x, y)
Where RowID = 1
Use the Insert statement to add a new row to a table. Insert lets you add one row to a table at a
time or insert groups of rows from another table. The following statement inserts one new row into
the Sites table, and stores a line object in the new row's Obj column:
The TextBox sample program demonstrates both the Insert statement and the Update statement.
The TextBox application draws a box (a rectangle object) around each selected text object; each
box is stored using an Insert statement. In addition, if the user checks the Change Text Color to
Match Box Color check box, the program also changes the color of the selected text object, and
then uses an Update statement to store the modified text object back in the table.
The Insert and Update statements are both powerful, flexible table-manipulation statements. In the
preceding examples, the statements operated only on one column (the graphical object column,
Obj); however, you can manipulate any column of your table using Insert and Update.
A MapBasic program can create new objects based on existing objects. This section provides an
introduction to various MapBasic statements and functions; for more information about a particular
statement or function, see the MapBasic Reference or MapBasic Help.
Creating a Buffer
A buffer region is a region representing the area within a certain distance of another object or objects.
Buffers are useful for locating objects within a certain distance of other objects. For instance, you
can create a buffer around a fiber optic cable to find all the dig sites within three hundred meters of
the cable. You can use the Create Object statement to create buffer regions.
The following example creates a 300-meter buffer region around the selected segment of cable,
then searches for dig locations within the buffer:
MapBasic also provides a Buffer( ) function, which returns an object value representing a buffer
region.
The Create Object statement also can calculate unions and intersections of regions. If you specify
Create Object As Merge, MapInfo Pro removes common segments from two or more neighboring
regions, producing a single, combined region. When two regions with a common border are merged
(for example, Nevada and California), the resulting region covers the total area of both regions. The
border between the neighboring regions is removed.
The following example demonstrates how to combine two regions from the states table:
Select *
From states
Where state ="CA" Or state = "NV"
The Merge operation is an exclusive-or (XOR) process. If you merge two region objects, and one
of the objects is completely contained within the other object, the merge operation removes the
smaller object's area from the larger object, leaving a hole.
Merge creates a new object. The two merged regions still exist in the source table. You may want
to remove the two original regions, as shown below:
Create Object As Union and Create Object As Intersection let you create a region that represents
logical combinations of two or more regions. These statements are different from Merge because
they work with all of the segments of the source regions, not just the common segments. A Union
is the total area of all polygons. An Intersection is the overlapping area. The object created by a
union or an intersection may contain new nodes that do not appear in the original regions. MapBasic
also provides a Combine( ) function, which returns the object produced by combining two other
objects.
Creating Isograms
An Isogram is a map that displays a set of points that satisfy a distance or time condition. Isograms
are either IsoChrones or IsoDistances. An IsoChrone is a polygon or set of points representing an
area that can be traversed from a starting point in a given amount of time along a given road network.
An IsoDistance is a polygon or set of points representing an area that can be traversed from a
starting point travelling a given distance along a given road network.
Using the Create Object As Isogram statement you can create one or more of these regions, each
with a different brush and pen style to differentiate them on your map. In order to create an Isogram,
you need the use of an external service such as Envinsa.
To create an Isogram:
1. Open a connection to Envinsa using the Open Connection statement.
The statement returns a handle to the connection in a variable that is passed on.
2. Configure the Isogram connection with the Set Connection Isogram statement.
3. Create the desired region with the Create Object As Isogram statement.
A group of Offset functions and statements can be use to produce new objects that are offset from
the initial objects by specified units.
The following statements can be used to create offset copies of existing objects.
• Offset( ) function: returns a copy of initial object offset by specified distance and angle.
• OffsetXY( ) function: returns a copy of initial object offset by a specified distance along the X and
Y axes.
• SphericalOffset( ) function: returns a copy of initial object by a specified distance and angle. The
Distance Type used must be Spherical.
• SphericalOffsetXY( ) function: returns a copy of initial object by a specified distance and angle.
The Distance Type used must be Spherical.
• CartesianOffset( ) function: returns a copy of initial object by a specified distance and angle. The
Distance Type used must be Cartesian.
• CartesianOffsetXY( ) function: returns a copy of initial object by a specified distance and angle.
The Distance Type used must be Cartesian.
Modifying Objects
MapBasic provides many statements that you can use to modify an existing map object. Regardless
of which statement you use to modify an object, the process of modifying an object is as follows:
1. Make a copy of the original object. (Often, this involves declaring an object variable, issuing a
Fetch statement to position the row cursor, and issuing an assignment statement of the form
variable_name = tablename.obj).
2. Issue statements or functions to modify the object. (This often involves issuing one or more Alter
Object statements.)
3. Issue an Update statement to store the modified object back in the table.
The TextBox program demonstrates this process. If the user checks the Change Text Color to Match
Box Color check box, the TextBox program uses an Alter Object statement to change the color of
the selected object, and then uses an Update statement to store the altered text object back in the
table.
Repositioning An Object
Use the Objects Move statement to move objects a specified distance along the positive X axis.
You can also specify the Distance Units and Distance Type. Use the Objects Offset statement to
make a new copy of objects offset a specified distance along the positive X axis. You can also
specify the Distance Units and Distance Type and specify whether the copied objects are placed in
the same table as the source objects or into a different table.
To modify an object's coordinates, issue an Alter Object statement that includes a Geography clause.
You may need to issue more than one Alter Object statement (one statement to reset the object's
x-coordinate, and another statement to reset the y-coordinate).
The Alter Object statement lets you modify an object's style. The example below uses the Alter
Object command to change a selected object in a table:
Include "mapbasic.def"
Dim myobj As Object, mysymbol As Symbol
mysymbol = CurrentSymbol()
Fetch First From selection
myobj = selection.obj
If ObjectInfo(myobj, OBJ_INFO_TYPE) = OBJ_POINT Then
Alter Object myobj
Info OBJ_INFO_SYMBOL, mysymbol
Update selection Set obj = myobj Where RowID = 1
Else
Note "The selected object is not a point."
End If
• To modify the height of a text object that appears on a Layout window (or a classic Layout
window), change the object's Font style (by issuing an Alter Object statement with an Info clause).
The frame in the Layout window must be in an active state.
Note: For background on what classic Layout windows are, see About Layout Windows.
• To modify the height of a text object that appears on a Map window or in a map frame in a Layout
window, change the object's x- and y-coordinates (by issuing an Alter Object statement with a
Geography clause). The map in the Layout window must be in an active state.
• To modify the height of a map label in a Map window or in a map frame in a Layout window, issue
a Set Map statement. The map in the Layout window must be in an active state.
To convert an object to a region object, call the ConvertToRegion( ) function. To convert an object
to a polyline object, call the ConvertToPline( ) function. For more information on these functions,
see the MapBasic Reference or MapBasic Help.
The following statements and functions allow you to erase part of an object:
• The Overlap( ) function takes two object parameters, and returns an object value. The resulting
object represents the area where the two objects overlap (the intersection of the two objects).
• The Erase( ) function takes two object parameters, and returns an object value. MapInfo Pro
erases the second object's area from the first object, and returns the result.
• The Objects Intersect statement erases the parts of the current target objects that are not covered
by the currently-selected object.
• The Objects Erase statement erases part of the currently-designated target object(s), using the
currently-selected object as the eraser.
The Objects Erase statement corresponds to MapInfo Pro's Erase Target command on the SPATIAL
tab. The Objects Intersect statement corresponds to MapInfo Pro's Erase Outside Target command
on the SPATIAL tab. Both operations operate on the objects that have been designated as the
"editing target." The editing target may have been set by the user choosing Set Target on the
SPATIAL tab, or it may have been set by the MapBasic Set Target statement. For an introduction
to the principles of specifying an editing target, see the MapInfo Pro User Guide.
Points Of Intersection
As mentioned earlier, you can add nodes to a region or polyline object by issuing an Alter Object
statement. However, the Alter Object statement requires that you explicitly specify any nodes to be
added. If you want to add nodes at the locations where two objects intersect, use the Objects Overlay
statement or the OverlayNodes( ) function.
Call the IntersectNodes( ) function to determine the coordinates of the point(s) at which two objects
intersect. IntersectNodes( ) returns a polyline object containing a node at each point of intersection.
Call ObjectInfo( ) to determine the number of nodes in the polyline. To determine the coordinates
of the points of intersection, call ObjectNodeX( ) and ObjectNodeY( ).
A map label is treated as a display attribute of a map object. However, MapInfo Pro still supports
the AutoLabel statement to provide backwards compatibility with older versions of the product in
which map labels were text objects in the Cosmetic layer.
Turning Labels On
A MapInfo Pro user can configure labeling options through the Layer Control window. A MapBasic
program can accomplish the same results through the Set Map...Label statement. For example, the
following statement displays labels for layer 1:
In the Layer Control window, clearing the Automatic Labels Off/On button (in the list of layers) turns
off the default labels for that layer. This MapBasic statement has the same effect:
Note: The Set Map...Auto Off statement turns off default (automatic) labels, but it does not affect
custom labels (labels that were added or modified by the user). The following statement
temporarily hides all labels for a layer―both default labels and custom labels:
A MapInfo Pro user can reset a layer's labels to their default state by choosing Clear Custom Labels
on the MAP tab. This MapBasic statement has the same effect:
MapInfo Pro users can edit labels interactively. For example, to hide a label, click on the label to
select it, and press Delete. To move a label, click the label and drag.
To modify individual labels through MapBasic, use a Set Map...Label statement that includes one
or more Object clauses. For example, the following statement hides two of the labels in a Map
window:
For each label you want to customize, include an Object clause. In this example, Object 1 refers to
the label for the table's first row, and Object 3 refers to the label for the table's third row. To save
custom labels, save a workspace file; see the MapBasic Save Workspace statement.
CAUTION: Packing a table can invalidate custom (edited) labels previously stored in workspaces.
When you store edited labels by saving a workspace, the labels are represented as
Set Map...Object... statements. Each Object clause refers to a row number in the table.
If the table contains rows that have been marked deleted (i.e., rows that appear grayed
out in a Browser window), packing the table eliminates the deleted rows, which can
change the row numbers of the remaining rows.
In other words, if you pack a table and then load a previously-saved workspace, any edited labels
contained in the workspace may be incorrect. Therefore, if you intend to pack a table, you should
do so before creating custom labels.
If the only deleted rows in the table appear at the very end of the table (i.e., at the bottom of a
Browser window), then packing the table will not invalidate labels in workspaces.
Querying Labels
To see the MapBasic syntax that corresponds to the Layer Control window, do the following:
1. Open the MapBasic window.
2. Make a Map window the active window.
3. On the HOME tab, in the Tool Windows group, click Layers to open the Layer Control window.
4. Select the desired options.
MapInfo Pro applies your changes, and displays a Set Map statement in the MapBasic window.
You can copy the text out of the MapBasic window and paste it into your program.
To see the MapBasic syntax that corresponds to editing an individual label, do the following:
1. Modify the labels in your Map window. (Move a label, delete a label, change a label's font, etc.)
2. Save a workspace file.
3. View the workspace file in a text editor, such as the MapBasic editor. Edits to individual labels
are represented as Set Map... Layer... Label... Object statements in the workspace.
The following table summarizes the differences between text objects and labels.
MapBasic statements used to create AutoLabel, Create Text, CreateText( ) Set Map
the text:
MapBasic statement used to select the Select MapBasic programs cannot select
text: labels.
Saving text in a Map: Text objects can be stored in mappable Labels are only stored in workspaces.
tables.
Saving text in a Layout: Text objects created in a Layout can Not applicable. Labels cannot appear
be saved in a workspace. in layouts (except when a map is in a
layout).
Controlling the text height: Text height is affected by the current A label's text height is controlled by its
map scale. Text grows larger as you font. Zooming in or out does not affect
zoom in, and smaller as you zoom out. a label's text height.
Converting between text and labels: Not applicable. Given a text object, Given a label, the Labelinfo( ) function
there is no MapBasic function that can return a text object that
returns a Label. approximates the label. See
LABELER.MBX for an example.
When you create a label, you specify the label's anchor point (in x- and y-coordinates). For example,
if you are viewing a map of the World table, this statement creates a label that acts as a title:
If you need to place text on your map, you may find it easier to create labels, rather than text objects.
You could create a table whose sole purpose is to be labeled, using this procedure:
1. Create a table (using the Create Table statement) that contains a character column. Make the
character column wide enough to store the text that you want to appear on the map. Make the
table mappable (using the Create Map statement).
2. Add the table to your Map window (using the Add Map statement). Use the Set Map statement
to set the table's labeling options (font, Auto On, etc.).
3. When you want to add text to the map, insert a point or line object into the table, using an invisible
symbol style (shape 31) or invisible pen style (pattern 1). The object will not be visible, but its
label will appear. (Use line objects if you want the text to be rotated.)
Note: The sample program COGOLine.mb demonstrates how to create a line object at a specific
angle.
Note: With this strategy, you do not need to use Set Map...Object statements to customize each
label's position. You can display labels at their default positions. Then, if you want to move
a label, move the object that corresponds to the label.
A MapBasic application can work in only one coordinate system at a time. MapBasic uses Earth
coordinates, non-Earth coordinates, or Layout coordinates. The fact that MapBasic has a current
coordinate system gives rise to the following programming guidelines:
• Earth map: Before you create, modify, or query objects from an Earth map, make sure that
MapBasic is working in an Earth coordinate system. This is the default. With many MapBasic
applications you do not need to worry about coordinate systems.
• Non-Earth map: Before creating, modifying, or querying objects from a non-Earth map, make sure
that MapBasic is working in a non-Earth coordinate system. To do this, issue a Set CoordSys
Nonearth statement.
• Classic Layout window: Before creating, modifying, or querying objects from a classic Layout
window, make sure that MapBasic is working in a layout coordinate system. To do this, issue a
Set CoordSys Layout statement. For background on what classic Layout windows are, see About
Layout Windows.
• Layout window: Before creating shapes, text, and image frames in a Layout window, make sure
that MapBasic is working in a layout coordinate system. To do this, issue a Set CoordSys Layout
statement. Creating map or browser frames and querying objects does not require this.
Each MapBasic application has a CoordSys system setting that represents the coordinate system
currently in use by that application. The default coordinate system setting is the Earth (longitude,
latitude) system. By default, every MapBasic application can work with objects from Earth maps,
and most MapInfo tables fall into this category. If a MapBasic application needs to work with objects
on a Layout window, you must first issue a Set CoordSys Layout statement, as follows:
The Set CoordSys Layout statement lets you specify a paper unit name, such as "in" (inches). This
dictates how MapBasic interprets Layout window coordinate information. To work in centimeters
or millimeters, specify the unit name as cm or mm respectively. The following program opens a
Layout window, then places a title on the layout by creating a text object. Since the object is created
on a Layout window, the Create Text statement is preceded by a Set CoordSys Layout statement.
Include "mapbasic.def"
Create Text
Into Window win_num
"Title Goes Here"
(3.0, 0.5) (5.4, 1.0)
Font MakeFont("Helvetica", 1, 24, BLUE, WHITE)
In the example above, the Layout coordinate system uses inches as the unit of measure. All of the
coordinates specified in the Create Text statement represent inches. After you change the coordinate
system through the Set CoordSys statement, the new coordinate system remains in effect until you
explicitly change it back. Every MapBasic application has its own coordinate system setting. This
allows one application to issue a Set CoordSys statement without interfering with any other
applications that are running.
The MapBasic coordinate system is independent of the coordinate system used by any MapInfo
Pro Map window. The default coordinate system is latitude/longitude (NAD 1927) (represented by
decimal degrees, not degrees, minutes, and seconds.)
All coordinates specified in MapBasic statements or functions should be in latitude and longitude
unless you change the MapBasic coordinate system with the Set CoordSys statement. For example,
the function Centroidx( ) returns the longitude of an object's centroid in decimal degrees, by default,
even if the object is stored in a table or a window that has been assigned a different coordinate
system. For example, the selection resulting from the statement below has the values: WY -107.554
43, the longitude and latitude of the centroid of Wyoming:
After the following statements are executed, the selection contains: WY -934612.97 2279518.38;
the coordinates reflect an Albers projection.
Set CoordSys Earth Projection 9, 62, "m", -96, 23, 29.5, 45.5, 0, 0
Select state, CentroidX(obj), CentroidY(obj)
From states
Where state = "WY"
To reset the MapBasic coordinate system to its default, issue the following statement:
Units of Measure
obj_var = CreateCircle(x, y, 5)
Because MapBasic's default distance unit is miles, the circle object will have a radius of five miles.
However, if you reset the distance unit by issuing a Set Distance Units statement, the meaning of
the radius parameter (5) changes. Thus, the following example creates a circle object with a radius
of 5 kilometers:
To reset the current area unit or the current paper unit, use the Set Area Units statement or the Set
Paper Units statement, respectively.
MapBasic programs can perform complex data queries that take both tabular and graphical data
into account. For example, your program can use the Add Column statement to calculate totals and
averages of data values within a region, based on how the region object overlaps and intersects
objects in other map layers.
To understand how MapBasic and MapInfo Pro can perform data-driven geographic analysis, you
must understand how MapBasic programs can manage and query tables. If you have not already
done so, you may want to read Working With Tables before reading this section.
MapBasic does not allow you to use the equal operator (=) to perform logical comparisons of objects
(If object_a = object_b). However, MapBasic does provide several geographic operators that let you
compare objects to see how they relate spatially. The MapBasic comparison operators Contains,
Within, and Intersects and the optional modifiers Part and Entire allow you to compare objects in
much the same way as the relational operator can be used with numbers.
Below is an example of a geographic comparison in an If...Then statement:
At least one of the objects used in a Within and Contains condition should be an object that represents
an enclosed area: regions, ellipses, rectangles, or rounded rectangles.
Whether you use Within or Contains depends on the order of the objects in the expression. The rule
is as follows:
• Use Within to test whether the first object is inside the second object.
• Use Contains to test whether the first object has the second object inside of it.
For example, when comparing points with regions:
• Points are Within regions.
• Regions Contain points.
The following statement selects the state(s) containing a distribution center object:
The Within operator and the Contains operator test whether the centroid of an object is inside the
other object. Use Entire(ly) to test whether the whole object is inside another object. Use Part(ly) to
test whether any part of an object is within the other object.
The next statement selects all sections of a highway with any part going through a county:
The Partly Within operator tests whether any portion of the first object is within the other object or
touching it at any point. You also can use the Entirely Within operator to test if all of an object is
within the area of another object. Since checking all of the segments of an object involves more
calculations than checking only the centroid, conditions that involve the Partly modifier or the Entirely
modifier evaluate more slowly.
The Intersects operator can be used with all types of objects. If any part of an object crosses, touches,
or is within the other object, the objects intersect. Regions that touch at one corner intersect. A point
on a node of a polyline intersects the polyline, lines that cross intersect, and a point inside a region
intersects that region.
The table below summarizes MapBasic's geographic operators:
You can use MapBasic functions or geographic comparison operators to build queries using the
object column of your table. Building these queries is much like building queries for regular columns,
except that there are no object literals. Instead, queries using objects typically use functions or
comparison operators (for example, Entirely Within) to analyze objects.
The statement below uses the ObjectLen( ) function to find all the sections of cable greater than
300 meters in length:
Select *
From cable
Where ObjectLen(obj, "m") > 300
The next statement selects all the storage tanks within one kilometer of a well at longitude lon, and
latitude lat:
The statement below creates a selection with employees and the distance they live from an office
(in order of farthest to nearest):
Select
Name, Distance(Centroidx(obj), Centroidy(obj),
office_lon, office_lat, "km")
From employee
Order By 2 Desc
MapBasic allows you to query objects from one table in relation to objects in another table. For
instance, you might want to query a table of doctors to see which ones are in Marion County, Indiana.
Doctors are in one table, counties in another.
One approach is to select a county from the county table, copy the object into a variable, and query
the table of doctors against the object variable. This is how it looks:
If you use a subselect in the Where clause instead of the variable mycounty, you can produce the
same results with fewer statements:
Select *
From doctors
Where obj Within
(Select obj From counties Where name="Marion" And state="IN")
Notice that the subselect (the latter select, which appears in parentheses) returns a table with only
one column and one row―the object representing Marion County, Indiana. MapInfo Pro examines
each row in the doctors table to determine whether that row is inside Marion County. The subselect
performs the same function as the variable in the previous example (mycounty), because it returns
the appropriate object to the expression.
To ensure that the subselect returns only the object column, the Select clause of the subselect lists
only one column, obj. The statement will not evaluate properly if there are many columns in the
subselect or if the column isn't an object column.
Use the Any( ) operator when the subselect returns multiple rows. The next example shows a
subselect that uses Any( ) to process a group of rows. It finds all the doctors in counties that have
a per-capita income of less than $15,000. Compare the locations with each county in the subselect.
Select *
From doctors
Where obj Within
Any (Select obj From counties Where inc_pcap < 15000)
Switch the order in the Select statement to select counties instead of doctors. The statement below
finds all the counties that have a doctor specializing in neurology:
Select *
From counties
Where obj Contains
(Select obj From doctors Where specialty = "Neurology")
Select *
From states
Where obj Intersects (Select obj From states Where state = "NE")
Joins link two tables together by matching, row-for-row, entries in specified columns from two tables.
The result is one table with a combination of columns for both tables with as many rows as there
are matches. MapBasic extends the relational concept of a join with geographic join criteria. For
instance, if you join demographic data with the states map, the resulting table can have all of the
information from the states map as well as the demographic data for each state.
MapInfo Pro supports geographic conditions in the join. For instance, instead of matching two tables
by a numeric ID, you can join tables by matching objects from one table that contain an object in
the second table. This is particularly useful when there is no matching field. You can join all of the
housing projects in a table with their congressional districts without having the congressional district
information in the projects table to begin with. Determining the district may be the reason to perform
the join in the first place―to see which projects are in which congressional districts. The SQL Select
statement for that operation is:
Select *
From projects, congdist
Where projects.obj Within congdist.obj
After you have joined the tables geographically, you can use the Update statement to enter the
congressional district names (from the name column) into the projects table (the column cd) as
follows:
The resulting projects table now contains the name of the congressional district for every project.
The following example calculates the total dollars spent on projects in each congressional district:
Since the table order in the Where clause has changed, use the condition Contains instead of Within.
The Add Column statement can perform advanced polygon-overlay operations that perform
proportional data aggregation, based on the way one table's objects overlap another table's objects.
For example, suppose you have one table of town boundaries and another table that represents a
region at risk of flooding. Some towns fall partly or entirely within the flood-risk area, while other
towns are outside the risk area. The Add Column statement can extract demographic information
from the town-boundaries table, then use that information to calculate statistics within the flood-risk
area. For information about the Add Column statement, see the MapBasic Reference.
In this section
Declaring and Calling Dynamic Link Libraries (DLLs) 238
Creating Custom Button Icons and Draw Cursors 244
Inter-Application Communication Using DDE 246
Incorporating Windows Help Into Your Application 252
Advanced Features of Microsoft Windows
Dynamic Link Libraries, or DLLs, are files that contain executable routines and other resources
(such as custom icons for toolbar buttons). You can use DLLs as libraries of external routines, and
call those routines from your MapBasic program. You can issue a Call statement to a DLL routine,
just as you would use a Call statement to call a MapBasic procedure. There are many DLLs available
from commercial sources. The documentation for a particular DLL should describe the routines that
it contains, its specific name, and any required parameters.
Note: If your MapBasic program calls DLLs, the DLLs must be present at run time. In other words,
if you provide your users with your compiled application (MBX file), you must also provide
your users with any DLLs called by your MBX.
The Windows DLLs are documented in the Windows Software Developer's Kit (SDK). Third-party
books that describe the standard Windows files are also available.
Before your MapBasic program can call a DLL routine, you must declare the DLL through a Declare
statement (just as you use the Declare statement to declare the sub-procedures in your MapBasic
source code). In the Declare statement, you specify the name of the DLL file and the name of a
routine in the library.
If you specify an explicit path in your Declare statement (for example, C:\lib\mylib.dll), MapInfo Pro
tries to load the DLL from that location. If the DLL file is not in that location, MapInfo Pro does not
load the DLL (possibly causing runtime errors). If your Declare statement specifies a DLL name
without a path (for example, mylib.dll), MapInfo Pro tries to locate the DLL from various likely locations,
in the following order:
1. If the DLL is in the same directory as the .MBX file, MapInfo Pro loads the DLL; otherwise, go to
step 2.
2. If the DLL is in the directory where MapInfo Pro is installed, MapInfo Pro loads the DLL; otherwise,
go to step 3.
3. If the DLL is in the Windows\System directory, MapInfo Pro loads the DLL; otherwise, go to step
4.
4. If the DLL is in the Windows directory, MapInfo Pro loads the DLL; otherwise, go to step 5.
5. MapInfo Pro searches for the DLL along the user's system search path.
MapInfo Pro follows the same search algorithm when loading bitmap icon and cursor resources
from DLLs.
Passing Parameters
Many DLLs take parameters; for example, the example above shows a Declare statement for a DLL
routine that takes two parameters.
MapBasic can pass parameters two ways: By value (in which case MapInfo Pro copies the arguments
onto the stack), or by reference (in which case MapInfo Pro puts the address of your MapBasic
variable on the stack; the DLL then can modify your MapBasic variables). For an introduction to the
conceptual differences between passing parameters by reference vs. by value, see MapBasic
Fundamentals.
To pass a parameter by value, include the ByVal keyword in the Declare statement (as shown in
the example above). If you omit the ByVal keyword, the argument is passed by reference.
The following MapBasic data types may not be passed by value: Arrays, custom data types (i.e.,
structures), and aliases. Fixed-length string variables may be passed by value, but only if the DLL
treats the parameter as a structure. See String Arguments, below.
The next example shows how a MapBasic program can reference the MessageBeep routine in the
standard Windows library known as user.
Note that this Declare statement refers to the library name "user" not "user.dll". User is the name
of a standard library that is included as part of Windows; other standard Windows library names
include GDI and Kernel.
After you declare a DLL routine using a Declare substatement, you can use the Call statement to
call the routine the way you would call any sub-procedure:
Call MessageBeep(1)
Some DLL routines have names that cannot be used as legal MapBasic identifiers. For example, a
DLL routine's name might conflict with the name of a standard MapBasic keyword. In this situation,
you can use the Alias keyword to refer to the DLL routine by another name.
The following example shows how you could assign the alias Beeper to the MessageBeep routine
in the User library:
Call Beeper(1)
Note: The name by which you will call the routine—"Beeper" in this example—appears after the
Sub keyword; the routine's original name appears after the Alias keyword.
String Arguments
When calling a DLL routine, a MapBasic program can pass variable-length string variables by
reference. If you are writing your own DLL routine in C, and you want MapBasic to pass a string by
reference, define the argument as char * from your C program.
CAUTION: When MapBasic passes a by-reference string argument, the DLL routine can modify
the contents of the string variable. However, DLL routines should not increase the size
of a MapBasic string, even if the string is declared as variable-length in MapBasic.
A MapBasic program can pass fixed-length string variables by reference or by value. However, if
you pass the argument by value, the DLL routine must interpret the argument as a C structure. For
example, if your MapBasic program passes a 20-character string by value, the DLL could receive
the argument as a structure consisting of five four-byte Integer values.
When a MapBasic program passes a string argument to a DLL, MapInfo Pro automatically includes
a null character (ANSI zero) to terminate the string. MapInfo Pro appends the null character regardless
of whether the MapBasic string variable is fixed-length or variable-length.
If your DLL routine will modify the string argument, make sure that the string is long enough. In other
words, take steps within your MapBasic program, so that the string variable that you pass contains
a sufficiently long string.
For example, if you need a string that is 100 characters long, your MapBasic program could assign
a 100-character string to the variable before you call the DLL routine. The MapBasic function
String$( ) makes it easy to create a string of a specified length. Or you could declare the MapBasic
string variable to be a fixed-length string (for example, Dim stringvar As String * 100 will define a
string 100 bytes long). MapBasic automatically pads fixed-length string variables with spaces, if
necessary, so that the string length is constant.
Array Arguments
MapBasic allows you to pass entire arrays to DLL routines in the same way that you can pass them
to MapBasic sub-procedures. Assuming that a DLL accepts an array as an argument, you can pass
a MapBasic array by specifying the array name with empty parentheses.
User-Defined Types
Some DLLs accept custom data types as parameters. (Use the Type statement to create custom
variable types.) MapBasic passes the address of the first element, and the rest of the elements of
the user-defined type are packed in memory following the first element.
CAUTION: For a DLL to work with custom variable types, the optional Align[n] keyword in the Type
statement may be defined to match the target DLL "structure packing". For example,
using the Microsoft C compiler, you can use the /Zp[n] option to specify the packing.
Logical Arguments
Handles
A handle is a unique integer value defined by the operating environment and used to reference
objects such as forms and controls. Operating-environment DLLs use handles to Windows (HWND),
Device Contexts (hDC), and so on. Handles are simply ID numbers and you should never perform
mathematical functions with them.
If a DLL routine takes a handle as an argument, your MapBasic program should declare the argument
as ByVal Integer.
If a DLL function returns a handle as its return value, your MapBasic program must declare the
function's return value type as Integer.
The following example illustrates calling a DLL. The DLL in this example, "kernel", is a standard
Windows library. This program uses a routine in the kernel library to read a setting from the Windows
configuration file, WIN.INI.
Sub Main
Dim sSection, sEntry, sDefault, sReturn As String
Dim iReturn As Smallint
The Declare Function statement establishes a reference to the kernel library. Note that the library
is referred to as "kernel" although the actual name of the file is krnl386.exe. Windows uses the
correct library if your program refers to "kernel". The kernel library receives special handling because
it is a standard part of the Windows API. If you create your own library, your Declare Function
statements should reference the actual name of your DLL file.
If you use DLLs to store custom ButtonPad icons and/or custom draw cursors, you can use the
same basic technique-calling SystemInfo(SYS_INFO_MIPLATFORM) to determine which DLL to
use. However, the MapBasic syntax is somewhat different: Instead of using a Declare statement,
you reference DLL resources (bitmap icons and cursors) by including a File clause in the Create
ButtonPad statement, as shown in the following example.
Sub Main
Dim s_dllname As String
s_dllname = getDLLname()
Sub DoIt
'this procedure called if the user
'uses the custom button...
End Sub
See Creating Custom Button Icons and Draw Cursors for a discussion of creating custom
ButtonPad icons.
The following tips may help if you are having trouble creating your own DLLs.
• If you are using C++ to create your own DLLs, note that C++ compilers sometimes append extra
characters to the end of your function names. You may want to instruct your C++ compiler to
compile your functions as "straight C" to prevent your function names from being changed.
• The Microsoft 32-bit C compiler provides three calling conventions: Standard (keyword "__stdcall"),
C (keyword "__cdecl") and fast call (keyword "__fastcall"). If you are creating DLLs to call from
MapBasic, do not use the fast call convention.
• If you are having trouble passing custom MapBasic data types (structures) to your DLL, make
sure that your C data structures are "packed" to one-byte boundaries, as discussed above.
• MapBasic can pass arguments by reference (the default) or by value. Note, however, that passing
arguments by value is not standardized among compilers; for example, different compilers behave
differently in the way that they process C-language doubles by value. Therefore, you may find it
more predictable to pass arguments by reference. When you pass an argument by reference, you
are passing an address; the major compilers on the market are consistent in their handling of
addresses.
• It is good programming to make your DLLs "self-contained." In other words, each DLL routine
should allocate whatever memory it uses, and it should free whatever memory it allocated.
• It is important to set up your MapBasic Declare statement correctly, so that it declares the arguments
just as the DLL expects the arguments. If a DLL routine expects arguments to be passed by value,
but your program attempts to pass the arguments by reference, the routine may fail or return bad
data.
The MapBasic language lets you control and customize MapInfo Pro's ButtonPads, which are an
important part of MapInfo Pro's user interface. For an introduction to how MapBasic can control
ButtonPads, see Creating the User Interface.
A small picture (an icon) appears on each button. You may want to create your own custom icons
to go with the custom buttons that you create. The process of creating custom icons varies from
platform to platform. On Windows, custom ButtonPad icons are stored as BMP resources in DLL
files.
A MapBasic program also can use custom cursors (the shapes that moves with the mouse as you
click and drag in a Map or Layout window). This section discusses the process for creating custom
cursors for Windows.
Before you go about creating your own custom button icons, take a moment to familiarize yourself
with the icons that are built into MapInfo Pro. Starting with version 4.0, MapInfo Pro includes a wide
assortment of custom icons. These icons are provided to make it easier for MapBasic developers
to create custom buttons.
To see a demonstration of the built-in icons, run the sample program Icon Sampler
(ICONDEMO.MBX). The following picture shows one of the ButtonPads created by the Icon Sampler.
Each of the icons built into MapInfo Pro has a numeric code. For a listing of the codes, see
ICONS.DEF. To see an individual button's code, run ICONDEMO.MBX, and place the mouse cursor
over a button; the button's ToolTip shows you the button's code.
If none of MapInfo Pro's built-in icons are appropriate for your application, you will want to create
custom icons, as described in the following pages.
Custom Icons
To create custom icons for MapInfo Pro, you need a resource editor. The MapBasic development
environment does not include its own resource editor; however, MapBasic programs can use the
resources that you create using third-party resource editors. For example, you could create custom
icons using AppStudio (the resource editor that is provided with Microsoft Visual C).
On Windows, custom icons are stored in a DLL file. Before you begin creating custom icons, you
should develop or acquire a DLL file where you intend to store the icons. This DLL file can be a
"stub" file (such as a file that does not yet contain any useful routines).
You must create two bitmap resources for each custom icon. The first bitmap resource must be 18
pixels wide by 16 pixels high; this is the icon that will appear if the user does not check the Large
Buttons check box in MapInfo Pro's Toolbar Options dialog box. The second bitmap resource must
be 26 pixels wide by 24 pixels tall; this is the icon that will appear if the user does check the Large
Buttons check box. You must create both resources.
The process of creating custom bitmaps involves the following steps:
• Acquire or develop the DLL file where you will store your custom icons.
• Edit the DLL using a resource editor, such as AppStudio.
• For each icon you wish to create, add two bitmap (BMP) resources: one bitmap that is 18 wide
by 16 high, and another bitmap that is 26 wide by 24 high (in pixels). (You must create bitmap
resources, not icon resources.)
• Assign sequential ID numbers to the two bitmap resources. For example, if you assign an ID of
100 to the 18 x 16 bitmap, assign an ID of 101 to the 26 x 24 bitmap.
Once you have created the pair of bitmap resources, you can incorporate your custom bitmaps
into your MapBasic application using either a Create ButtonPad or an Alter ButtonPad statement.
In your program, refer to the ID of the smaller (18 x 16) bitmap resource. For example, if you
assigned the IDs 100 and 101 to your bitmap resources, your program should refer to ID 100, as
shown in the following statement:
The DLL file where you store your custom icons (in this example, MBICONS1.DLL) must be installed
on your user's system, along with the .MBX file. The DLL file can be installed in any of the following
locations:
• The directory where the .MBX file is located;
• the directory where the MapInfo Pro software is installed;
• the user's Windows directory;
• the system directory within the Windows directory;
• or anywhere along the user's search path.
If you place the DLL in any other location, your MapBasic program must specify the directory path
explicitly (for example, Icon 100 File "C:\GIS\MBICONS1.DLL"). Note that the
ProgramDirectory$( ) and ApplicationDirectory$( ) functions can help you build
directory paths relative to the MapInfo Pro directory or relative to the directory path where your MBX
is installed.
The process of creating custom draw cursors is similar to the process of creating custom icons.
However, draw cursors have some attributes that do not apply to icons (for example, each draw
cursor has a "hot spot").
To create custom draw cursors, use a resource editor to store CURSOR resources in a DLL. You
can store CURSOR resources and BMP resources in the same DLL file.
Inter-Process Communication, or IPC, is the generic term for the exchange of information between
separate software packages. Windows supports IPC through the Dynamic Data Exchange protocol,
commonly known as DDE.
If two Windows applications both support DDE, the applications can exchange instructions and data.
For instance, a DDE-capable Windows package, such as Microsoft Excel, can instruct MapInfo Pro
to carry out tasks (for example, Map From World).
A DDE conversation is a process that can take place between two Windows applications. Both
applications must be running, and both must support DDE conversations. A single DDE conversation
can involve no more than two applications; however, MapInfo Pro can be involved in multiple
conversations simultaneously.
In a conversation, one application is active; it begins the conversation. This application is called the
client. The other, passive application is called the server. The client application takes all initiative;
for instance, it sends instructions and queries to the server application. The server reacts to the
instructions of the client.
The MapBasic language supports the following statements and functions that allow a MapBasic
application to act as the client in a DDE conversation.
MapBasic Action
Statement or
Function
DDETerminateAll Closes all DDE conversations which were opened by the same MapBasic program.
Refer to the MapBasic Reference or MapBasic Help for detailed information on these statements
and functions.
To initiate a DDE conversation, call the DDEInitiate( ) function. DDEInitiate( ) takes two parameters:
an application name, and a topic name.
Typically, the application parameter is the name of a potential server application (for example, Excel
is the DDE application name of Microsoft Excel). The list of valid topic parameters varies depending
of the application. Often, the topic parameter can be the name of a file or document currently in use
by the server application.
For instance, if Excel is currently editing a worksheet file called TRIAL.XLS, then a MapBasic
application can initiate a conversation through the following statements:
In this example, Excel is the application name, and TRIAL.XLS is the topic name.
Many DDE applications, including MapInfo Pro, support the special topic name System. You can
use the topic name System to initiate a conversation, then use that conversation to obtain a list of
the available topics.
Each DDE conversation is said to take place on a unique channel. The DDEInitiate( ) function returns
an integer channel number. This channel number is used in subsequent DDE-related statements.
Once a conversation has been initiated, the MapBasic application can send commands to the server
application by issuing the DDEExecute statement. For instance, a MapBasic application could
instruct the server application to open or close a file.
A MapBasic application can request information from the server application by calling the
DDERequest$( ) function. When calling DDERequest$( ), you must specify an item name. A DDE
item name tells the server application exactly what piece of information to return. If the server
application is a spreadsheet, the item name might be a cell name.
Use the DDEPoke statement to send information to the server. Generally, when a MapBasic
application pokes a value to the server application, the value is stored in the appropriate document,
as if it had been entered by the user. The following example shows how a MapBasic program can
store the text "NorthEast Territory" in a cell in the DDE server's worksheet.
Once a DDE conversation has completed its task, the MapBasic (client) application should terminate
the conversation by issuing a DDETerminate or DDETerminateAll statement. DDETerminate closes
one specific DDE conversation; DDETerminateAll closes all open DDE conversations that were
opened by that same application. Multiple MapBasic applications can be in use at one time, with
each application conducting its own set of DDE conversations.
When a MapBasic application acts as a DDE client, the application may generate runtime errors if
the server application "times-out" (does not respond to the client's actions within a certain amount
of time).
MapInfo Pro stores the time-out setting in the Windows registry For more details about how MapInfo
Pro stores settings in the registry, search for "registry" in the MapBasic Help index.
MapInfo Pro acts as the server when another Windows application initiates the DDE conversation.
This allows the client application to read from MapBasic global variables and even poke values into
MapBasic global variables. The DDE client can also perform execute operations to run MapBasic
statements; for example, the client could use DDE execute functionality to issue a MapBasic Map
statement. (However, the client cannot issue MapBasic flow-control statements.)
Other software packages do not necessarily provide the same set of DDE statements that MapBasic
provides. While MapBasic provides a DDEPoke statement, other packages may provide the same
functionality under a different name. To learn what DDE statements are provided by a particular
Windows application, refer to the documentation for that application.
Any application that acts as a DDE client must address the three basic DDE parameters: application,
topic, and item.
Application name: Specify MapInfo Pro as the application name to initiate a DDE conversation with
MapInfo Pro as the server.
Topic name: Specify System or specify the name of a MapBasic application that is currently running
(for example, SCALEBAR.MBX).
Item name: The item name that you specify depends on the topic you use. If you use MapInfo Pro
as the application name and System as the topic name, you can use any item name from the table
below.
The following table shows the actions and items supported by a DDE conversation with Application
as MapInfo and Topic as System.
Peek request "SysItems" MapInfo Pro returns a TAB-separated list of item names accepted under the
System topic.
Topics SysItems Formats Version
Peek request "Topics" MapInfo Pro returns a TAB-separated list of currently available topics (System,
and the names of all running MapBasic applications).
Peek request "Formats" MapInfo Pro returns a list of all Clipboard formats supported by MapInfo Pro
(TEXT).
Peek request "Version" MapInfo Pro returns a text string representing the MapInfo Pro version number,
multiplied by 100. For example, MapInfo Pro 12.0 returns "1200". See example
below.
Peek request A MapBasic MapInfo Pro interprets the string as a MapBasic expression and returns the
expression value as a string. If expression is invalid, MapInfo Pro returns an error. This
functionality applies to MapInfo Pro 4.0 and higher.
Execute A text message MapInfo Pro tries to execute the message as a MapBasic statement, as if the
user had typed the statement into the MapBasic window. The statement cannot
contain calls to user-defined functions, although it can contain calls to standard
functions. The statement cannot reference variables that are defined in compiled
applications (.MBX files). However, the statement can reference variables that
were defined by executing Dim statements into the MapBasic window.
For example, the following MapBasic program—which you can type directly into the MapBasic
window—conducts a simple DDE conversation using "MapInfo" as the application and "System" as
the topic.
The DDEInitiate( ) function call initiates the DDE conversation. Then the DDERequest$( ) function
performs a peek request, using "Version" as the item name.
If you use the name of a running MapBasic application (for example, C:\MB\SCALEBAR.MBX, or
SCALEBAR.MBX, or SCALEBAR) as the DDE topic name, you can use any item name from the
table below.
The following table shows the actions and items supported by a DDE conversation with Application
as MapInfo and Topic as the name of a running MapBasic application.
Peek request "{items}" MapInfo Pro returns a TAB-separated list of the global variables defined by the
running application. See example below.
Peek request The name of a MapInfo Pro returns a string representing the value of the variable.
global variable
Peek request A string that is not If the MapBasic application has a function called
the name of a RemoteQueryHandler( ), MapInfo Pro calls the function. The function
global variable can determine the item name by calling CommandInfo(CMD_INFO_MSG).
Poke The name of a MapInfo Pro stores the new value in the variable.
global variable
Execute A text message If the MapBasic application has a procedure called RemoteMsgHandler,
MapInfo Pro calls the procedure. The procedure can determine the text message
by calling CommandInfo(CMD_INFO_MSG).
For example, the following MapBasic program—which you can type directly into the MapBasic
window—conducts a simple DDE conversation using SCALEBAR.MBX as the topic. This conversation
prints a list of the global variables used by SCALEBAR.MBX.
Note: This conversation will only work if the application SCALEBAR.MBX is already running.
There are two ways that the client application can send MapInfo Pro an execute message:
• When a conversation uses "System" as the topic, and the client application sends an execute
message, MapInfo Pro tries to execute the specified message as a MapBasic statement.
• When a conversation uses the name of a MapBasic application as the topic, and the client sends
an execute message, MapInfo Pro calls the application's RemoteMsgHandler procedure, which
can then call CommandInfo( ) to determine the text of the execute message.
A MapBasic application can act as the client in one DDE conversation, while acting as the server
in another conversation. A MapBasic application can initiate a conversation with another MapBasic
application, or with MapInfo Pro itself.
Many MapBasic programmers use Microsoft's Visual Basic language to enhance their MapBasic
applications. You might use Visual Basic to create elaborate dialog boxes that would be difficult to
create using the MapBasic Dialog statement. For example, a Visual Basic program can create
custom controls that are not available through MapBasic's Dialog statement.
MapBasic applications can communicate with Visual Basic applications using DDE (or using OLE
Automation). For more information about communicating with Visual Basic applications, see
Integrated Mapping.
For an example of using DDE to read and write values of cells in a Microsoft Excel worksheet, see
DDEInitiate( ) in the MapBasic Reference or MapBasic Help.
The sample program, AppInfo (APPINFO.MBX), provides a more complex DDE example. The
AppInfo program is a debugging tool. If you run your MapBasic application, and then you run AppInfo,
you can use AppInfo to monitor the global variables in your MapBasic program. The WhatApps( )
procedure queries the DDE item name "Topics" to retrieve the list of running MBX files. The
WhatGlobals( ) procedure conducts another DDE conversation, using the "{Items}" item name
to retrieve the list of global variable names.
When MapInfo Pro acts as a server in a DDE conversation, the conversation can support both warm
and hot advise links. In other words, when a Windows application initiates a DDE conversation that
monitors the values of MapBasic global variables, Windows is able to notify the DDE client when
and if the values of the MapBasic global variables change.
When a MapBasic application acts as a client in a DDE conversation, there is no mechanism for
creating an advise link.
If you are developing a complex application, you may want to develop help file that explains the
application. To create a help file, you need a help compiler. The MapBasic development environment
does not include a help compiler. However, if you already own a Windows help compiler, and you
use it to create a Windows help file, you can control the help file through a MapBasic application.
Note: Pitney Bowes Inc. Technical Support staff cannot assist you with the creation of on-line help
files.
Within your program, you can control the Help window by using the Open Window, Close Window,
and Set Window statements. The following statement opens the Help window, showing the Contents
screen of the MapInfo Pro Help file:
The Set Window statement has many uses; see the MapBasic Reference for details. Most forms of
the Set Window statement require an Integer window identifier, but if you specify the Help keyword,
you should omit the Integer identifier-there is only one Help window.
If you create a custom help file, and call the file Dispatch.hlp, the following statement displays your
help file in the Help window:
The following statement sets the Help window so that it displays the help that has 500 as its context
ID number:
Context ID numbers (such as 500 in the preceding example) are defined in the [MAP] section of a
help file's Project file (for example, filename.hlp). For more information about the architecture of a
Windows help file, see the documentation for the Windows Software Developers Kit (SDK).
If you want to provide a help screen for a specific dialog box in your application, place a button
control in the dialog box, and assign the button a title called "Help."
Control Button
Title "Help"
Calling show_help_sub
Assign the Help Button control a handler procedure, and have the handler procedure issue a Set
Window statement. The user will be able to obtain help for the dialog box by clicking the Help button.
For more information about assigning handler procedures to dialog box controls, see Creating the
User Interface.
In this section
What Does Integrated Mapping Look Like? 255
Conceptual Overview of Integrated Mapping 256
Technical Overview of Integrated Mapping 257
A Short Sample Program: "Hello, (Map of) World" 257
A Closer Look at Integrated Mapping 259
OLE Automation Support 263
MapInfo Pro Command-Line Arguments 263
Integrated Mapping
You control the appearance of the Integrated Mapping application. If you want, you can create a
user interface that is radically different from the MapInfo Pro user interface. For example, the following
picture picture shows the WPF Integrated Mapping sample application (a sample WPF application
that integrates a MapInfo Pro Map window into a WPF Window).
When you integrate a map into your program, the user sees a genuine MapInfo Pro Map window―not
a bitmap, metafile, or any other type of snapshot. You can allow the user to interact with the map
(for example, using the Zoom tools to magnify the map). An integrated Map window has all of the
capabilities of a Map window within MapInfo Pro.
Note: When the user runs an Integrated Mapping application, the MapInfo Pro "splash screen"
(the image that ordinarily displays while MapInfo Pro is loading) does not appear.
To create an Integrated Mapping application, you write a program―but not a MapBasic program.
Integrated Mapping applications can be written in several languages. The most often-used languages
are C# and VB.Net. The code examples in this chapter use C#.
To get started with custom integrated mapping application client, you need two interfaces
IIntegratedMappingApplication and IMapInfoApplication. Create a class implementing
IIntegratedMappingApplication interface, this could be your WPF application MainWindow class. In
the main method of your application call MapInfoCore.StartUp() method to initialize the core
components of MapInfo. Then to get access to events and other internal functionalities of MapInfo
call MapInfoCore.Initialize(instance of application window, Instance of IIntegratedMappingApplicatio).
This will return you instance of IMapInfoApplication interface which would allow you to get access
to events and other stuff.
Your program manipulates MapInfo Pro by calling functions on IIntegratedMappingApplication
interface.
If you want to open a Map window, use MapBasic's Map From statement, just as you would in a
conventional MapBasic program. But in an Integrated Mapping application, you need to handle the
IIntegratedMappingApplication.WindowCreated() function.
System Requirements
• Integrated Mapping requires MapInfo Pro 12.5.1 or later. You may use a full copy of MapInfo Pro
or MapInfo Runtime, which is a very basic version of MapInfo Pro that is sold only as a base for
custom applications.
• Your user's computer must have enough free memory and system resources to run both your
client program and MapInfo Pro simultaneously.
• Your client program must be able to create a user-interface element (for example, a window, form,
or control) as a place-holder for where the map will go. Your client program must also be able to
determine the Windows HWND value of the user-interface element.
The following WPF example will give you a sense of how to integrate MapInfo Pro windows into
another application. And this sample uses WPF ribbon to access the commands.
Create a new C# WPF project. Refer following dll files:
1. MapInfo.Application
2. MapInfo.Controls
3. MapInfo.StyleResources
4. MapInfo.Types
5. Miadm
6. System.Windows.Controls.Ribbon
Add the following section to "app.config" under configuration section.
<runtime>
<appDomainManagerType
value="MapInfo.MiPro.Interop.ProAppDomainManager" />
<appDomainManagerAssembly value="miadm, Version=[miadm version],
Culture=neutral, PublicKeyToken=1c8d81d2ee78b75d" />
</runtime>
try
{
//Call to set your main application window into the MapInfo Application
and get access to the interface to control MapInfo and listen to events.
MyRibbon.CommandBindings.AddRange(Application.InitializeCommandBindings(null,
null));
<RibbonButton x:Name="OpenTable"
Margin="4,0,0,0"
DataContext="{x:Static cmds:ApplicationCommands.OpenTable}"
Command="cmds:ApplicationCommands.OpenTable"
Label="{Binding Path=Text}"
SmallImageSource="{Binding Path=SmallIcon}"
LargeImageSource="{Binding Path=LargeIcon}"
ToolTipDescription="{Binding Path=ToolTipText}"
ToolTipTitle="{Binding Path=ToolTipDescription}"
ToolTipService.ShowOnDisabled="True" >
<RibbonButton.ControlSizeDefinition>
For further details, refer IntegratedMappingWPF sample application under samples\dotnet folder.
The following section explains how to integrate elements of MapInfo Pro into a WPF application.
This discussion is written with two assumptions:
• You should already understand the basic terms and concepts of WPF programming. For background
information on the concepts of WPF programming, see the documentation for your programming
language.
• You should already know how to program in WPF, because the code examples in this discussion
use WPF syntax.
<runtime>
<appDomainManagerType
value="MapInfo.MiPro.Interop.ProAppDomainManager" />
<appDomainManagerAssembly value="miadm, Version=[miadm version],
Culture=neutral, PublicKeyToken=1c8d81d2ee78b75d" />
</runtime>
This will allow MapInfo Pro core to be loaded into separate app domain.
To access the MapInfo instance you need to call following method in application load event.
The above call set your main application window into the MapInfo Application and get access to the
interface to control MapInfo and listen to events.
Application.Events.ConfigureStatusField += <Your_EventHandler>;
Application.Events.StatusFieldTextChanged += <Your_EventHandler>;
The following code snippet shows how to handle new mapper window and display as child control
in TabPage.
Tag = wi.WindowId,
};
}
The following code snippet shows how to manage the tab show and hide behavior.
tab.Visibility = Visibility.Collapsed;
}
}
else
{
// Show window and make it active.
if (tab.Visibility == Visibility.Collapsed)
{
tab.Visibility = Visibility.Visible;
SetActiveWindow(window);
}
}
}
}
The following functions allow client apps to manage window close behavior and resource
management.
CommandBindingCollection
InitializeCommandBindings(ExecutedRoutedEventHandler exec,
CanExecuteRoutedEventHandler canExec);
CommandBindings.AddRange(Application.InitializeCommandBindings(null,
null));
MyRibbon.CommandBindings.AddRange(Application.InitializeCommandBindings(null,
null));
After launching MapInfo Pro, construct text strings that represent MapBasic statements. For example,
if you want MapInfo Pro to execute a MapBasic Open Table statement, you might construct the
following string (within C#):
Application.EvalMapBasicCommand(msg)
When you use the EvalMapBasicCommand method, MapInfo Pro executes the command string as
if you had typed the command into the MapBasic window.
To query the value of a MapBasic expression, construct a string that represents the expression. For
example, if you want to determine the value returned by the MapBasic function call WindowID(0),
construct the following string (within WPF):
When you use the EvalMapBasicCommand method, MapInfo Pro interprets the string as a MapBasic
expression, determines the value of the expression, and returns the value, as a string.
Note: If the expression has a Logical value, MapInfo Pro returns a one-character string, "T" or "F".
Ensure that you close all tables before the Integrated Mapping application exits.
You can use MapInfo Pro's COM API for OLE automation.
Note: COM GUID for MapInfo Pro 64-bit is MapInfo.Application.x64.
This version of MapBasic supports only 2 methods for OLE automation: DO and EVAL.
If you use DDE to communicate with MapInfo Pro, you will need to launch MapInfo Pro manually
(for example, by calling Visual Basic's Shell() function) before you establish the DDE connection.
When you launch MapInfo Pro, you can use any of the command-line arguments listed below. If
you want the user to remain unaware that MapInfo Pro is running, you will want to specify one of
the following arguments.
-nosplash
MapInfo Pro runs without showing its splash screen, although the main MapInfo Pro
window still shows.
-noautoload
MapInfo Pro starts without loading the startup.wor, mapinfow.wor, and any MapBasic
tool marked for auto loading.
-server
MapInfo Pro runs without showing a splash screen or main window. Use this argument
when you want MapInfo Pro to act as a behind-the-scenes server to another application
(using DDE).
-automation or -embedding MapInfo Pro runs without displaying a splash screen or main window. Additionally,
MapInfo Pro registers its OLE Class Factory with the OLE subsystem, which allows
MapInfo Pro to act as a behind-the-scenes OLE server to another application.
-regserver
MapInfo Pro registers its OLE capabilities in the registration database, then exits. Run
MapInfo Pro with this argument once, when you install MapInfo Pro. Note that MapInfo
Pro automatically registers itself when it is run normally. Note very well that this
registers everything about the MapInfo product: OLE Automation, OLE Embedding,
etc.
-unregserver
MapInfo Pro removes all references to itself from the registration database and exits.
Use this option at uninstall time to remove MapInfo Pro from the system registry. Using
this argument unregisters everything that the -regserver option registered.
-embedding
MapInfo Pro activate as an OLE Server.
-helpdiag
This argument sets a flag in MapInfo Pro, so that MapInfo Pro displays a diagnostic
dialog box every time you press F1 for MapInfo Pro Help.
-d
MapBasic only. Opens as a small symbol or graphic, not an integrated development
environment (IDE) window, and takes the remaining arguments as MapBasic files
(*.mb) to compile.
-l
MapBasic only. Opens as a small symbol or graphic, not an integrated development
environment (IDE) window, and takes the remaining arguments as MapBasic files
(*.mbo) to link.
-utf8 MapBasic only. MapBasic is set to compile MapBasic (*.mb) programs and link
MapBasic (*.mbo) modules in a Project (*.mbp) file using UTF-8 charset instead of
current system character set for unicode support.
Note: The forward slash ("/") can be used instead of the minus sign.
The following command-line arguments let you work silently with the MapInfo Pro license.
-activatelicense
Silently activate a node locked or permanently borrowed license. You can specify a
path and log file name after this command (-activatelicense "C:\path\logfile.txt"). If not
specified, the log file saves as BorrowLicense.log to the your temporary folder
(C:\Users\UserName\AppData\Local\Temp for example).
-borrowlicense
Silently borrow a license from a license server. You can specify a path and log file
name after this command (-borrowlicense "C:\path\logfile.txt"). If not specified, the log
file saves as BorrowLicense.log to the your temporary folder
(C:\Users\UserName\AppData\Local\Temp for example).
-licensetransfer
Silently transfer a node-locked license to the Pitney Bowes FNO Server, or transfer
a borrowed or distributed license to your License Server. You can specify a path and
log file name after this command (-licensetransfer "C:\path\logfile.txt"). This command
opens a window on the screen.
-returnlicense
Silently return a node-locked license to the Pitney Bowes FNO Server, or return a
borrowed or distributed license to your License Server. You can specify a path and
log file name after this command (-returnlicense "C:\path\logfile.txt").
In this section
Introduction and Requirements for .Net Programming 267
Getting Started 267
Working with Structures in .Net 273
Exception Handling 277
Working with the GAC 278
Controlling MapInfo Pro from Within a .Net Method 279
Integrated Mapping in .Net 281
Working with .Net
This chapter assumes that you are already somewhat familiar with how to write code in .Net. In
particular, you should already understand how to define a class in .Net, how to give your class a
constructor, and how to build a project using Microsoft's Visual Studio development environment
for .Net.
You must use MapInfo Pro and MapBasic version 10 or higher to call .Net routines from MapBasic.
The .Net version 3.5 framework or higher must be installed on the computer where you will run the
MapBasic application (.mbx) file; however, you can assume that the .Net framework is already
present on any system where MapInfo Pro 10 or higher is running, since the MapInfo Pro installer
will install the framework if it is not already present.
Code samples in this chapter are provided in VB.Net and C#. The examples in this chapter were
written using Visual Studio 2005.
Terminology
In this chapter, the term method refers to any sub or function routine written in .Net. For example,
a Sub routine written in VB is one type of method, while a Function written in VB is another type of
method. Both types of methods can be called from MapBasic.
Some methods can be called without first creating an instance of the class. C# programmers refer
to these methods as static methods, while VB.Net syntax refers to them as shared functions. In this
chapter, we will use the term static method to refer to a method that can be called without first
creating an instance of the class.
Getting Started
This section provides a simple example of how to create a class in .Net, and use the class from
MapBasic.
Calling a .Net method from MapBasic involves six basic steps:
1. Create a class in .Net, containing one or more static methods
2. Build the .Net class into an assembly
3. Make the assembly available to the MapBasic application
4. Add a Declare Method statement to the .MB program
5. Call the method that you declared in the Declare Method statement
6. Compile and run your MapBasic application.
You can start by defining a class in .Net. The class can be very simple. The main requirement is
that the class must contain at least one static method. MapBasic programs can only call .Net methods
that are static.
The following example shows a simple class, with one static method that displays a greeting in a
dialog box. This method takes one String argument, and returns an integer value (indicating the
number of characters in the String).
If you write this class in C#, the code looks like this:
using System;
using System.Windows.Forms;
namespace MapBasicMethods
{
public class Demo
{
public static int SayHello(String strName)
{
MessageBox.Show("Hello, " + strName);
return strName.Length;
}
}
}
Much of the code in this example was generated by Visual Studio, so there is little code that you
have to type in by hand. When you create a new project in Visual Studio, choose the project template
that lets you define a new Class Library, and Visual Studio will generate much of the needed code.
This same class, written in VB, might look like this:
Namespace MapBasicMethods
End Class
End Namespace
Note: This VB example declares the namespace explicitly, in the source code. Your VB project
might not have the Namespace declaration in the source code if you have a Root Namespace
set in your VB project properties.
The SayHello method uses the .Net MessageBox class to display a dialog box such as this:
Since this sample uses the MessageBox class, the project depends on a standard assembly,
System.Windows.Forms. If you type in this example yourself, you may need to add a Reference to
the System.Windows.Forms assembly to your Visual Studio project.
Once you have written your class, you use Visual Studio to build the class into a .exe or .dll file.
You will need to make your assembly available to your MapBasic application. The simplest way to
do this is to copy the assembly (.dll) file to the directory where the .MBX file resides in the directory
from where you will run the .MBX. Alternatively, rather than copy the assembly to the .MBX directory,
you could instead register the assembly in the .Net Global Assembly Cache (GAC). To register your
assembly, use the gacutil utility provided by Microsoft; for details, see the .Net documentation from
Microsoft.
Note: MapInfo Pro allows you to run a .MBX application from a network location, such as a UNC
path. However, the default .Net Framework security settings do not allow loading a .Net
assembly from the network. If you call your own .Net assembly from your MapBasic
application, consider installing your application files on client machines, rather than having
the client machines access the files via a network. Otherwise you will have to modify the
security settings through the .Net Framework Configuration utility found in Control
PanelAdministrative Tools. The exact steps to change the security settings are beyond the
scope of this documentation.
Now that you have a static method, in a class, in a .Net assembly, you can call that method from
MapBasic.
Before you call the .Net method from MapBasic, you must add a Declare Method statement to your
.MB program. The Declare Method statement is very similar to the Declare Function statement, but
it includes additional syntax to let you specify the assembly and class name of your .Net class.
For details about the Declare Method syntax, see the MapBasic Help. The following example shows
how you might declare the SayHello method from the example above.
In this example, we will call the method by its actual name, SayHello. (You could refer to the method
with an alias, using the Alias clause; but for this simple example, it is not necessary to use an alias.
You only need to use the Alias clause when you need to differentiate multiple functions that have
the same name.)
The Class clause specifies the class name as MapBasicMethods.Demo because our source code
specified that MapBasicMethods is the namespace, and Demo is the class name.
The Lib clause specifies the name of the assembly file as MBMethods.dll your assembly name will
depend on your project settings in Visual Studio.
The argument list matches the argument list of the .Net method: one by-value String argument.
The return type matches the return type of the .Net method. The MapBasic "Integer" type is a 4-byte
integer, which is equivalent to the C# "int" type (also known as System.Int32).
Once your Declare Method statement is in place, you can call your .Net method just as you would
call any other MapBasic function. For example:
If your .Net method does not have a return value (i.e. it is a Sub rather than a Function, or it is a C#
void method), or if you simply want to ignore the return value, omit the final As clause from the
Declare Method statement. For example:
Sub Main
Call SayHello("Fred")
End Sub
Compile and run the MapBasic program. When your .MBX calls the SayHello method, your .Net
assembly is loaded and your static method is called.
Note that if your Declare Method statement contains errors (such as misspelling the Class name),
your MapBasic program may still compile, but the method call will fail when you try to run your .MBX.
Your assembly name, class name, method name and method argument list are not validated until
you actually call the method at run-time.
If the method name that you specify in a Declare Method statement is the same as one of the existing
Function or Sub routine names in your MapBasic program, your program will not compile, because
a MapBasic program cannot allow multiple routines to use the same name. To correct this error,
add the Alias clause to the Declare Method statement. Within the Alias clause, you specify the .Net
method's original name; then, you change the fname argument―the argument that follows the
Method keyword―to be a unique name (i.e. a function name that is not already in use). In the
following example, we call a .Net method that is defined with the name "ShowDialog", but within the
.MB source code, we call the method by the name "ShowPointDialog":
Dim i As Integer
i = ShowPointDialog()
Some MapBasic variable types, such as Pen and Brush, cannot be passed to a .Net method. The
following table summarizes how MapBasic variable types correspond to .Net data types.
Arguments can be array types. For example, if your .Net method takes an argument that is an array
of Integer values, the Declare Method statement might look like this:
Arguments can be passed by-reference or by-value. The syntax for specifying by-ref vs. by-val
varies from language to language. The following table demonstrates how you might pass String
arguments by-val vs. by-ref in various cases.
Note: You cannot resize a MapBasic array variable within your .Net method.
Note: MapBasic can only pass array arguments and structure arguments ByRef.
Performance Notes
The speed of calling a .Net method depends on how much data you pass via the argument list. The
more data you pass as arguments, the longer the call will take.
If you find that the execution speed of calling .Net methods is not satisfactory, try to minimize the
amount of data that you pass via the argument list.
MapBasic programs can pass structures (custom variable types created using the Type statement)
to .Net, but some restrictions apply, and you need to do some additional work in .Net―namely,
creating an appropriate Class definition in .Net to represent the structure.
When you want to pass a MapBasic structure to a .Net method, you must do the following in your
.MB code:
1. Use the MapBasic Type statement to define your MapBasic structure. (If you want to pass a
structure to .Net then you have probably already done this.)
2. Use the Declare Method statement to describe a .Net method signature, and include your
MapBasic Type in the method argument list.
3. Declare a variable of your structure type, and assign its field values.
4. Call the method, and pass the structure variable to the method call.
The following MapBasic code defines a structure type with 3 fields, then passes that structure type
to a .Net method.
Note: The Type statement must come before the Declare Method statement, because the Type
name (in this example, ParcelInfo) is used within the Declare Method statement.
Type ParcelInfo
idnum As Integer
descript As String
area As Float
End Type
Call ShowParcelDialog( p )
End Sub
In this example we are passing a ParcelInfo data structure to a .Net method. The next question is:
how should the .Net method be written, so that it will be able to receive the data sent from MapBasic?
When a .Net method needs to receive structure information sent from MapBasic, you need to do
the following:
1. Define a Class in .Net.
2. Give your Class a public constructor, and give this constructor an argument list that matches the
fields in your MapBasic structure. For example, if your MapBasic structure contains an integer,
a string, and a floating-point number, then your constructor's argument list must also take an
integer, a string, and a floating-point number. (Your class can also have other constructors, but
MapInfo Pro/MapBasic will ignore those other constructors.)
3. Somewhere in one of your .Net classes, write a public static method (the method that you will
call from MapBasic). Add an argument to this method, and define the argument type as the Class
you created in step 1.
The following C# code sample demonstrates how to create a Parcel class that corresponds to the
ParcelInfo structure described above:
Having defined the Parcel class, you can now define a public static method that takes an argument
of type Parcel.
Now your MapBasic program can pass a ParcelInfo structure to the ShowParcelDialog method.
While your MapBasic program sends a structure to the method call, the ShowParcelDialog method
receives an object of the appropriate type; MapInfo Pro converts the structure to the appropriate
.Net type, so that the method call can be performed. (This is why you are required to put a public
constructor on your .Net class―MapInfo Pro needs the public constructor so that it can convert the
MapBasic data structure into an appropriate type of .Net object.)
When you pass a MapBasic structure to your .Net method, the call succeeds only if the argument's
.Net class has a public constructor with arguments that match the fields in the MapBasic structure.
If no such constructor exists, your MapBasic program will produce a run-time error when it attempts
to call the method. Note that this is a run-time error condition; the MapBasic compiler cannot detect
this type of problem at compile-time.
In some cases, you might not start out with an existing MapBasic Type structure as your
"given"―instead, you might start out with a pre-existing .Net method signature. Suppose you want
to call a .Net method that has already been written, and this existing method expects one argument:
a System.Drawing.Point object.
This method's argument does not match any of the standard MapBasic variable types, such as
Integer or String. Therefore, if you want to call this method from MapBasic, you will need to define
a MapBasic structure that approximates the .Net argument type (System.Drawing.Point, in this
case). The following MapBasic example shows the appropriate syntax:
Type Location
ix as Integer
iy as Integer
End Type
loc.iy = 42
Call ShowPointDialog(loc)
In this example, MapInfo Pro will try to convert the MapBasic structure into a .Net
System.Drawing.Point object, by calling a public constructor on the Point class. This conversion
process is similar to what happened in the previous example, with one important difference: In this
case, you did not have to write the .Net Point class, because it already exists―it is a class provided
by Microsoft.
Because the MapBasic Location structure contains two Integer fields, MapInfo Pro will try to find a
public constructor on the Point class that takes two integers. The fields from the MapBasic structure
are passed to the .Net constructor, thus creating a .Net Point object. The Point object is passed to
the method to complete the call.
Some .Net classes do not have public constructors. For example, the System.Drawing.Color structure
does not have public constructors; therefore, it is impossible to define a MapBasic structure that
approximates a System.Drawing.Color object. If you need to pass color information to your .Net
method, give your method separate red, green, and blue arguments. Then, inside your .Net method
you can combine those values to form a .Net Color.
ByRef b As Integer)
Dim c As Color
Dim dlg As ColorDialog
dlg = New ColorDialog
dlg.Color = Color.FromArgb(r, g, b)
If (dlg.ShowDialog = DialogResult.OK) Then
c = dlg.Color
r = c.R
g = c.G
b = c.B
End If
End Sub
In this example we are instantiating objects, such as the ColorDialog, and calling non-static methods
on those objects. As stated earlier, MapBasic programs (.MB source code) can only call static
methods; however, the .Net code that you write inside your static method has no such restriction.
Inside your static method, your .Net code can instantiate objects, and use those objects to call
non-static methods (instance methods).
If you pass MapBasic structures to .Net, you may need to give your .Net methods unique names.
Note that .Net allows a class to have multiple methods with the exact same name (as long as the
argument lists are different); MapBasic, however, is more restrictive. If you pass MapBasic structures
to .Net, and if your .Net class has multiple methods with the same name and the same number of
arguments, then MapBasic might not be able to determine which of the methods you want to call.
In this situation your MapBasic program will produce a run-time error when you attempt to call the
.Net method. The simplest way to resolve this type of ambiguity is to use a unique method name
for any .Net method to which you will be passing a structure.
If you pass a structure to a .Net method, and the .Net method modifies the object passed to it, the
corresponding MapBasic structure is not modified. If you need to have your.Net method update your
MapBasic argument variables, use ByRef scalar variable arguments (such as "ix As Integer") rather
than structures.
Exception Handling
An unhandled exception in a .Net method will cause a runtime error in your MapBasic application
(MapBasic error code 1666). Any unhandled runtime error in a MapBasic application will halt the
.MBX; therefore, you will want to handle all such errors. You can choose whether you prefer to trap
your error conditions in your .Net code, or in your .MB code.
The .Net error handling mechanism (try-catch-finally blocks) is more robust than the error handling
provided in MapBasic. Therefore, it is generally preferable to catch exceptions in your .Net code,
rather than allowing exceptions to propagate to your .MB program. However, if you do not want to
or for some reason cannot catch an exception in your .Net method, you can handle the resulting
runtime error in your .MB program, using MapBasic's OnError statement.
The following code demonstrates the MapBasic error-trapping syntax:
Sub MakeExternalCall
end if
End Sub
The Declare Method statement's Lib clause identifies a .Net assembly. If the assembly file is in the
same directory as the .MBX file, the Lib clause can simply identify the assembly by its file name
(such as mbtools.dll or simply mbtools).
If you are using an assembly that has been registered in the GAC, there is no need to copy the .DLL
file to the same directory as the .MBX file. However, when you reference an assembly from the
GAC, your Lib clause must provide more information, because the GAC might contain more than
one version of an assembly. In this situation, the Lib clause needs to specify a fully-qualified assembly
name.
The following example shows how to reference the System.IO.File.Delete method, which is in
Microsoft's mscorlib assembly:
For more information on registering an assembly in the GAC, or on fully qualified assembly names,
consult the .Net documentation from Microsoft.
The following example demonstrates how to declare methods in assemblies that are registered in
the GAC. Note that when an assembly is loaded from the GAC, the Lib clause must specify a
fully-qualified assembly name. Various utilities exist that can help you to identify an assembly's
fully-qualified name, including the gacutil utility provided by Microsoft as part of Visual Studio.
' Display a .Net MessageBox dialog box with both a message and a
caption:
Call Show("Table update is complete.", "Tool name")
The MapInfo Pro installation includes a .Net assembly, miadm.dll, which supports MapBasic / .Net
interoperability. You may find some of these "interop" methods useful because they allow you to
execute MapBasic statements from within a .Net method.
For example, imagine you have written a .Net Map Properties dialog box that contains various map
options, plus OK, Cancel, and Apply buttons. Suppose the dialog box can be used as follows:
1. Your MapBasic program calls a .Net method to display your .Net dialog box.
2. The user selects various options within the dialog box, then clicks the Apply button to apply the
changes.
3. The MapInfo Pro Map window is updated immediately; however, because the user clicked Apply
(as opposed to OK), the dialog box remains on the .
4. Later, after the user finally dismisses the dialog box, the .Net method returns.
To update a Map window, you use a MapBasic statement such as Set Map. However, in this example,
the Set Map statement needs to be executed from within .Net code, because in this example, we
are updating the map before the .Net method has returned.
MapInfo Pro's COM interface provides a Do method, which allows you to execute MapBasic
statements, and an Eval method, which allows you to retrieve information about the state of MapInfo
Pro. If you have written any Integrated Mapping applications, you are already familiar with the Do
and Eval methods. see Integrated Mapping for more details.
The MapInfo.MiPro.Interop.InteropServices class gives .Net programmers easy access to MapInfo
Pro's Do and Eval methods. The InteropServices class has a MapInfoApplication property that gives
you a reference to the MapInfoApplication object. The MapInfoApplication class, in turn, provides
the Do and Eval methods.
For an example of using Do and Eval, see the Named Views sample application installed with
MapBasic (see Samples\DotNet\NamedViews). The Named Views application calls the Eval method
to determine the window ID of the active Map window:
Similarly, the Named Views application uses the Do method to issue a Set Map statement from
within .Net code:
InteropServices.MapInfoApplication.Do(string.Format(
"Set Map Window {0} Center ( {1}, {2} ) Zoom {3}",
windowId, centerX, centerY, mapperZoom));
Before you can use the MapInfo.MiPro.Interop.InteropServices class, your .Net project must include
a reference to the miadm.dll assembly. The assembly is located in the MapInfo Pro install directory.
Note: If you encounter any errors while building the Named Views sample project, you may need
to re-create the reference in the Visual Studio project, so that it specifies the current location
for the assembly.
The MapInfoApplication class is a wrapper class, which gives .Net programmers easy access to
MapInfo Pro's COM interface. This class is provided as a convenience, so that you may access
methods, properties and events through a standard .Net class, instead of dealing with the COM
interface directly. In addition to providing the Do and Eval methods shown above, the
MapInfoApplication class also provides the properties and events listed below.
MapInfoApplication members
Methods
Do
Executes a MapBasic statement, as if you had typed the statement into the MapBasic window
Eval
Evaluates a MapBasic expression, and returns the result, as a string
Properties
FullName
Gets the full path to the application executable
LastErrorCode
Gets an integer representing the last MapBasic error that occurred during a Do or Eval method call
LastErrorMessage
Gets the error message associated with LastErrorCode
Name
Gets the application name
Version
Gets the version number string, representing the version number, multiplied by 100
Events
MenuItemClick
Occurs when the user selects a custom menu item defined with the syntax: Calling OLE
"MenuItemHandler"
StatusBarTextChanged
Occurs when the MapInfo Pro status bar text changes
WindowContentsChanged
Occurs when the contents of the Map window change (such as when a map is zoomed in or out)
Integrated mapping is an application architecture where you write your own application (the "client"
application), which your users could launch instead of launching MapInfo Pro. Your application
would then launch MapInfo Pro silently, in the background, so that you can display MapInfo maps
within your application's user interface.
The following section describes how to write an integrated mapping application using .Net. For a
general discussion of integrated mapping concepts and rules, see the Integrated Mapping chapter.
The MapBasic installation includes a sample .Net integrated mapping application; see
samples\DotNet\IntegratedMapping. You might find it useful to refer to the sample application as
you read this section.
In an integrated mapping application, you will use MapInfo Pro's COM interface. Before you can do
this, you need to add a Reference in your Visual Studio project:
1. Create a Visual Studio project.
2. In the Solution Explorer window, right-click the References folder and select Add Reference.
Once the _mapInfoApp object is initialized, you can use its Do method to execute MapBasic
statements (which is analogous to typing statements into MapInfo Pro's MapBasic window), or use
its Eval method to retrieve information from MapInfo Pro.
In particular, you will be using the Do method to execute the following MapBasic statements:
1. Set Application Window — this allows you to use MapInfo dialog boxes in your client application.
2. Open Table — this statement opens MapInfo tables.
3. Set Next Document Parent — this statement puts MapInfo Pro into a special state, so that the
next Map window opened will be "re-parented" so that it appears within your client application.
4. Map From — this statement creates a Map window.
The sample application demonstrates the use of these statements; for examples, search the MapForm
class for calls to the Do method.
Callback Methods
In some cases, integrated mapping applications need to provide callback methods. If your application
needs to execute code whenever certain events occur―for example, if you need to execute code
whenever the user alters the map―then you will need to set up a callback method, so that MapInfo
Pro can call your callback method every time that event occurs.
MapInfo Pro will call the following callback methods:
• The WindowContentsChanged method is called by MapInfo Pro whenever the contents of the
Map window change (e.g. when a layer is added or removed).
• The SetStatusText method is called by MapInfo Pro whenever anything happens that would alter
the text on the MapInfo Pro status bar.
• Any custom OLE menu item has a handler method; the name of the handler method is specified
in the client application. The sample application defines one custom OLE menu item and specifies
MenuItemHandler as the handler name. This method name also appears in the MapBasic statement
that defines the custom menu item (the Create Menu statement or the Alter Menu...Add statement).
In the sample application, these callbacks are represented by the IMapInfoCallback interface. The
C# version of the interface, from MapInfoCallback.cs, looks like this:
The Visual Basic version of the interface, from MapInfoCallback.vb, looks like this:
' Method called by MapInfo Pro when the status bar text
changes
Function SetStatusText(ByVal message As String) As Integer
' Method called by MapInfo Pro when user chooses custom OLE
menuitem
Sub MenuItemHandler(ByVal commandInfo As String)
End Interface
The same source code module contains the MapInfoCallback class, which demonstrates how to
implement the IMapInfoCallback interface. Note that the MapInfoCallback class has attributes to
mark the class as COM-visible, so that MapInfo Pro will be able to call the methods. The C# syntax
for the class attributes:
[ClassInterface(ClassInterfaceType.None)]
[ComVisible(true)]
public class MapInfoCallBack : IMapInfoCallback
<ClassInterface(ClassInterfaceType.None)> _
<ComVisible(True)> _
Public Class MapInfoCallBack
Implements IMapInfoCallback
In the same file where the IMapInfoCallback interface is defined, there is a second interface,
ICallbackNotify. Implement this interface in your Windows Forms application. In the sample
application, this interface is implemented in MapForm.cs or MapForm.vb.
Events can cause MapInfo Pro to call the callback (IMapInfoCallback) class, which in turn notifies
the client (ICallbackNotify) class. For a better understanding of how and when the various interface
methods are called, consider the following sequence of events:
1. The user runs the Integrated Mapping client application, which silently launches MapInfo Pro. In
the sample application, this happens in the MapForm.InitializeComObject method. This method
launches MapInfo Pro, instantiates the callback object, and registers the callback object with
MapInfo Pro:
2. The client application calls the MapInfoApplication.Do method to open tables and Map windows.
In the sample application, this happens in the MapForm.NewMap method, which is called when
the user has chosen FileOpen to open one or more .tab files.
3. The user modifies the map in some way. In the sample application, the user can select Layer
Control from the Map window's right-click menu, then use the dialog box to modify the map.
MapInfo Pro manages the Layer Control window.
4. Because the map has been modified, MapInfo Pro notifies the client app by calling the
MapInfoCallback.WindowContentsChanged method.
5. The WindowContentsChanged method calls the MapForm.OnWindowContentsChanged method.
The code to be included in this method will depend on the purpose of the application. For example,
if your application displays information about the map, on the status bar or elsewhere in your
form, then you might want to update your form in the OnWindowContentsChanged method.
6. If the application includes a custom OLE menu item, MapInfo Pro calls the menu item's handler
method whenever the user selects the menu item. In the sample application, the Alter Menu
statement adds an item to the map's context menu, and specifies "MenuItemHandler" as the
handler name. Therefore, if the user selects the custom menu item, MapInfo Pro calls the
MenuItemHandler method, which then calls the MapForm.OnMenuItemClick method. The code
to be included in the OnMenuItemClick method will depend on the purpose of the custom menu
item.
7. Whenever the user does something that would cause MapInfo Pro to modify the text on the status
bar―for example, clicking in the map to make a selection―MapInfo Pro calls the
MapInfoCallback.SetStatusText method. This method calls the
MapForm.OnStatusBarTextChanged method. If you want to make your client application's status
bar look like the MapInfo Pro status bar, you could add code to the OnStatusBarTextChanged
method to update your status bar.
8. On exit, we un-register the callback object. In the sample application, this happens in the
FormClosed method.
{
// Unregister the callback object
MapInfoApp.UnregisterCallback(_callbackObject);
}
The sample application defines one custom OLE menu item. If your application defines multiple
OLE menu items, you can have each menu item call its own designated handler method. Or, you
can have all of your OLE menu items call the same handler method―but, if you do, then you will
need to give each custom menu item an ID number (by including the ID clause in the Create Menu
or Alter Menu...Add statement) so that the handler method can determine which menu item the user
selected.
Note that the MapInfoCallback class is re-usable. You could write several different integrated mapping
applications, and use the same MapInfoCallback class with each of those applications.
To understand the sample MapInfoCallback class, you must first understand how multi-threading
can affect a Windows Forms user interface. When you want to execute code that will manipulate
your Windows Forms user interface―for example, if you want to change the text displayed on the
form's status bar―you must make sure that the code is executing on the same thread that was used
to create the user interface.
It is likely that callback methods will execute on a different thread than the thread that created your
user interface. Therefore, your callback methods must detect and correct any thread safety issues
before executing any code that affects your user interface.
The Windows Forms Control class provides an InvokeRequired property. If InvokeRequired is true,
it indicates that the current thread is not the correct thread for updating the Control, in which case,
you must use the Control.Invoke method to apply any changes to the Control. The Invoke method
ensures that the change is applied on the appropriate thread.
For example, the sample MapInfoCallback.SetStatusText method contains the following code, which
ensures that any changes made to the status bar occur on the appropriate thread:
if (_callbackClient.InvokeRequired)
{
_callbackClient.Invoke(this._onStatusBarTextChangedDelegate, new
Object[] { text });
}
else
{
_callbackClient.OnStatusBarTextChanged(text);
}
Note that we are using the _callbackClient object (an object that implements ICallbackNotify) to
access the InvokeRequired property and the Invoke method. In the sample application, the Form
class serves as the ICallbackNotify object:
In the sample application, the _callbackClient member is a reference to the MapForm. Since the
Form class derives from Control, we are able to call _callbackClient.Invoke.
Note: Do not perform the callback un-register operation in a destructor method, as that method
will probably be called from an incorrect thread.
In this section
Samples\DotNet Directory 288
Samples\MapBasic Directory 288
Samples\RIBBONINTERFACE\DotNet Directory 294
Samples\RIBBONINTERFACE\MapBasic Directory 301
Sample Programs
Samples\DotNet Directory
Samples\DotNet\GoogleConnect Directory
A MapBasic utility to send map views or selections to Google Earth.
Samples\DotNet\HelloWorld Directory
Sample of calling a .Net method from MapBasic (C# and VB.Net versions).
Samples\DotNet\IntegratedMappingWinForms Directory
Integrated Mapping client application written in Windows Forms.
Samples\DotNet\IntegratedMappingWinFormsVB Directory
Integrated Mapping client application written in Windows VB Forms.
Samples\DotNet\IntegratedMappingWpf Directory
Integrated Mapping client application written in WPF.
Samples\DotNet\NamedViews Directory
Named Views MapBasic tool, which uses .Net for managing XML files and dialog boxes (C# and
VB.Net versions). The Named Views application lets you define named views, which act as bookmarks
that let you return to that map view at a later time.
Samples\MapBasic Directory
The Samples\MapBasic\ directory contains subdirectories that include sample program files. The
contents of each subdirectory is described in the following sections.
Samples\MapBasic\ANIMATOR Directory
Animator.mb: demonstrates how Animation Layers can speed up the redrawing of Map windows.
Samples\MapBasic\APPINFO Directory
AppInfo.mb: retrieves information about the MapBasic applications that are currently running.
Samples\MapBasic\AUTOLBL Directory
AutoLbl.mb: "labels" a map by placing text objects in the Cosmetic layer (emulating the way earlier
versions of MapInfo Pro created labels).
Samples\MapBasic\GOGOLINE Directory
COGOLine.mb: draws a line at a specified length and angle.
Samples\MapBasic\CoordinateExtractor Directory
Coordinateextractor.mb: updates two columns with the x and y coordinates in the table's native
projection or a user selected projection for each object in the table.
Samples\MapBasic\CSB Directory
CoordSysBounds.mb: enables you to check and set the coordinate system bounds of any mappable
MapInfo base table.
Samples\MapBasic\DATABASE Directory
Autoref.mb: refreshes linked tables every (Interval) seconds
BuildSQL.mb: allows you to connect to DBMS databases; build, save, and load queries; run queries
and preview or download the results.
Connect.mb: provides the MapInfo DBMS Connection Connection Manager dialog box and
related functions. The connection manager allows you to select an existing connection to use,
disconnect existing connections, and get new connections.
DescTab.mb: provides a dataLink utility function that given a table opens a dialog box that describes
it.
DLSUtil.mb: returns the list value at the selection index for Dialog Box List control processing.
GetMITab.mb: MapInfo Pro table picker dialog box.
MIODbCat.mb: This is the DBMS Catalog tool that is loaded from the MapInfo Pro Tool Manager.
This allows the database administrator to create a MapInfo Pro User with the with a
MAPINFO_MAPCATALOG table. It also allows the DBA to delete a table from the catalog.
MIRowCnt.mb: This is the DBMS Count Rows in Table tool that is loaded from the MapInfo Pro Tool
Manager. This tool lets you connect to DBMS databases and run a count(*) against tables, updating
the mapcatalog with the results.
MISetMBR.mb: This is the CoordSysBounds tool that is loaded from the MapInfo Pro Tool Manager.
This tool allows the DBA to change the bounds of a table in the MapInfo_MAPCATALOG table.
MIUpldDB.mb: This tool provides the ability to generate the Database specific SQL statements
allowing you to upload a MapInfo table.
MIUpLoad.mb: This is the Spatialize SQL Server Table tool that is loaded from the MapInfo Pro
Tool Manager. This tool provides the ability to upload a MapInfo table to a remote database with
spatial column information. The Spatial columns are used with DBMS linked tables, which allows a
remote database table to be mappable in MapInfo Pro.
PickCol.mb: This tool provides a server table column picker dialog box.
PickSel.mb: This tool provides a selection picker dialog box as part of the BuildSQL.mbx.
PickTab.mb: This tool provides functions to get a list of server database tables, and table owners
(schemas), and contains a generic function that provides a table selection dialog box.
PrepSQL.mb: This tool provides a SQL Query prepare function that processes query parameters.
The parameters are bound here (resolved and replaced with a value).
SQLPVW.mb: This tool resolves each parameter to a value and return the resolved SQL query
string given an SQL query string with embedded parameters of a specific format.
SQLUtil.mb: This tool provides many utility functions that enable Mapinfo to access to ODBC data.
SQLView.mb: This tool provides a SQL DataLink application for testing the SERVER_COLUMNINFO
function for all options (except VALUE).
Samples\MapBasic\DeleteDuplicates
DeleteDuplicates.mb: This tool allows the user to delete duplicate records from a table while retaining
map objects. The user may also select whether they want a 'Count' column added to the newly
created table.
Samples\MapBasic\DISPERSE Directory
disperse.mb: This tool provides a takes points at given coordinates and disperses them either
randomly or systematically.
Samples\MapBasic\DistanceCalc
DistanceCalc.mb: The Distance Calculator tool can be used to calculate the distance from a selected
object (or group of objects) to the closest or farthest object(s). You can also specify criteria to limit
the results.
Samples\MapBasic\DMSCNVRT Directory
DMSCnvrt.mb: This tool converts between columns of Degree/Minute/Second coordinates and
columns of decimal-degree coordinates.
Samples\MapBasic\FTPLib
FilesManager.mb: A MapBasic sample program to demonstrate the usage of MapInfo HTTP/FTP
library API to receive/send/search files from/to FTP server.
FTPtest.mb: A MapBasic sample program to demonstrate the usage of MapInfo HTTP/FTP library
API to receive/send/search files from/to FTP server.
Samples\MapBasic\GRIDMAKR Directory
GridMakr.mb: This tool creates a grid (graticule) of longitude/latitude lines.
Samples\MapBasic\HTTPLib
HTTPUtil.mb: A sample program to demonstrate how to wrap MapInfo HTTP/XML library internet
APIs into MapBasic functions/subs.
MapUtils.mb: A sample program of MapBasic functions/subs to help with map-associated activities.
TrafficInfo.mb: A sample program to demonstrate how to use the MapInfo HTTP/XML library API
to get traffic information from Yahoo.
XMLUtil.mb: A sample program to demonstrate how to wrap the MapInfo HTTP/XML library XML
APIs into MapBasic functions/subs.
YahooTrafficRSS.mb: A sample program to demonstrate how to use the MapInfo HTTP/XML library
API to get traffic information from Yahoo.
Samples\MapBasic\ICONDEMO Directory
IconDemo.mb: This tool demonstrates the built-in ButtonPad icons provided in MapInfo Pro.
Samples\MapBasic\INC Directory
inc.mb: This directory contains include files that can be useful when programming in the MapBasic
environment.
Among these files are:
• Definition (.DEF) files used by various of the MapBasic tools installed with MapInfo Pro.
AUTO_LIB.DEF and RESSTRNG.DEF are needed by the Tool Manager registration system and
the tools' string localization module, respectively (both of these are stored in the \LIB directory.)
• MAPBASIC.DEF contains, among other things, the definitions for general purpose macros, logical
constants, angle conversion, colors, and string length. These are used as inputs for various
MapBasic functions.
• MENU.DEF contains the definitions needed to access and/or modify MapInfo Pro's dialog boxes,
toolbars, and menu items.
• MAPBASIC.H is the C++ version of MAPBASIC.DEF plus MENU.DEF.
• MAPBASIC.BAS is the Visual Basic 6.0 version of MAPBASIC.DEF plus MENU.DEF.
Samples\MapBasic\LABELER Directory
labeler.mb: This tool allows you to transfer your layers labels into permanent text objects, label the
current selection, and use a label tool and individually label objects into permanent text objects.
Samples\MapBasic\LIB Directory
lib: This directory contains a library of functions and subroutines that can be useful when programming
in the MapBasic environment.
In particular, two of these files are used by many of the MapBasic tools installed with MapInfo Pro:
• AUTO_LIB.MB is used by most tools to help register themselves into the Tools directory.
• RESSTRNG.MB is used by the localized tools to look up the appropriate language strings in the
tools' .STR files.
Samples\MapBasic\NorthArrow Directory
northarrow.mb: This MapBasic program creates North Arrows.
Samples\MapBasic\PACKAGER Directory
packager.mb: This tool packages a copy of a workspace into a single directory for easier backups,
compression, or transfer between computers.
Samples\MapBasic\ProportionalOverlap
ProportionalOverlap.mb: This tool calculates proportional aggregates for objects in a target table
that overlap with objects in a base table. Calculation results are added to a new or to an existing
column in the target table, which you can then save.
Samples\MapBasic\RegVector Directory
regvector.mb: This tool allows you to copy a table of vector objects (regions, polylines, points, etc.)
from one location to another by specifying target locations for three points in the original table.
Samples\MapBasic\RINGBUF Directory
ringbuf.mb: this tool allows you to create multiple "donut" ring buffers. It also will calculate sums and
averages of underlying data within each ring.
Samples\MapBasic\RMW Directory
rotatemapwindow.mb: This tool enables you to rotate the contents of the current Map window a
specific number of degrees.
Samples\MapBasic\RotateLabels Directory
rotatelabels.mb: This tool allows you to rotate labels.
Samples\MapBasic\RotateSymbols Directory
rotatesymbols.mb: This tool allows you to rotate symbols in a table.
Samples\MapBasic\SEAMMGR Directory
seammgr.mb: This tool creates and manages seamless map tables.
Samples\MapBasic\SNIPPETS Directory
The Snippets directory contains sample programs and code snippets that you can incorporate into
your custom MapInfo applications.
Note: In addition to containing sample code snippets, this directory also contains three tools that
are installed with MapInfo Pro Tool Manager. These are the Named Views tool
[NVIEWS.MBX], the Overview tool [OVERVIEW.MBX] and the Scalebar drawing tool
[SCALEBAR.MBX].
Samples\MapBasic\SpiderGraph Directory
SpiderGraph.mb: This application draws lines between objects in a single table, or the objects from
two tables based on a join. It then creates a new table of lines that connect the objects from the
origin table to the objects from the destination table based on matching column values.
Samples\MapBasic\SRCHREPL Directory
srchrepl.mb: performs search-and-replace operations within a table.
Samples\MapBasic\SYMBOL Directory
symbol.mb: allows you to create/edit/delete MapInfo symbols. Editor that lets you customize the
MapInfo symbol set.
Samples\MapBasic\SyncWindows Directory
syncwindows.mb: This program synchronizes mapper windows, creates objects in all mapper
windows, tiles windows, and clears cosmetic layter in all Map windows.
Samples\MapBasic\TABLEMGR Directory
tablemgr.mb: This application lists all open tables in a list box and provides more information about
a table as the user clicks on it. Also allows the user to set some table properties and view table
metadata.
Samples\MapBasic\WINMGR Directory
winmgr.mb: This program allows you to set the title of a document window title and set the default
view for a table.
Samples\MapBasic\WorkspaceResolver
WorkspaceResolver.mb: This tool opens a workspace with references to tables that no longer exist.
It performs a search and replace for the missing tables or resolves the workspace file by ignoring
the missing tables. You can request to open or save a repaired version of the workspace. The default
is to open and save the resolved workspace.
Samples\RIBBONINTERFACE\DotNet Directory
Samples\RIBBONINTERFACE\DotNet\AdvancedPackTableAddIn Directory
This tool gives the users an option to pack the table without losing the currently open windows. The
Advanced pack also allows to select multiple tables for packing. When the addin is loaded, it removes
the Pack Table ribbon button in the Table Ribbon, in Maintenance Ribbon Group and adds an
Advanced Pack ribbon button at the same place. This tool is auto loaded by default.
The advanced pack addin does the following:
1. Save the current session into a temporary workspace.
2. Pack the selected tables.
3. Closes all windows.
4. Reopen the temporary workspace.
This addin still has an issue of custom labels pointing to the wrong rows after the packing. Therefore
it is advised to select only those tables which do not have custom labels associated with them.
How To Run:
1. Open AdvancedPackTableAddIn.csproj.
2. If MapInfo Pro 64-bit is installed to the default location of C:\Program Files\MapInfo\Professional,
then build the project. If MapInfo Pro 64-bit is not installed in the default location, then update
the assembly reference path for MapInfo.Types.dll to your MapInfo Pro 64-bit installation directory
and build the project.
3. Run AdvancedPack.MBX from the project output path.
Note: This sample is only for MapInfo Pro 64-bit.
Samples\RIBBONINTERFACE\DotNet\BackStageAddIn Directory
This sample AddIn exposes the following behavior:
1. Changes caption of the Backstage Header.
2. Adds a BackStage tab Item.
3. Adds custom controls in BackStage tab AddIns.
How To Run:
1. Open BackStage.csproj
2. If MapInfo Pro 64-bit is installed to the default location of C:\Program Files\MapInfo\Professional,
then build the project. If MapInfo Pro 64-bit is not installed in the default location, then update
the assembly reference path for MapInfo.Types.dll, MapInfo.Events.dll, and miadm.dll to your
MapInfo Pro 64-bit installation directory and build the project.
3. Run BackStage.MBX from the project output path.
Note: This sample is only for MapInfo Pro 64-bit.
Samples\RIBBONINTERFACE\DotNet\FloatingWindowRibbon Directory
This sample AddIn exposes the following behavior:
1. Adding controls to Floating Window Ribbon based on the window type.
How To Run:
1. Open FloatingWindowRibbon.csproj
2. If MapInfo Pro 64-bit is installed to the default location of C:\Program Files\MapInfo\Professional,
then build the project. If MapInfo Pro 64-bit is not installed in the default location, then update
the assembly reference path for MapInfo.Types.dll and MapInfo.Events.dll to your MapInfo Pro
64-bit installation directory and build the project.
3. Run FloatingWindowRibbon.MBX from the project output path.
Note: This sample is only for MapInfo Pro 64-bit.
Samples\RIBBONINTERFACE\DotNet\HelloRibbon Directory
This sample AddIn enables to add a new tab in the application.
How To Run:
1. Open HelloRibbon.csproj.
2. If MapInfo Pro 64-bit is installed to the default location of C:\Program Files\MapInfo\Professional,
then build the project. If MapInfo Pro 64-bit is not installed in the default location, then update
the assembly reference path for MapInfo.Types.dll to your MapInfo Pro 64-bit installation directory
and build the project.
3. Run HelloRibbon.MBX from the project output path.
Note: This sample is only for MapInfo Pro 64-bit.
Samples\RIBBONINTERFACE\DotNet\LayoutScaleBarAddIn Directory
This AddIn enables ScaleBar in the MapInfo Pro Layout Designer window.
How To Run:
1. Open LayoutScaleBarAddIn.sln.
2. If MapInfo Pro 64-bit is installed to the default location of C:\Program Files\MapInfo\Professional,
then build the project. If MapInfo Pro 64-bit is not installed in the default location, then update
the assembly reference path for MapInfo.Types.dll and MapInfo.Events.dll to your MapInfo Pro
64-bit installation directory and build the project.
3. Run LayoutScaleBarAddIn.MBX from the project output path.
Note: This sample is only for MapInfo Pro 64-bit.
Samples\RIBBONINTERFACE\DotNet\LayoutTemplate Directory
This is a sample layout template addIn for the Layout Designer window.
How To Run:
1. Open LayoutTemplate.csproj
2. If MapInfo Pro 64-bit is installed to the default location of C:\Program Files\MapInfo\Professional,
then build the project. If MapInfo Pro 64-bit is not installed in the default location, then update
the assembly reference path for MapInfo.Types.dll to your MapInfo Pro 64-bit installation directory
and build the project.
3. Run LayoutTemplate.MBX from the project output path.
Note: This sample is only for MapInfo Pro 64-bit.
Further Information:
More information concerning the various LI API services and SDK's can be found here:
http://www.pitneybowes.com/us/developer/geocoding-apis.html
Samples\RIBBONINTERFACE\DotNet\MapBasicBuildTask Directory
How To Run:
1. Open MapBasicBuildTasks.csproj
2. If MapInfo Pro 64-bit is installed to the default location of C:\Program Files\MapInfo\Professional,
then build the project. If MapInfo Pro 64-bit is not installed in the default location, then update
the assembly reference path for MapInfo.Types.dll, MapInfo.Events.dll, and miadm.dll to your
MapInfo Pro 64-bit installation directory and build the project.
3. Run MapBasicBuildTasks.MBX from the project output path.
Note: This sample is only for MapInfo Pro 64-bit.
Samples\RIBBONINTERFACE\DotNet\MiniToolbar Directory
This sample AddIn demonstrates how to customize the Mapper Context Menu and Mini Tool bar.
How To Run:
1. Open MiniToolbar.csproj
2. If MapInfo Pro 64-bit is installed to the default location of C:\Program Files\MapInfo\Professional,
then build the project. If MapInfo Pro 64-bit is not installed in the default location, then update
the assembly reference path for MapInfo.Types.dll and mibase.dll to your MapInfo Pro 64-bit
installation directory and build the project.
3. Run MiniToolbar.MBX from the project output path.
Note: This sample is only for MapInfo Pro 64-bit.
Samples\RIBBONINTERFACE\DotNet\ProSampleAddIn Directory
This sample AddIn exposes the following behavior:
1. Ribbon
a. Customization of Ribbon tab.
b. Customization of gallery controls.
c. Exposes commands to control the behavior of existing commands in tab.
2. Hide/UnHide Backstage tabs.
3. Customizing the backstage tabs and allowing AddIns to add custom content.
4. OLE Handler.
5. Rearranging an existing MapInfo Pro Window.
6. Managing the tab grouping.
7. Hiding/UnHiding the QAT.
8. Custom windows and docking behavior.
9. Customizing floating window Ribbon.
10. Manage custom tasks.
11. Provide custom window to navigate the Object Model.
How To Run:
1. Open ProSampleAddIn.csproj
2. MapInfo Pro 64-bit is installed to the default location of C:\Program Files\MapInfo\Professional,
then build the project. If MapInfo Pro 64-bit is not installed in the default location, then update
the assembly reference path for MapInfo.Types.dll, MapInfo.Events.dll, and miadm.dll to your
MapInfo Pro 64-bit installation directory and build the project.
Samples\RIBBONINTERFACE\DotNet\ProSpy Directory
This sample AddIn monitors the events in MapInfo Pro by logging all or selected events to the
message window.
How To Run:
1. Open ProSpy.csproj
2. MapInfo Pro 64-bit is installed to the default location of C:\Program Files\MapInfo\Professional,
then build the project. If MapInfo Pro 64-bit is not installed in the default location, then update
the assembly reference path for MapInfo.Types.dll and MapInfo.Events.dll to your MapInfo Pro
64-bit installation directory and build the project.
3. Run ProSpy.MBX from the project output path.
Note: This sample is only for MapInfo Pro 64-bit.
Samples\RIBBONINTERFACE\DotNet\ReBranding Directory
This sample AddIn exposes the following behavior:
1. Change caption of Backstage Header.
2. Change application title.
3. Provide MapInfo Pro Color Scheme Editor in the BackStage AddIn tab.
4. Provide option to apply a sample color scheme.
5. Hide QAT and status bar.
6. Hide About, Help and Product Tabs.
7. Rename the explorer window.
How To Run:
1. Open ReBranding.csproj
2. MapInfo Pro 64-bit is installed to the default location of C:\Program Files\MapInfo\Professional,
then build the project. If MapInfo Pro 64-bit is not installed in the default location, then update
the assembly reference path for MapInfo.Types.dll, MapInfo.Events.dll, and miadm.dll to your
MapInfo Pro 64-bit installation directory and build the project.
3. Run ReBranding.MBX from the project output path.
Note: This sample is only for MapInfo Pro 64-bit.
Samples\RIBBONINTERFACE\DotNet\RibbonCustomization Directory
This sample AddIn demonstrates addition of controls to ribbon. Includes examples on customizing
existing ribbons and also adding new ones.
How To Run:
1. Open RibbonCustomization.csproj
2. MapInfo Pro 64-bit is installed to the default location of C:\Program Files\MapInfo\Professional,
then build the project. If MapInfo Pro 64-bit is not installed in the default location, then update
the assembly reference path for MapInfo.Types.dll and MapInfo.Events.dll to your MapInfo Pro
64-bit installation directory and build the project.
3. Run RibbonCustomization.MBX from the project output path.
Note: This sample is only for MapInfo Pro 64-bit.
Samples\RIBBONINTERFACE\DotNet\RuntimeRebranding Directory
This sample AddIn exposes the following behavior:
1. Change caption of Backstage Header.
2. Change application title.
3. Hide QAT and status bar.
4. Hide About, Help and Product Tabs.
5. Rename the explorer window.
How To Run:
1. Open RuntimeRebranding.csproj
2. MapInfo Pro 64-bit is installed to the default location of C:\Program Files\MapInfo\Professional,
then build the project. If MapInfo Pro 64-bit is not installed in the default location, then update
the assembly reference path for MapInfo.Types.dll, MapInfo.Events.dll, and miadm.dll to your
MapInfo Pro 64-bit installation directory and build the project.
3. Run RuntimeRebranding.MBX from the project output path.
Note: This sample is only for MapInfo Pro 64-bit.
Samples\RIBBONINTERFACE\DotNet\SimpleCustomFrameExample Directory
This sample will build two custom frame samples:
1. Simple Custom Frame Example.
2. Simple Interactive Custom Frame Example.
How To Run:
1. Open SimpleCustomFrameExamples.sln
2. MapInfo Pro 64-bit is installed to the default location of C:\Program Files\MapInfo\Professional,
then build the project. If MapInfo Pro 64-bit is not installed in the default location, then update
the assembly reference path for MapInfo.Types.dll and MapInfo.Events.dll to your MapInfo Pro
64-bit installation directory and build the project.
3. Solution will build two samples. SimpleCustomFrameExample.mbx and
SimpleInteractiveCustomFrameExample.mbx.
Note: This sample is only for MapInfo Pro 64-bit.
Samples\RIBBONINTERFACE\DotNet\StatusBar Directory
This sample AddIn demonstrates how to customize the MapInfo Pro status bar.
How To Run:
1. Open StatusBar.csproj
2. MapInfo Pro 64-bit is installed to the default location of C:\Program Files\MapInfo\Professional,
then build the project. If MapInfo Pro 64-bit is not installed in the default location, then update
the assembly reference path for MapInfo.Types.dll to your MapInfo Pro 64-bit installation directory
and build the project.
3. Run StatusBarCustomization.MBX from the project output path.
Note: This sample is only for MapInfo Pro 64-bit.
Samples\RIBBONINTERFACE\DotNet\UnattachedWindow Directory
This sample describes how to create an unattached window and re-parent it to a dialog. It adds two
buttons onto the ribbon, one to create a dialog with a new map in it and one to create a dialog with
a browser in it.
Note: The Set Next Document Parent HWND MapBasic statement is no longer supported for
re-parenting in MapInfo Pro 64-bit.
How To Run:
1. Open UnattachedWindow.csproj
2. MapInfo Pro 64-bit is installed to the default location of C:\Program Files\MapInfo\Professional,
then build the project. If MapInfo Pro 64-bit is not installed in the default location, then update
the assembly reference path for MapInfo.Types.dll to your MapInfo Pro 64-bit installation directory
and build the project.
3. Run UnattachedWindow.MBX from the project output path.
Note: This sample is only for MapInfo Pro 64-bit.
Samples\RIBBONINTERFACE\MapBasic Directory
Samples\RIBBONINTERFACE\MapBasic\HelloRibbon Directory
This sample AddIn demonstrates adding a new tab, group and a button in MapBasic script. The
button displays a message dialog.
How To Run:
1. Compile HelloRibbon.mb.
2. Compile Resstrng.mb. This should be available in a default install of MapBasic in the folder
Samples\MapBasic\Lib.
3. Link the HelloRibbon.mbp MapBasic project.
4. Run HelloRibbon.MBX in MapInfo Pro 64-bit.
Note: This sample is only for MapInfo Pro 64-bit.
Samples\RIBBONINTERFACE\MapBasic\ProSpyMB Directory
This sample AddIn monitors the events in MapInfo Pro by logging all or selected events to the
message window.
How To Run:
1. Compile ProSpyMB.mb and ProSpyMB_Events.mb.
2. Link the ProSpyMB.mbp MapBasic project.
3. Run ProSpyMB.MBX in MapInfo Pro 64-bit.
Note: This sample is only for MapInfo Pro 64-bit.
Samples\RIBBONINTERFACE\MapBasic\UnattachedWindow Directory
This sample describes using .net for creating an unattached window and re-parenting it to a dialog.
This will add following two buttons into the ribbon:
1. For creating a dialog with a new map in it.
2. For creating a dialog with a browser in it.
Note: "Set Next Document Parent HWND" MapBasic statement is no longer supported for
re-parenting in MapInfo Pro 64-bit.
How To Run:
1. Compile UnattachedWindowMB.mb.
2. Run UnattachedWindowMB.MBX in MapInfo Pro 64-bit.
Note: This sample is only for MapInfo Pro 64-bit.
In this section
Numeric Operators 304
Comparison Operators 305
Logical Operators 306
Geographic Operators 307
Precedence 308
Automatic Type Conversions 310
Summary of Operators
Numeric Operators
The following numeric operators act on two numeric values, producing a numeric result.
+ addition
a + b
- subtraction
a - b
* multiplication
a * b
/ division
a / b
^ exponentiation
a ^ b
Two of these operators are also used in other contexts. The plus sign (+) acting on a pair of strings
concatenates them into a new string value. The minus sign (-) acting on a single number is a negation
operator, producing a numeric result. The ampersand also performs string concatenation.
- numeric negation
- a
+ string concatenation
a + b
Comparison Operators
The comparison operators compare two items of the same general type to produce a logical value
of TRUE or FALSE. Although you cannot directly compare numeric data with non-numeric data (for
example, String expressions), a comparison expression can compare Integer, SmallInt, LargeInt,
and Float data types. Comparison operators are often used in conditional expressions, such as
If...Then.
= a is equal to b
a = b
Logical Operators
The logical operators operate on logical values to produce a logical result of TRUE or FALSE:
Geographic Operators
The geographic operators act on objects to produce a logical result of TRUE or FALSE:
Precedence
A special type of operators are parentheses, which enclose expressions within expressions. Proper
use of parentheses can alter the order of processing in an expression, altering the default precedence.
The table below identifies the precedence of MapBasic operators. Operators which appear on a
single row have equal precedence. Operators of higher priority are processed first. Operators of the
same precedence are evaluated left to right in the expression (with the exception of exponentiation,
which is evaluated right to left).
exponentiation
negation
(Lowest Priority)
addition, subtraction
geographic operators
Not
And
Or
When you create an expression involving data of different types, MapInfo Pro performs automatic
type conversion in order to produce meaningful results. For example, if your program subtracts a
Date value from another Date value, MapBasic will calculate the result as an Integer value
(representing the number of days between the two dates). The table below summarizes the rules
that dictate MapBasic's automatic type conversions. Within this chart, the token Integer represents
an integer value, which can be an Integer variable, a SmallInt variable, a LargeInt variable, or an
Integer constant. The token Number represents a numeric expression which is not necessarily an
integer.
In this section
Supported ODBC Table Types 313
Supported Table Types
These are the ODBC data types that MapInfo Pro supports:
• SQL_BIT
• SQL_TINYINT
• SQL_SMALLINT
• SQL_INTEGER:
• SQL_REAL
• SQL_BIGINT
• SQL_DECIMAL
• SQL_DOUBLE
• SQL_FLOAT
• SQL_NUMERIC
• SQL_BINARY
• SQL_LONGVARBINARY
• SQL_VARBINARY
• SQL_LONGVARCHAR
• SQL_DATE
• SQL_TYPE_DATE
• SQL_TIMESTAMP
• SQL_TYPE_TIMESTAMP
• SQL_TIME
• SQL_TYPE_TIME
• SQL_CHAR
• SQL_VARCHAR
In this section
Prerequisites for Storing/Retrieving Spatial Data 315
Making a Remote Table Mappable
There are four prerequisites for storing and retrieving points on an RDBMS table.
1. The coordinate values for the spatial data must be stored in columns of the table as numbers or
a supported spatial data type.
Possible methods for accomplishing this include:
• Existing data.
• Use Easyloader to upload to the database. This application will work for all supported databases.
This is a data creation task and can be done at any time.
2. To increase performance on queries against the coordinates, a spatial index column can be
included. This is done as part of the sample upload applications, if it is desired. This is a data
creation task and can be done at any time.
3. MapInfo Pro stores information about which columns are the coordinates in a special table on
the RDBMS system known as the MapInfo Map Catalog. There must be one Map Catalog per
database. To create the Map Catalog use Easyloader or MIODBCAT.MBX. You can also follow
the procedure for manually creating a Map Catalog, described in Manually Creating a
MapInfo_MapCatalog. This is a once only task and is required before ANY tables on that database
can be mapped in MapInfo Pro.
4. MapInfo Pro gets catalog information about mappable tables using the MapBasic statement
Server Create Map. This is a once per table task and is required before this specific table can
be mapped in MapInfo Pro.
In this section
Manually Creating a MapInfo_MapCatalog 317
Manually Making a Remote Table Mappable 319
Manually Creating a MapInfo_MapCatalog
SPATIALTYPE Float,
TABLENAME Char(32),
OWNERNAME Char(32),
SPATIALCOLUMN Char(32),
DB_X_LL Float,
DB_Y_LL Float,
DB_X_UR Float,
DB_Y_UR Float,
VIEW_X_LL Float,
VIEW_Y_LL Float,
VIEW_X_UR Float,
VIEW_Y_UR Float,
COORDINATESYSTEM Char(254),
SYMBOL Char(254),
XCOLUMNNAME Char(32),
YCOLUMNNAME Char(32),
RENDITIONTYPE Integer,
RENDITIONCOLUMN VarChar(32),
RENDITIONTABLE VarChar(32),
NUMBER_ROWS Integer
It is important that the structure of the table is exactly like this statement. The only substitution
that can be made is for databases that support varchar or text data types; these data types can
be substituted for the Char data type.
3. Create a unique index on the TABLENAME and the OWNERNAME, so only one table for each
owner can be made mappable.
4. Grant Select privileges to all users on the MAPINFO_MAPCATALOG. This allows users to make
tables mappable. The Update, Insert, and Delete privileges must be granted at the discretion of
the database administrator.
For each spatial table in the remote database that you want to access in MapBasic, you must add
a row to the MAPINFO_MAPCATALOG table. This is carried out in MapInfo Pro when on the TABLE
tab, you click Maintenance, Database, and Make DBMS Table Mappable.
If you do not use MapInfo Pro to manage the Map Catalog, you must manually add rows to the
MAPINFO_MAPCATALOG table for each spatial table in the database that you want to geocode.
Each entry must contain the following information about the table.
• 0 - points only
• 1 – lines
• 2 - regions
• 3 - all geometries
• 4 – text
360
In this section
Definition of Terms 323
List of Embedded images in MapInfo Pro Style Resources (MapInfo Pro
64-bit) 338
Glossary
Definition of Terms
aggregate functions
In MapBasic, functions such as Sum( ) and Count( ) that calculate summary information about
groups of rows in a table. See Select in the MapBasic Reference Guide or Help System.
alias
A name by which a MapInfo Pro user (or a MapBasic program) refers to an open table. For example,
if a table name is C:\MapInfo\Parcels.Tab, then its alias would be Parcels. Table aliases may not
contain spaces; any spaces in a table name become underscore characters in a table alias. Alias
is also a MapBasic data type; an alias variable can store a string expression that represents a column
name (for example, World.Population). The maximum length of an alias is 32 characters.
animation layer
In MapInfo Pro, a special "floating" layer added to a map that allows for redraw of objects in that
layer only. Modifying an object in the animation layer does not cause other layers to redraw.
A set of configuration, template, and custom symbol files and directories that affect the basic settings
and customizations of maps.
argument
array
A grouping of variables of the same type used to keep similar elements together.
bar chart
A type of thematic map that displays a bar chart of thematic variables for each record in a table from
which the map is based.
breakpoint
A debugging aid. To make your program halt at a specific line, place a breakpoint before that line.
brush style
An object's fill pattern. The style is comprised of pattern, foreground color, and background color.
ButtonPad
by reference, by value
In MapBasic, two different ways of passing parameters to a function or procedure. When you pass
an argument by reference (the default), you must specify a variable name when you make the
function call; the called function can modify the variable that you specify. When you pass an argument
by value (using the ByVal keyword), you do not need to specify a variable name.
client
An application that uses or receives information from another program. Often referred to in database
connections or DDE connections.
column
Part of a table or database. A table contains one or more columns, each of which represents an
information category (for example, name, address, and phone number). Columns are sometimes
referred to as "fields". Tables based on raster images do not have columns.
comment
A programmer's note included in the program. The note has no use in the syntax necessary for
compiling the program. In the MapBasic language, an apostrophe (single quotation mark - `) marks
the beginning of a comment. When an apostrophe appears in a statement, MapBasic ignores the
remainder of the line (unless the apostrophe appears inside of a literal string expression).
compiler
A program that takes the text of a program, checks for syntax errors, and converts the code to an
executable format.
control
coordinate
points. Plane coordinate systems describe a two-dimensional x,y location in terms of distance from
a fixed reference and are usually in the first quadrant so that all coordinates are positive numbers.
coordinate system
A set of parameters that specifies how to interpret the locational coordinates of objects. Coordinate
systems may be earth (for example, coordinates in degrees longitude/latitude) or non-earth (for
example, coordinates in feet) based; earth maps are referenced to locations on the Earth.
Cosmetic layer
In MapInfo Pro, a temporary layer that exists on every map window. This layer always occupies the
topmost position on the layer control. MapInfo Pro's Find command places symbols in the Cosmetic
layer to mark where a location was found.
The mouse cursor is a small image that moves as the user moves the mouse. The row cursor is a
value that represents which row in the table is the current row.
DDE
Degrees (longitude and latitude) are coordinates used to represent locations on the surface of the
earth. Longitude, or X-coordinate, represents a location’s east-west position, where any location
west of the prime meridian has a negative X value. Latitude, or Y-coordinate, represents a location’s
north-south position, where any location south of the equator has a negative Y value.
derived column
disabled
A condition where part of the user interface (a menu command, dialog box control, or toolbar button)
is not available to the user. The disabled item is generally shown as "grayed out" to indicate that it
is not available. See also: enabled on page 327.
Microsoft Windows files containing shared executable routines and other resources. DLLs are
generally called from one program to handle a task which often returns a value back to the original
program.
Microsoft Windows-specific protocol that allows different applications to exchange instructions and
data. Both applications must be DDE compliant for a successful exchange.
enabled
The opposite of disabled on page 327; a condition where a menu command, dialog box control, or
toolbar button is available for use.
expression
In MapBasic, a grouping of one or more variables, constant values, function calls, table references,
and operators.
The process of reading information from a file or writing information to a file. Note that the MapBasic
language has one set of statements for performing file i/o, and another set of statements for
performing table manipulation.
focus
In a dialog box, the active control (the control which the user is currently manipulating) is said to
have the focus; pressing the Tab key moves the focus from one control to the next. Focus also
refers to the active application that is running. Switching to a different application (for example, by
pressing Alt+Tab on Windows) causes the other application to receive the focus.
folder
geographic join
A relational link between two mappable tables based on geographic criteria (for example, by
determining which point objects from one table are inside of regions in the other table).
global variable
A variable defined at the beginning of a program that can be used in any procedure or function.
A hardware/software system that receives satellite signals and uses the signals to determine the
receiver's location on the globe.
handler
A procedure in a program. When a specific event occurs (such as the user choosing a menu
command), the handler performs whatever actions are needed to respond to the event.
hexadecimal
A base-16 number system, often used in computer programming. Each character in a hexadecimal
number can be 0-9 or A-F. In MapBasic, you must begin each hexadecimal number with the &H
prefix (for example, &H1A is a hexadecimal number that equals decimal 26).
integrated mapping
Technology that allows MapInfo Pro features, such as Map windows, to be integrated into other
applications (such as Visual Basic programs).
isochrone
A polygon or set of points representing the area that can be traversed in a road network from a
starting point in a given amount of time.
isodistance
A polygon or set of points representing the area that is at a certain travel distance from the starting
point.
Isogram
An Isogram is a map that displays a set of points that satisfy a distance or time condition. Isograms
are either IsoChrones or IsoDistances.
keyword
A word recognized as part of the programming language; for example, a statement or function name.
In the MapBasic documentation, keywords appear in bold.
latitude
The horizontal lines on a map that increase from 0 degrees at the Equator to 90 degrees at both
the North (+90.0 degrees) and South (-90.0 degrees) poles. Used to describe the North-South
position of a point as measured usually in degrees or decimal degrees above or below the equator.
linked tables
A type of MapInfo table that is downloaded from a remote database. The data is taken from the
remote database and transferred locally. The next time the table is linked back to the remote
database, MapInfo Pro checks time stamps to see if there are any differences between the two
tables. Where differences occur, the table is updated with the new information.
linker
In MapBasic, a program that combines separate modules from a project file into a single MBX
application file.
literal value
An expression that defines a specific, explicit value. For example, 23.45 is a literal number, and
"Hello, World" is a literal string. Also referred to as a hard-coded value.
local variable
A variable that is defined and used within a specific function or procedure. Local variables take
precedence over global variables of the same name.
longitude
The vertical lines on a map, running from the North to South poles, used to describe the east-west
position of a point. The position is reported as the number of degrees east (to -180.0 degrees) or
west (to +180.0 degrees) of the prime meridian (0 degrees). Lines of longitude are farthest apart at
the Equator and intersect at both poles, and therefore, are not parallel.
loop
A control structure in a program that executes a group of statements repeatedly. Incorrect coding
of a loop can create an infinite loop (a situation where the loop never ends).
MapBasic Window
A window in the MapInfo Pro user interface. From MapInfo Pro's Options menu, choose Show
MapBasic Window. You can type MapBasic statements into the MapBasic window, without compiling
a program.
MapInfo Runtime
A special version of MapInfo Pro that contains all of the geographic and database capabilities of a
full version but does not include the specific menu and toolbar options in a standard package. Used
to create customized versions of MapInfo Pro.
MBX file
A MapBasic executable file, which the user can run in MapInfo Pro on the Home tab by pointing to
Tools and Run MapBasic Program. Any MapInfo Pro user can run an MBX file. To create an MBX
file, you must use the MapBasic development environment.
metadata
In MapInfo Pro, information about a table (such as date of creation, copyright notice, etc.) stored in
the .TAB file instead of being stored in rows and columns.
In MapBasic, part of OLE Automation. Calling an application's methods is like calling a procedure
that affects the application.
module-level variable
A variable that can be accessed from any function or procedure in an program file, although it cannot
be accessed from other program files in the same project. Created by defining the variable outside
of any function or procedure.
native
A standard file format. Choosing MapInfo Pro's New Table command (on the TABLE tab) creates
a native MapInfo table, but a table based on a spreadsheet or text file is not in MapInfo's native file
format.
object
A graphical object is an entity that can appear in a Map or Layout window (for example, lines, points,
or circles). A MapBasic object variable is a variable that can contain a graphical object. The Object
column name refers to the set of objects stored in a table. An OLE object is a Windows-specific
entity (produced, for example, through drag and drop).
Technology that allows objects created in one application to be used in another application. An
object can be any information such as a map, chart, spreadsheet, sound effect, or text. Embedding
is the process of inserting an object from a server into a container application.
In MapInfo Pro, OLE Automation is technology through which one Windows application can control
another Windows application. For example, a Visual Basic application can control MapInfo Pro
through MapInfo Pro's Automation methods and properties.
operator
A special character or word that acts upon one or more constants, variables, or other values. For
example, the minus operator (-) subtracts one number from another.
parameter
pen style
The line style set for an object. The style is comprised of width, pattern, and color.
pie chart
A circle divided into sectors representing values as percentages in comparison to one another.
MapInfo Pro can display pie charts in the Graph window or in thematic maps.
platform
progress bar
A standard dialog box that displays a horizontal bar, showing the percent complete.
In MapBasic, a project is a collection of modules. A project file (.MBP file) is a text file that defines
the list of modules. Compiling all modules in the project and then linking the project produces an
application (MBX) file.
Part of OLE Automation. A property is a named attribute of an OLE object. To determine the object's
status, read the property. If a property is not read-only, you can change the object's status by
assigning a new value to the property.
A table that consists of a raster image. This table does not contain rows or columns; therefore, some
MapBasic statements that act on tables cannot be used with raster underlay tables.
record
A collection of related fields treated as a unit, such as a record for a customer containing fields for
name, address, and telephone number.
recursion
A condition where a function or procedure calls itself. While recursion may be desirable in some
instances, programmers should be aware that recursion may occur unintentionally, especially with
special event handlers such as SelChangedHandler.
remote data
routine
In MapBasic, a group of statements that performs a specific task; for example, you can use the
OnError statement to designate a group of statements that will act as the error-handling routine.
row
run time
The time at which a program is executing. A runtime error is an error that occurs when an application
is running.
scope of variables
Refers to whether a variable can be accessed from anywhere within a program (global variables)
or only from within a specific function or procedure (local variables). If a procedure has a local
variable with the same name as a global variable, the local variable takes precedence; any references
to the variable name within the procedure will use the local variable.
seamless tables
A type of table that groups other tables together, making it easier to open and map several tables
at one time.
server
An application that performs operations for or sends data to another application (the client). Often
referred to in database connections or DDE connections.
Shortcut menu
A menu that appears if the user clicks the right mouse button.
source code
standard
Standard menu commands and standard toolbar buttons appear as part of the default MapInfo Pro
user interface. Standard dialog boxes are dialog boxes that have a predefined set of controls (for
example, the Note statement produces a standard dialog box with one static text control and an OK
button). If a MapBasic program creates its own user interface element (dialog box or toolbar button)
that element is referred to as a custom dialog box or a custom button.
statement
status bar
In MapInfo Pro, a bar at the bottom of the screen that displays messages that help in using MapInfo
Pro. The StatusBar also displays messages that pertain to the active window. In a Map window, the
StatusBar indicates what layer is editable, the zoom display of the map, and the status of Snap and
Digitizing modes. In a Browser window, the StatusBar indicates the number of records currently
displaying and the total number of records. In a Layout window, the StatusBar indicates the zoom
display as a percentage of the actual size of the map.
A help message that appears on the status bar when the user highlights a menu command or places
the mouse cursor over a toolbar button.
subroutine
A group of statements; in MapBasic syntax, subroutines are known as procedures or sub procedures.
toolbar
A set of buttons. The user can "dock" a toolbar by dragging it to the top edge of the application's
work area. The MapBasic documentation often refers to toolbars as "ButtonPads" because ButtonPad
is the MapBasic-language keyword that you use to modify toolbars.
ToolTip
A brief description of a toolbar button; appears next to the mouse cursor when the user holds the
mouse cursor over a button.
transparent fill
A fill pattern, such as a striped or cross-hatch pattern, that is not completely opaque, allowing the
user to see whatever is "behind" the filled area.
variable
• Images/Application/print_32x32.png
• Images/Application/saveWorkspace_16x16.png
• Images/Application/saveWorkspace_32x32.png
• Images/Window/tasksWindow_16x16.png
• Images/Window/tasksWindow_32x32.png
• Images/Window/toolManager_16x16.png
• Images/Window/toolManager_32x32.png
• Images/Window/windowList_16x16.png
• Images/Window/windowList_32x32.png
• Images/Mapping/addBaseMap_16x16.png
• Images/Mapping/addBaseMap_32x32.png
• Images/Mapping/addLayer_16x16.png
• Images/Mapping/addLayer_32x32.png
• Images/Mapping/addTheme_16x16.png
• Images/Mapping/addTheme_32x32.png
• Images/Mapping/areaSelect_16x16.png
• Images/Mapping/areaSelect_32x32.png
• Images/Mapping/basemapAerial_16x16.png
• Images/Mapping/basemapAerial_32x32.png
• Images/Mapping/basemapHybrid_16x16.png
• Images/Mapping/basemapHybrid_32x32.png
• Images/Mapping/basemapRoads_16x16.png
• Images/Mapping/basemapRoads_32x32.png
• Images/Mapping/boundarySelect_16x16.png
• Images/Mapping/boundarySelect_32x32.png
• Images/Mapping/changeView_16x16.png
• Images/Mapping/changeView_32x32.png
• Images/Mapping/clearCustomLabels_16x16.png
• Images/Mapping/clearCustomLabels_32x32.png
• Images/Mapping/clear_16x16.png
• Images/Mapping/clear_32x32.png
• Images/Mapping/cloneMap_16x16.png
• Images/Mapping/cloneMap_32x32.png
• Images/Mapping/copy_16x16.png
• Images/Mapping/copy_32x32.png
• Images/Mapping/cut_16x16.png
• Images/Mapping/cut_32x32.png
• Images/Mapping/dragMap_16x16.png
• Images/Mapping/dragMap_32x32.png
• Images/Mapping/graphSelect_16x16.png
• Images/Mapping/graphSelect_32x32.png
• Images/Mapping/infoTool_16x16.png
• Images/Mapping/infoTool_32x32.png
• Images/Mapping/invert_16x16.png
• Images/Mapping/invert_32x32.png
• Images/Mapping/labelPriority_16x16.png
• Images/Mapping/labelPriority_32x32.png
• Images/Mapping/labelTool_16x16.png
• Images/Mapping/labelTool_32x32.png
• Images/Mapping/layerControl_16x16.png
• Images/Mapping/layerControl_32x32.png
• Images/Mapping/lockScale1_16x16.png
• Images/Mapping/lockScale1_32x32.png
• Images/Mapping/lockScale2_16x16.png
• Images/Mapping/lockScale2_32x32.png
• Images/Mapping/lockScale_16x16.png
• Images/Mapping/lockScale_32x32.png
• Images/Mapping/mapOptions_16x16.png
• Images/Mapping/mapOptions_32x32.png
• Images/Mapping/marqueeSelect_16x16.png
• Images/Mapping/marqueeSelect_32x32.png
• Images/Mapping/measure_16x16.png
• Images/Mapping/measure_32x32.png
• Images/Mapping/moveTo_16x16.png
• Images/Mapping/moveTo_32x32.png
• Images/Mapping/newBrowser_16x16.png
• Images/Mapping/newBrowser_32x32.png
• Images/Mapping/newMap_16x16.png
• Images/Mapping/newMap_32x32.png
• Images/Mapping/openTable_16x16.png
• Images/Mapping/openTable_32x32.png
• Images/Mapping/pan_16x16.png
• Images/Mapping/pan_32x32.png
• Images/Mapping/paste_16x16.png
• Images/Mapping/paste_32x32.png
• Images/Mapping/redistricter_16x16.png
• Images/Mapping/redistricter_32x32.png
• Images/Mapping/scalebar_16x16.png
• Images/Mapping/scalebar_32x32.png
• Images/Mapping/selectableLabels_16x16.png
• Images/Mapping/selectableLabels_32x32.png
• Images/Mapping/select_16x16.png
• Images/Mapping/select_32x32.png
• Images/Mapping/sqlSelect1_16x16.png
• Images/Mapping/sqlSelect1_32x32.png
• Images/Mapping/sqlSelect_16x16.png
• Images/Mapping/sqlSelect_32x32.png
• Images/Mapping/statsWindow_16x16.png
• Images/Mapping/statsWindow_32x32.png
• Images/Mapping/undo_16x16.png
• Images/Mapping/undo_32x32.png
• Images/Mapping/zoomIn_16x16.png
• Images/Mapping/zoomIn_32x32.png
• Images/Mapping/zoomOut_16x16.png
• Images/Mapping/zoomOut_32x32.png
• Images/Mapping/zoomTo_16x16.png
• Images/Mapping/zoomTo_32x32.png
• Images/Table/addNewRow_16x16.png
• Images/Table/addNewRow_32x32.png
• Images/Table/addToLibrary_16x16.png
• Images/Table/addToLibrary_32x32.png
• Images/Table/addToMap_16x16.png
• Images/Table/addToMap_32x32.png
• Images/Table/appendRows_16x16.png
• Images/Table/appendRows_32x32.png
• Images/Table/browserFont_16x16.png
• Images/Table/browserFont_32x32.png
• Images/Table/clearFilter_16x16.png
• Images/Table/clearFilter_32x32.png
• Images/Table/clearSortFilter_16x16.png
• Images/Table/clearSortFilter_32x32.png
• Images/Table/closeTable_16x16.png
• Images/Table/closeTable_32x32.png
• Images/Table/createPoints_16x16.png
• Images/Table/createPoints_32x32.png
• Images/Table/filter_16x16.png
• Images/Table/filter_32x32.png
• Images/Table/findMapSelection_16x16.png
• Images/Table/findMapSelection_32x32.png
• Images/Table/geocodeServer_16x16.png
• Images/Table/geocodeServer_32x32.png
• Images/Table/geocode_16x16.png
• Images/Table/geocode_32x32.png
• Images/Table/hotLink_16x16.png
• Images/Table/hotLink_32x32.png
• Images/Table/pickFields_16x16.png
• Images/Table/pickFields_32x32.png
• Images/Table/resort_16x16.png
• Images/Table/resort_32x32.png
• Images/Table/saveCopyAs_16x16.png
• Images/Table/saveCopyAs_32x32.png
• Images/Table/saveTable_16x16.png
• Images/Table/saveTable_32x32.png
• Images/Table/showGridlines_16x16.png
• Images/Table/showGridlines_32x32.png
• Images/Table/sortAscending_16x16.png
• Images/Table/sortAscending_32x32.png
• Images/Table/sortClearSort_16x16.png
• Images/Table/sortClearSort_32x32.png
• Images/Table/sortDescending_16x16.png
• Images/Table/sortDescending_32x32.png
• Images/Table/sortMulticolumn_16x16.png
• Images/Table/sortMulticolumn_32x32.png
• Images/Table/sort_16x16.png
• Images/Table/sort_32x32.png
• Images/Table/sort_onOff_16x16.png
• Images/Table/sort_onOff_32x32.png
• Images/Table/updateColumn_32x32.png
• Images/Table/viewEditMetadata_16x16.png
• Images/Table/viewEditMetadata_32x32.png
• Images/Application/clearMapbasicWindow_16x16.png
• Images/Application/clearMapbasicWindow_32x32.png
• Images/Application/getTools_16x16.png
• Images/Application/getTools_32x32.png
• Images/Application/openCatalog_16x16.png
• Images/Application/openCatalog_32x32.png
• Images/Application/openDatabaseTable_16x16.png
• Images/Application/openDatabaseTable_32x32.png
• Images/Application/openDataTable_16x16.png
• Images/Application/openDataTable_32x32.png
• Images/Application/openTable_16x16.png
• Images/Application/openTable_32x32.png
• Images/Application/printToPdf_16x16.png
• Images/Application/printToPdf_32x32.png
• Images/Application/recentFiles_16x16.png
• Images/Application/recentFiles_32x32.png
• Images/Application/runMapbasic_16x16.png
• Images/Application/runMapbasic_32x32.png
• Images/Application/saveMapbasicContents_16x16.png
• Images/Application/saveMapbasicContents_32x32.png
• Images/Layout/addHorizGuideline_16x16.png
• Images/Layout/addHorizGuideline_32x32.png
• Images/Layout/addVertGuideline_16x16.png
• Images/Layout/addVertGuideline_32x32.png
• Images/Layout/alignBottom_16x16.png
• Images/Layout/alignBottom_32x32.png
• Images/Layout/alignLeft_16x16.png
• Images/Layout/alignLeft_32x32.png
• Images/Layout/alignRight_16x16.png
• Images/Layout/alignRight_32x32.png
• Images/Layout/alignTop_16x16.png
• Images/Layout/alignTop_32x32.png
• Images/Layout/align_16x16.png
• Images/Layout/align_32x32.png
• Images/Layout/backgroundFill_16x16.png
• Images/Layout/backgroundFill_32x32.png
• Images/Layout/bold_16x16.png
• Images/Layout/bold_32x32.png
• Images/Layout/browser_16x16.png
• Images/Layout/browser_32x32.png
• Images/Layout/clearAlignBars_16x16.png
• Images/Layout/clearAlignBars_32x32.png
• Images/Layout/decreaseFont_16x16.png
• Images/Layout/decreaseFont_32x32.png
• Images/Layout/fontColor_16x16.png
• Images/Layout/fontColor_32x32.png
• Images/Layout/frame_16x16.png
• Images/Layout/frame_32x32.png
• Images/Layout/gridlines_16x16.png
• Images/Layout/gridlines_32x32.png
• Images/Layout/group_16x16.png
• Images/Layout/group_32x32.png
• Images/Layout/image_16x16.png
• Images/Layout/image_32x32.png
• Images/Layout/increaseFont_16x16.png
• Images/Layout/increaseFont_32x32.png
• Images/Layout/insertArc_16x16.png
• Images/Layout/insertArc_32x32.png
• Images/Layout/insertEllipse_16x16.png
• Images/Layout/insertEllipse_32x32.png
• Images/Layout/insertFont_16x16.png
• Images/Layout/insertFont_32x32.png
• Images/Layout/insertLegend_16x16.png
• Images/Layout/insertLegend_32x32.png
• Images/Layout/insertLine_16x16.png
• Images/Layout/insertLine_32x32.png
• Images/Layout/insertMap_16x16.png
• Images/Layout/insertMap_32x32.png
• Images/Layout/insertPolygonRegion_16x16.png
• Images/Layout/insertPolygonRegion_32x32.png
• Images/Layout/insertPolyline_16x16.png
• Images/Layout/insertPolyline_32x32.png
• Images/Layout/insertRectangle_16x16.png
• Images/Layout/insertRectangle_32x32.png
• Images/Layout/insertRoundRectangle_16x16.png
• Images/Layout/insertRoundRectangle_32x32.png
• Images/Layout/insertScalebar_16x16.png
• Images/Layout/insertScalebar_32x32.png
• Images/Layout/insertTextbox_16x16.png
• Images/Layout/insertTextbox_32x32.png
• Images/Layout/italic_16x16.png
• Images/Layout/italic_32x32.png
• Images/Layout/lineStyle_16x16.png
• Images/Layout/lineStyle_32x32.png
• Images/Layout/margins_16x16.png
• Images/Layout/margins_32x32.png
• Images/Layout/marqueeSelect_16x16.png
• Images/Layout/marqueeSelect_32x32.png
• Images/Layout/newLayoutPage_16x16.png
• Images/Layout/newLayoutPage_32x32.png
• Images/Layout/northArrow_16x16.png
• Images/Layout/northArrow_32x32.png
• Images/Layout/orientation_16x16.png
• Images/Layout/orientation_32x32.png
• Images/Layout/pageLines_16x16.png
• Images/Layout/pageLines_32x32.png
• Images/Layout/regionStyle_16x16.png
• Images/Layout/regionStyle_32x32.png
• Images/Layout/reorderBackward_16x16.png
• Images/Layout/reorderBackward_32x32.png
• Images/Layout/reorderBack_16x16.png
• Images/Layout/reorderBack_32x32.png
• Images/Layout/reorderForward_16x16.png
• Images/Layout/reorderForward_32x32.png
• Images/Layout/reorderFront_16x16.png
• Images/Layout/reorderFront_32x32.png
• Images/Layout/reorder_16x16.png
• Images/Layout/reorder_32x32.png
• Images/Layout/ruler_16x16.png
• Images/Layout/ruler_32x32.png
• Images/Layout/showAlignBars_16x16.png
• Images/Layout/showAlignBars_32x32.png
• Images/Layout/size_16x16.png
• Images/Layout/size_32x32.png
• Images/Layout/symbolStyle_16x16.png
• Images/Layout/symbolStyle_32x32.png
• Images/Layout/symbol_16x16.png
• Images/Layout/symbol_32x32.png
• Images/Layout/textAllCaps_16x16.png
• Images/Layout/textAllCaps_32x32.png
• Images/Layout/textExpanded_16x16.png
• Images/Layout/textExpanded_32x32.png
• Images/Layout/textHalo_16x16.png
• Images/Layout/textHalo_32x32.png
• Images/Layout/textShadow_16x16.png
• Images/Layout/textShadow_32x32.png
• Images/Layout/textStyle_16x16.png
• Images/Layout/textStyle_32x32.png
• Images/Layout/underline_16x16.png
• Images/Layout/underline_32x32.png
• Images/Layout/ungroup_16x16.png
• Images/Layout/ungroup_32x32.png
• Images/Mapping/basemapRoads_b_16x16.png
• Images/Mapping/basemapRoads_b_32x32.png
• Images/Mapping/insertLegend_16x16.png
• Images/Mapping/insertLegend_32x32.png
• Images/Mapping/new3DMap_16x16.png
• Images/Mapping/new3DMap_32x32.png
• Images/Mapping/newPrismMap_16x16.png
• Images/Mapping/newPrismMap_32x32.png
• Images/Window/connectionsWindow_16x16.png
• Images/Window/exportImage_16x16.png
• Images/Window/exportImage_32x32.png
• Images/Window/recoverWindows_16x16.png
• Images/Window/recoverWindows_32x32.png
• Images/Window/redrawWindows_16x16.png
• Images/Window/redrawWindows_32x32.png
• Images/Window/ruler_16x16.png
• Images/Window/ruler_32x32.png
• Images/Window/statsWindow_16x16.png
• Images/Window/statsWindow_32x32.png
• Images/Window/tools_16x16.png
• Images/Window/tools_32x32.png
• Images/Window/workspaceExplorerWindow_16x16.png
• Images/Window/workspaceExplorerWindow_32x32.png
• Images/Window/mapbasicWindow_16x16.png
• Images/Window/mapbasicWindow_32x32.png
• Images/Window/messageWindow_16x16.png
• Images/Window/messageWindow_32x32.png
• Images/Mapping/polygonSelect_16x16.png
• Images/Mapping/polygonSelect_32x32.png
• Images/Application/openFolder_16x16.png
• Images/Application/openFolder_32x32.png
• Images/Spatial/addNodes_16x16.png
• Images/Spatial/addNodes_32x32.png
• Images/Spatial/alignHorizontal_16x16.png
• Images/Spatial/alignHorizontal_32x32.png
• Images/Spatial/alignVertical_16x16.png
• Images/Spatial/alignVertical_32x32.png
• Images/Spatial/arcThreePoints_16x16.png
• Images/Spatial/arcThreePoints_32x32.png
• Images/Spatial/buffer_16x16.png
• Images/Spatial/buffer_32x32.png
• Images/Spatial/calcAngle_16x16.png
• Images/Spatial/calcAngle_32x32.png
• Images/Spatial/calcDirection_16x16.png
• Images/Spatial/calcDirection_32x32.png
• Images/Spatial/checkRegions_16x16.png
• Images/Spatial/checkRegions_32x32.png
• Images/Spatial/circleCenterRadius_16x16.png
• Images/Spatial/circleCenterRadius_32x32.png
• Images/Spatial/circleThreePoints_16x16.png
• Images/Spatial/circleThreePoints_32x32.png
• Images/Spatial/cleanObjects_16x16.png
• Images/Spatial/cleanObjects_32x32.png
• Images/Spatial/clearTarget_16x16.png
• Images/Spatial/clearTarget_32x32.png
• Images/Spatial/clipRegionSet_16x16.png
• Images/Spatial/clipRegionSet_32x32.png
• Images/Spatial/clipRegionToggle_16x16.png
• Images/Spatial/clipRegionToggle_32x32.png
• Images/Spatial/combineSelectObj_16x16.png
• Images/Spatial/combineSelectObj_32x32.png
• Images/Spatial/combineUsingCol_16x16.png
• Images/Spatial/combineUsingCol_32x32.png
• Images/Spatial/convertLinesToPolylines_16x16.png
• Images/Spatial/convertLinesToPolylines_32x32.png
• Images/Spatial/convertToPolylines_16x16.png
• Images/Spatial/convertToPolylines_32x32.png
• Images/Spatial/convertToRectangle_16x16.png
• Images/Spatial/convertToRectangle_32x32.png
• Images/Spatial/convertToRegions_16x16.png
• Images/Spatial/convertToRegions_32x32.png
• Images/Spatial/convexHull_16x16.png
• Images/Spatial/convexHull_32x32.png
• Images/Spatial/copyStyle_16x16.png
• Images/Spatial/copyStyle_32x32.png
• Images/Spatial/copyToStamp_16x16.png
• Images/Spatial/copyToStamp_32x32.png
• Images/Spatial/createLinesFromDb_16x16.png
• Images/Spatial/createLinesFromDb_32x32.png
• Images/Spatial/createPolylinesFronDb_16x16.png
• Images/Spatial/createPolylinesFronDb_32x32.png
• Images/Spatial/digitizeLines_16x16.png
• Images/Spatial/digitizeLines_32x32.png
• Images/Spatial/digitizerSetup_16x16.png
• Images/Spatial/digitizerSetup_32x32.png
• Images/Spatial/disaggregateObject_16x16.png
• Images/Spatial/disaggregateObject_32x32.png
• Images/Spatial/driveRegions_16x16.png
• Images/Spatial/driveRegions_32x32.png
• Images/Spatial/enclose_16x16.png
• Images/Spatial/enclose_32x32.png
• Images/Spatial/eraseOutside_16x16.png
• Images/Spatial/eraseOutside_32x32.png
• Images/Spatial/erase_16x16.png
• Images/Spatial/erase_32x32.png
• Images/Spatial/filletChamfer_16x16.png
• Images/Spatial/filletChamfer_32x32.png
• Images/Spatial/insertText_16x16.png
• Images/Spatial/insertText_32x32.png
• Images/Spatial/intersectingArcs_16x16.png
• Images/Spatial/intersectingArcs_32x32.png
• Images/Spatial/mapcadHelp_16x16.png
• Images/Spatial/mapcadHelp_32x32.png
• Images/Spatial/mapcadOptions_16x16.png
• Images/Spatial/mapcadOptions_32x32.png
• Images/Spatial/measurementLineCumul_16x16.png
• Images/Spatial/measurementLineCumul_32x32.png
• Images/Spatial/measurementLine_16x16.png
• Images/Spatial/measurementLine_32x32.png
• Images/Spatial/mirrorHorizontal_16x16.png
• Images/Spatial/mirrorHorizontal_32x32.png
• Images/Spatial/mirroVertical_16x16.png
• Images/Spatial/mirroVertical_32x32.png
• Images/Spatial/moveDupNodes_16x16.png
• Images/Spatial/moveDupNodes_32x32.png
• Images/Spatial/moveObject_16x16.png
• Images/Spatial/moveObject_32x32.png
• Images/Spatial/offsetObject_16x16.png
• Images/Spatial/offsetObject_32x32.png
• Images/Spatial/orthogonalPoints_16x16.png
• Images/Spatial/orthogonalPoints_32x32.png
• Images/Spatial/orthogonalPolygon_16x16.png
• Images/Spatial/orthogonalPolygon_32x32.png
• Images/Spatial/overlayNodes_16x16.png
• Images/Spatial/overlayNodes_32x32.png
• Images/Spatial/parallelLine_16x16.png
• Images/Spatial/parallelLine_32x32.png
• Images/Spatial/pasteFromStamp_16x16.png
• Images/Spatial/pasteFromStamp_32x32.png
• Images/Spatial/pasteStyle_16x16.png
• Images/Spatial/pasteStyle_32x32.png
• Images/Spatial/perpendicularLine_16x16.png
• Images/Spatial/perpendicularLine_32x32.png
• Images/Spatial/polarAppend_16x16.png
• Images/Spatial/polarAppend_32x32.png
• Images/Spatial/polybuilder_16x16.png
• Images/Spatial/polybuilder_32x32.png
• Images/Spatial/polylineSplitNode_16x16.png
• Images/Spatial/polylineSplitNode_32x32.png
• Images/Spatial/polylineSplit_16x16.png
• Images/Spatial/polylineSplit_32x32.png
• Images/Spatial/replaceFromStamp_16x16.png
• Images/Spatial/replaceFromStamp_32x32.png
• Images/Spatial/reshapeNodes_16x16.png
• Images/Spatial/reshapeNodes_32x32.png
• Images/Spatial/reverseLineDir_16x16.png
• Images/Spatial/reverseLineDir_32x32.png
• Images/Spatial/rightAngle_16x16.png
• Images/Spatial/rightAngle_32x32.png
• Images/Spatial/rotateAroundPoint_16x16.png
• Images/Spatial/rotateAroundPoint_32x32.png
• Images/Spatial/rotatedRectangle_16x16.png
• Images/Spatial/rotatedRectangle_32x32.png
• Images/Spatial/rotateObject_16x16.png
• Images/Spatial/rotateObject_32x32.png
• Images/Spatial/scaleObject_16x16.png
• Images/Spatial/scaleObject_32x32.png
• Images/Spatial/setTarget_16x16.png
• Images/Spatial/setTarget_32x32.png
• Images/Spatial/smoothLines_16x16.png
• Images/Spatial/smoothLines_32x32.png
• Images/Spatial/snapThin_16x16.png
• Images/Spatial/snapThin_32x32.png
• Images/Spatial/snapToLines_16x16.png
• Images/Spatial/snapToLines_32x32.png
• Images/Spatial/snapToNodes_16x16.png
• Images/Spatial/snapToNodes_32x32.png
• Images/Spatial/spline_16x16.png
• Images/Spatial/spline_32x32.png
• Images/Spatial/splitRegion_16x16.png
• Images/Spatial/splitRegion_32x32.png
• Images/Spatial/splitToLines_16x16.png
• Images/Spatial/splitToLines_32x32.png
• Images/Spatial/split_16x16.png
• Images/Spatial/split_32x32.png
• Images/Spatial/styleSelect_16x16.png
• Images/Spatial/styleSelect_32x32.png
• Images/Spatial/textFromDb_16x16.png
• Images/Spatial/textFromDb_32x32.png
• Images/Spatial/textFromTable_16x16.png
• Images/Spatial/textFromTable_32x32.png
• Images/Spatial/trimLineIntersect_16x16.png
• Images/Spatial/trimLineIntersect_32x32.png
• Images/Spatial/undershotOvershot_16x16.png
• Images/Spatial/undershotOvershot_32x32.png
• Images/Spatial/unsmoothLines_16x16.png
• Images/Spatial/unsmoothLines_32x32.png
• Images/Spatial/voronoi_16x16.png
• Images/Spatial/voronoi_32x32.png
• Images/Application/closeConnection_16x16.png
• Images/Application/closeConnection_32x32.png
• Images/Application/loadExtension_16x16.png
• Images/Application/loadExtension_32x32.png
• Images/Table/briefView_16x16.png
• Images/Table/briefView_32x32.png
• Images/Table/catalogBrowserOptions_16x16.png
• Images/Table/catalogBrowserOptions_32x32.png
• Images/Table/catalogList_16x16.png
• Images/Table/catalogList_32x32.png
• Images/Table/collapseWindow_16x16.png
• Images/Table/collapseWindow_32x32.png
• Images/Table/next_16x16.png
• Images/Table/next_32x32.png
• Images/Table/prev_16x16.png
• Images/Table/prev_32x32.png
• Images/Table/search_16x16.png
• Images/Table/search_32x32.png
• Images/Table/summaryView_16x16.png
• Images/Table/summaryView_32x32.png
• Images/Table/updateColumn_16x16.png
• Images/Application/exit_16x16.png
• Images/Application/exit_32x32.png
• Images/Application/help_16x16.png
• Images/Application/help_32x32.png
• Images/Window/connectionsWindow_32x32.png
• Images/Window/tableList_16x16.png
• Images/Window/tableList_32x32.png
• Images/Raster/calculator_16x16.png
• Images/Raster/calculator_32x32.png
• Images/Raster/classifyReclassify_16x16.png
• Images/Raster/classifyReclassify_32x32.png
• Images/Raster/clip_16x16.png
• Images/Raster/clip_32x32.png
• Images/Raster/convert_16x16.png
• Images/Raster/convert_32x32.png
• Images/Raster/copy_16x16.png
• Images/Raster/copy_32x32.png
• Images/Raster/delete_16x16.png
• Images/Raster/delete_32x32.png
• Images/Raster/extractCellValues_16x16.png
• Images/Raster/extractCellValues_32x32.png
• Images/Raster/extractStatistics_16x16.png
• Images/Raster/extractStatistics_32x32.png
• Images/Raster/gridProperties_16x16.png
• Images/Raster/gridProperties_32x32.png
• Images/Raster/histogram_16x16.png
• Images/Raster/histogram_32x32.png
• Images/Raster/infoTool_16x16.png
• Images/Raster/infoTool_32x32.png
• Images/Raster/merge_16x16.png
• Images/Raster/merge_32x32.png
• Images/Raster/rasterize_16x16.png
• Images/Raster/rasterize_32x32.png
• Images/Raster/rename_16x16.png
• Images/Raster/rename_32x32.png
• Images/Raster/reproject_16x16.png
• Images/Raster/reproject_32x32.png
• Images/Raster/resample_16x16.png
• Images/Raster/resample_32x32.png
• Images/Application/databaseMaintenance_16x16.png
• Images/Application/databaseMaintenance_32x32.png
• Images/Application/import_48x48.png
• Images/Application/openCatalog_48x48.png
• Images/Application/openDatabaseTable_48x48.png
• Images/Application/openTable_48x48.png
• Images/Application/openUniversal_48x48.png
• Images/Application/openWFS_48x48.png
• Images/Application/openWMS_48x48.png
• Images/Application/rename_16x16.png
• Images/Application/rename_32x32.png
• Images/Application/tableMaintenance_16x16.png
• Images/Application/tableMaintenance_32x32.png
• Images/Layout/lineSpacing_16x16.png
• Images/Layout/lineSpacing_32x32.png
• Images/Layout/textRotationAngle_16x16.png
• Images/Layout/textRotationAngle_32x32.png
• Images/Mapping/basemapAerial_48x48.png
• Images/Mapping/basemapHybrid_48x48.png
• Images/Mapping/basemapRoads_48x48.png
• Images/Table/saveQuery_16x16.png
• Images/Table/saveQuery_32x32.png
• Images/Mapping/find_16x16.png
• Images/Mapping/find_32x32.png
• Images/Mapping/findAddress_16x16.png
• Images/Mapping/findAddress_32x32.png
• Images/Mapping/findAndMark_16x16.png
• Images/Mapping/findAndMark_32x32.png
• Images/Mapping/zoomToEntireLayer_16x16.png
• Images/Mapping/zoomToEntireLayer_32x32.png
• Images/Mapping/zoomToEntireMap_16x16.png
• Images/Mapping/zoomToEntireMap_32x32.png
• Images/Mapping/zoomToEntireSelectionLayer_16x16.png
• Images/Mapping/zoomToEntireSelectionLayer_32x32.png
• Images/Mapping/zoomToExtentsSelectedObject_16x16.png
• Images/Mapping/zoomToExtentsSelectedObject_32x32.png
• Images/Mapping/zoomToNearestTileServerLevel_16x16.png
• Images/Mapping/zoomToNearestTileServerLevel_32x32.png
• Images/Application/openDataTable_48x48.png
• Images/Application/openWorkspace_48x48.png
• Images/Table/exportTable_16x16.png
• Images/Table/exportTable_32x32.png
• Images/Table/newTable_16x16.png
• Images/Table/newTable_32x32.png
• Images/Application/upArrow_16x16.png
• Images/Table/revertTable_16x16.png
• Images/Table/revertTable_32x32.png
• Images/Table/deleteTable_16x16.png
• Images/Table/deleteTable_32x32.png
• Images/Table/modifyStructure_16x16.png
• Images/Table/modifyStructure_32x32.png
• Images/Table/packTable_16x16.png
• Images/Table/packTable_32x32.png
• Images/Table/renameTable_16x16.png
• Images/Table/renameTable_32x32.png
• Images/Table/refreshConnection_16x16.png
• Images/Table/refreshConnection_32x32.png
• Images/Oracle/createOracleWorkspace_16x16.png
• Images/Oracle/createOracleWorkspace_32x32.png
• Images/Oracle/deleteOracleWorkspace_16x16.png
• Images/Oracle/deleteOracleWorkspace_32x32.png
• Images/Oracle/disableOracleVersioning_16x16.png
• Images/Oracle/disableOracleVersioning_32x32.png
• Images/Oracle/enableOracleVersioning_16x16.png
• Images/Oracle/enableOracleVersioning_32x32.png
• Images/Oracle/mergeOracleTable_16x16.png
• Images/Oracle/mergeOracleTable_32x32.png
• Images/Oracle/refreshOracleTable_16x16.png
• Images/Oracle/refreshOracleTable_32x32.png
• Images/Application/changeDBMSTableSymbol_16x16.png
• Images/Application/changeDBMSTableSymbol_32x32.png
• Images/Application/makeDBMSTableMappable_16x16.png
• Images/Application/makeDBMSTableMappable_32x32.png
• Images/Application/refreshDBMSTable_16x16.png
• Images/Application/refreshDBMSTable_32x32.png
• Images/Application/unlinkDBMSTable_16x16.png
• Images/Application/unlinkDBMSTable_32x32.png
• Images/Application/about_32x32.png
• Images/Application/copyright_16x16.png
• Images/Application/copyright_32x32.png
• Images/Application/dataproducts_16x16.png
• Images/Application/dataproducts_32x32.png
• Images/Application/systeminfo_16x16.png
• Images/Application/systeminfo_32x32.png
• Images/Application/techsupport_16x16.png
• Images/Application/techsupport_32x32.png
• Images/Application/tutorials_16x16.png
• Images/Application/tutorials_32x32.png
• Images/Application/website_32x32.png
• Images/Application/wwwstore_16x16.png
• Images/Application/wwwstore_32x32.png
• Images/Mapping/autoLabel_16x16.png
• Images/Mapping/autoLabel_32x32.png
• Images/Mapping/layerControlOptions_16x16.png
• Images/Mapping/layerControlOptions_32x32.png
• Images/Spatial/insert_16x16.png
• Images/Spatial/insert_32x32.png
• Images/Layout/stackedStyles_16x16.png
• Images/Layout/stackedStyles_32x32.png
• Images/Spatial/Nodes_16x16.png
• Images/Spatial/Nodes_32x32.png
• Images/Application/about_48x48.png
• Images/Application/dataProducts_48x48.png
• Images/Application/displayHelpSearch_32x32.png
• Images/Application/displayHelpSearch_48x48.png
• Images/Application/licensing_32x32.png
• Images/Application/licensing_48x48.png
• Images/Application/suggestions_32x32.png
• Images/Application/suggestions_48x48.png
• Images/Application/tutorials_48x48.png
• Images/Application/website_48x48.png
• Images/Application/onlineStore_32x32.png
• Images/Application/onlineStore_48x48.png
• Images/Mapping/customColors_16x16.png
• Images/Mapping/customColors_32x32.png
• Images/Window/statusBar_16x16.png
• Images/Window/statusBar_32x32.png
• Images/Layout/borderStyle_16x16.png
• Images/Layout/borderStyle_32x32.png
• Images/Layout/regionFill_16x16.png
• Images/Layout/regionFill_32x32.png
• Images/Application/exportAsImage_16x16.png
• Images/Application/exportAsImage_32x32.png
• Images/Mapping/hotLinkOptions_16x16.png
• Images/Mapping/hotLinkOptions_32x32.png
• Images/Mapping/suspendRedraw_16x16.png
• Images/Mapping/suspendRedraw_32x32.png
• Images/Spatial/addNodesFixedDist_16x16.png
• Images/Spatial/addNodesFixedDist_32x32.png
• Images/Application/cancelSearch_16x16.png
• Images/Application/cancelSearch_32x32.png
• Images/Application/search_16x16.png
• Images/Application/search_32x32.png
• Images/Labelling/anchorPointBottomCenter_16x16.png
• Images/Labelling/anchorPointBottomCenter_32x32.png
• Images/Labelling/anchorPointBottomLeft_16x16.png
• Images/Labelling/anchorPointBottomLeft_32x32.png
• Images/Labelling/anchorPointBottomRight_16x16.png
• Images/Labelling/anchorPointBottomRight_32x32.png
• Images/Labelling/anchorPointCenterCenter_16x16.png
• Images/Labelling/anchorPointCenterCenter_32x32.png
• Images/Labelling/anchorPointCenterLeft_16x16.png
• Images/Labelling/anchorPointCenterLeft_32x32.png
• Images/Labelling/anchorPointCenterRight_16x16.png
• Images/Labelling/anchorPointCenterRight_32x32.png
• Images/Labelling/anchorPointTopCenter_16x16.png
• Images/Labelling/anchorPointTopCenter_32x32.png
• Images/Labelling/anchorPointTopLeft_16x16.png
• Images/Labelling/anchorPointTopLeft_32x32.png
• Images/Labelling/anchorPointTopRight_16x16.png
• Images/Labelling/anchorPointTopRight_32x32.png
• Images/Labelling/anchorPoint_32x32.png
• Images/Labelling/labelLeader_16x16.png
• Images/Labelling/labelLeader_32x32.png
• Images/Labelling/offset_16x16.png
• Images/Labelling/offset_32x32.png
• Images/Labelling/stackedStylesLines_16x16.png
• Images/Labelling/stackedStylesLines_32x32.png
• Images/Labelling/stackedStylesRegions_16x16.png
• Images/Labelling/stackedStylesRegions_32x32.png
• Images/Raster/pointInspection_32x32.png
• Images/Raster/regionInspection_32x32.png
• Images/Application/saveAll_16x16.png
• Images/Application/saveAll_32x32.png
• Images/Layout/symbolStyleStacked_16x16.png
• Images/Layout/symbolStyleStacked_32x32.png
• Images/Layer/showCentroids_16x16.png
• Images/Layer/showCentroids_32x32.png
• Images/Layer/showLineDirection_16x16.png
• Images/Layer/showLineDirection_32x32.png
• Images/Layer/showNodes_16x16.png
• Images/Layer/showNodes_32x32.png
• Images/Table/bufferTable_16x16.png
• Images/Table/bufferTable_32x32.png
• Images/Table/rasterImageStyle_16x16.png
• Images/Table/rasterImageStyle_32x32.png
• Images/Table/rasterRegistration_16x16.png
• Images/Table/rasterRegistration_32x32.png
• Images/Table/rasterControlPoint_16x16.png
• Images/Table/rasterControlPoint_32x32.png
• Images/Raster/rasterTools_16x16.png
• Images/Raster/rasterTools_32x32.png
• Images/Mapping/redistricterAdd_16x16.png
• Images/Mapping/redistricterAdd_32x32.png
• Images/Mapping/redistricterAssign_16x16.png
• Images/Mapping/redistricterAssign_32x32.png
• Images/Mapping/redistricterDelete_16x16.png
• Images/Mapping/redistricterDelete_32x32.png
• Images/Mapping/redistricterOptions_16x16.png
• Images/Mapping/redistricterOptions_32x32.png
• Images/Mapping/redistricterSetTarget_16x16.png
• Images/Mapping/redistricterSetTarget_32x32.png
• Images/Application/optAddressMatch_16x16.png
• Images/Application/optAddressMatch_32x32.png
• Images/Application/optDirectories_16x16.png
• Images/Application/optDirectories_32x32.png
• Images/Application/optImageProc_16x16.png
• Images/Application/optImageProc_32x32.png
• Images/Application/optNotifications_16x16.png
• Images/Application/optNotifications_32x32.png
• Images/Application/optOutputSettings_16x16.png
• Images/Application/optOutputSettings_32x32.png
• Images/Application/optPerformance_16x16.png
• Images/Application/optPerformance_32x32.png
• Images/Application/optPrinterDefaults_16x16.png
• Images/Application/optPrinterDefaults_32x32.png
• Images/Application/optStartup_16x16.png
• Images/Application/optStartup_32x32.png
• Images/Application/optStyles_16x16.png
• Images/Application/optStyles_32x32.png
• Images/Application/optSystemSettings_16x16.png
• Images/Application/optSystemSettings_32x32.png
• Images/Application/optWebServices_16x16.png
• Images/Application/optWebServices_32x32.png
• Images/Layer/labelAutosizeCallouts_16x16.png
• Images/Layer/labelAutosizeCallouts_32x32.png
• Images/Layer/labelAutosizeOverflow_16x16.png
• Images/Layer/labelAutosizeOverflow_32x32.png
• Images/Layer/labelAutoSize_16x16.png
• Images/Layer/labelAutoSize_32x32.png
• Images/Layer/labelCentroid_16x16.png
• Images/Layer/labelCentroid_32x32.png
• Images/Layer/labelCurvedFallback_16x16_A.png
• Images/Layer/labelCurvedFallback_16x16_B.png
• Images/Layer/labelCurvedFallback_16x16_C.png
• Images/Layer/labelCurvedFallback_32x32_A.png
• Images/Layer/labelCurvedFallback_32x32_B.png
• Images/Layer/labelCurvedFallback_32x32_C.png
• Images/Layer/labelCurved_16x16_A.png
• Images/Layer/labelCurved_16x16_B.png
• Images/Layer/labelCurved_16x16_C.png
• Images/Layer/labelCurved_32x32_A.png
• Images/Layer/labelCurved_32x32_B.png
• Images/Layer/labelCurved_32x32_C.png
• Images/Layer/labelHorizontal_16x16.png
• Images/Layer/labelHorizontal_32x32.png
• Images/Layer/labelPoint_16x16.png
• Images/Layer/labelPoint_32x32.png
• Images/Layer/labelRotated_16x16.png
• Images/Layer/labelRotated_32x32.png
• Images/Layer/toggleGrayScale_16x16.png
• Images/Layer/toggleGrayScale_32x32.png
• Images/Layer/layerProperties_16x16.png
• Images/Layer/layerProperties_32x32.png
• Images/Layout/labelLeaderStyle_16x16.png
• Images/Layout/labelLeaderStyle_32x32.png
• Images/Layout/lineStyleStacked_16x16.png
• Images/Layout/lineStyleStacked_32x32.png
• Images/Layout/regionStyleStacked_16x16.png
• Images/Layout/regionStyleStacked_32x32.png
• Images/Raster/pause_16x16.png
• Images/Raster/resume_16x16.png
• Images/Raster/stop_16x16.png
• Images/Spatial/createPolylinesFromDb_16x16.png
• Images/Spatial/createPolylinesFromDb_32x32.png
• Images/Spatial/mirrorVertical_16x16.png
• Images/Spatial/mirrorVertical_32x32.png
• Images/Table/changeTableSymbol_16x16.png
• Images/Table/changeTableSymbol_32x32.png
• Images/Table/createOracleWorkspace_16x16_A.png
• Images/Table/createOracleWorkspace_16x16_B.png
• Images/Table/createOracleWorkspace_32x32_A.png
• Images/Table/createOracleWorkspace_32x32_B.png
• Images/Table/deleteOracleWorkspace_16x16_A.png
• Images/Table/deleteOracleWorkspace_16x16_B.png
• Images/Table/deleteOracleWorkspace_32x32_A.png
• Images/Table/deleteOracleWorkspace_32x32_B.png
• Images/Table/disableOracleVersioning_16x16.png
• Images/Table/disableOracleVersioning_32x32.png
• Images/Table/enableOracleVersioning_16x16.png
• Images/Table/enableOracleVersioning_32x32.png
• Images/Table/makeDatabaseMappable_16x16.png
• Images/Table/makeDatabaseMappable_32x32.png
• Images/Table/mergeTables_32x32.png
• Images/Table/modifyTableStructure_16x16.png
• Images/Table/modifyTableStructure_32x32.png
• Images/Table/refreshDBMSTable_16x16.png
• Images/Table/refreshDBMSTable_32x32.png
• Images/Table/refreshOracleTable_16x16.png
• Images/Table/refreshOracleTable_32x32.png
• Images/Table/unlinkDBMSTable_16x16.png
• Images/Table/unlinkDBMSTable_32x32.png
• Images/Tools/briefView_16x16.png
• Images/Tools/briefView_32x32.png
• Images/Tools/toolUniversalTranslator_16x16.png
• Images/Tools/toolUniversalTranslator_32x32.png
• Images/Tools/toolCatalogBrowser_16x16.png
• Images/Tools/toolCatalogBrowser_32x32.png
• Images/Tools/toolNamedViews_16x16.png
• Images/Tools/toolNamedViews_32x32.png
• Images/Tools/toolSyncWindows_16x16.png
• Images/Tools/toolSyncWindows_32x32.png
• Images/Tools/clearCosmeticLayer_16x16.png
• Images/Tools/clearCosmeticLayer_32x32.png
• Images/Tools/syncAllMapWindows_16x16.png
• Images/Tools/syncAllMapWindows_32x32.png
• Images/Tools/syncInstant_16x16.png
• Images/Tools/syncInstant_32x32.png
• Images/Tools/saveCosmeticLayer_16x16.png
• Images/Tools/saveCosmeticLayer_32x32.png
• Images/Tools/catalogBrowserOptions_16x16.png
• Images/Tools/catalogBrowserOptions_32x32.png
• Images/Tools/catalogList_16x16.png
• Images/Tools/catalogList_32x32.png
• Images/Tools/collapseWindow_16x16.png
• Images/Tools/collapseWindow_32x32.png
• Images/Tools/next_16x16.png
• Images/Tools/next_32x32.png
• Images/Tools/prev_16x16.png
• Images/Tools/prev_32x32.png
• Images/Tools/searchCatalog_16x16.png
• Images/Tools/searchCatalog_32x32.png
• Images/Tools/summaryView_16x16.png
• Images/Tools/summaryView_32x32.png
• Images/Tools/toolGridMaker_16x16.png
• Images/Tools/toolGridMaker_32x32.png
• Images/Tools/registerTool_16x16.png
• Images/Tools/registerTool_32x32.png
• Images/Tools/toolCoordSysBounds_16x16.png
• Images/Tools/toolCoordSysBounds_32x32.png
• Images/Tools/toolProportionalOverlap_16x16.png
• Images/Tools/toolProportionalOverlap_32x32.png
• Images/Tools/toolNorthArrow_16x16.png
• Images/Tools/toolNorthArrow_32x32.png
• Images/Labelling/labelOverlap_16x16.png
• Images/Labelling/labelOverlap_32x32.png
• Images/Labelling/labelOverflow_16x16.png
• Images/Labelling/labelOverflow_32x32.png
• Images/Layer/applyStyles_16x16.png
• Images/Layer/applyStyles_32x32.png
• Images/Layer/labelAutoPositionCallout_16x16.png
• Images/Layer/labelAutoPositionCallout_32x32.png
• Images/Layer/labelAutoPositionOverflow_16x16.png
• Images/Layer/labelAutoPositionOverflow_32x32.png
• Images/Layer/labelAutoPosition_16x16.png
• Images/Layer/labelAutoPosition_32x32.png
• Images/Tasks/cancelJob_16x16.png
• Images/Tasks/cancelJob_32x32.png
• Images/Tasks/jobErrors_16x16.png
• Images/Tasks/jobErrors_32x32.png
• Images/Tasks/jobSuccessful_16x16.png
• Images/Tasks/jobSuccessful_32x32.png
• Images/Tasks/jobWarnings_16x16.png
• Images/Tasks/jobWarnings_32x32.png
• Images/Tasks/pauseJob_16x16.png
• Images/Tasks/pauseJob_32x32.png
• Images/Tasks/removeJob_16x16.png
• Images/Tasks/removeJob_32x32.png
• Images/Tasks/resumeJob_16x16.png
• Images/Tasks/resumeJob_32x32.png
• Images/Tasks/viewJobLog_16x16.png
• Images/Tasks/viewJobLog_32x32.png
• Images/Layout/activeMapFrameSelected_16x16.png
• Images/Layout/openMap_16x16.png
• Images/Layout/activeBrowserFrameSelected_16x16.png
• Images/Layout/openBrowser_16x16.png
• Images/Layout/textJustifyCenter_16x16.png
• Images/Layout/textJustifyCenter_32x32.png
• Images/Layout/textJustifyLeft_16x16.png
• Images/Layout/textJustifyLeft_32x32.png
• Images/Layout/textJustifyRight_16x16.png
• Images/Layout/textJustifyRight_32x32.png
• Images/Layout/frameStyle_16x16.png
• Images/Layout/frameStyle_32x32.png
• Images/Layout/panCanvas_16x16.png
• Images/Layout/panCanvas_32x32.png
• Images/Layout/zoomInCanvas_16x16.png
• Images/Layout/zoomInCanvas_32x32.png
• Images/Layout/zoomOutCanvas_16x16.png
• Images/Layout/zoomOutCanvas_32x32.png
• Images/Layout/selectCanvas_16x16.png
• Images/Layout/selectCanvas_32x32.png
• Images/Layout/snapToGrid_16x16.png
• Images/Layout/snapToGrid_32x32.png
• Images/Layout/newBrowserActive_16x16.png
• Images/Layout/newBrowser_16x16.png
• Images/Layout/newBrowser_32x32.png
• Images/Layout/newMapActive_16x16.png
• Images/Layout/newMap_16x16.png
• Images/Layout/newMap_32x32.png
• Images/Legend/legendrefreshAll_16x16.png
• Images/Legend/legendrefreshAll_32x32.png
• Images/Legend/legendRefreshQuick_16x16.png
• Images/Legend/legendRefreshQuick_32x32.png
• Images/Legend/modifyLegend_16x16.png
• Images/Legend/modifyLegend_32x32.png
• Images/Legend/modifyTheme_16x16.png
• Images/Legend/modifyTheme_32x32.png
• Images/Legend/addHorizGuideline_16x16.png
• Images/Legend/addHorizGuideline_32x32.png
• Images/Legend/addVertGuideline_16x16.png
• Images/Legend/addVertGuideline_32x32.png
• Images/Legend/alignBottom_16x16.png
• Images/Legend/alignBottom_32x32.png
• Images/Legend/alignLeft_16x16.png
• Images/Legend/alignLeft_32x32.png
• Images/Legend/alignRight_16x16.png
• Images/Legend/alignRight_32x32.png
• Images/Legend/alignTop_16x16.png
• Images/Legend/alignTop_32x32.png
• Images/Legend/align_16x16.png
• Images/Legend/align_32x32.png
• Images/Legend/clearAlignBars_16x16.png
• Images/Legend/clearAlignBars_32x32.png
• Images/Legend/deleteFrame_16x16.png
• Images/Legend/deleteFrame_32x32.png
• Images/Legend/insertLegend_16x16.png
• Images/Legend/insertLegend_32x32.png
• Images/Legend/showAlignBars_16x16.png
• Images/Legend/showAlignBars_32x32.png
• Images/Legend/showGridlines_16x16.png
• Images/Legend/showGridlines_32x32.png
• Images/Legend/snapToGrid_16x16.png
• Images/Legend/snapToGrid_32x32.png
• Images/Legend/insertTextbox_16x16.png
• Images/Legend/insertTextbox_32x32.png
• Images/Layout/removeItems_16x16.png
• Images/Layout/removeItems_32x32.png
• Images/Application/defaultToolButton_16x16.png
• Images/Application/defaultToolButton_32x32.png
• Images/Window/themeLegend_16x16.png
• Images/Window/themeLegend_32x32.png
• Images/Tools/toolRotateSymbols_16x16.png
• Images/Tools/toolRotateSymbols_32x32.png
• Images/Tools/toolDistanceCalculator_16x16.png
• Images/Tools/toolDistanceCalculator_32x32.png
• Images/Labelling/previewOn_16x16.png
• Images/Labelling/previewOn_32x32.png
• Images/Tools/DegreeConvert_16x16.png
• Images/Tools/DegreeConvert_32x32.png
• Images/Tools/toolSeamlessManager_16x16.png
• Images/Tools/toolSeamlessManager_32x32.png
• Images/Spatial/voronoiTable_16x16.png
• Images/Spatial/voronoiTable_32x32.png
• Images/Spatial/driveRegionsTable_16x16.png
• Images/Spatial/driveRegionsTable_32x32.png
• Images/Tools/GELink_16x16.png
• Images/Application/BackStage_About.png
• Images/Application/about_64x64.png
• Images/Application/bingKey_64x64.png
• Images/Application/bingTerms.png
• Images/Application/borrowLicense_64x64.png
• Images/Application/checkNews.png
• Images/Application/checkUpdate_64x64.png
• Images/Application/exit_64x64.png
• Images/Application/help_64x64.png
• Images/Application/options_64x64.png
• Images/Application/products_64x64.png
• Images/Application/readNotice.png
• Images/Application/returnLicense_64x64.png
• Images/Application/search_64x64.png
• Images/Application/suggestions.png
• Images/Application/transferLicense_64x64.png
• Images/Application/video_64x64.png
• Images/Application/aboutWhite_64x64.png
• Images/Application/bingKeyWhite_64x64.png
• Images/Application/bingTermsWhite_64x64.png
• Images/Application/borrowLicenseWhite_64x64.png
• Images/Application/checkNewsWhite_64x64.png
• Images/Application/checkUpdateWhite_64x64.png
• Images/Application/exitWhite_64x64.png
• Images/Application/helpWhite_64x64.png
• Images/Application/optionsWhite_64x64.png
• Images/Application/productsWhite_64x64.png
• Images/Application/readNoticeWhite_64x64.png
• Images/Application/returnLicenseWhite_64x64.png
• Images/Application/searchWhite_64x64.png
• Images/Application/suggestionsWhite_64x64.png
• Images/Application/transferLicenseWhite_64x64.png
• Images/Application/videoWhite_64x64.png
• Images/Mapping/clearCosmeticLayer_16x16.png
• Images/Mapping/clearCosmeticLayer_32x32.png
• Images/Application/InsertWorkspace_16x16.png
• Images/Application/InsertWorkspace_32x32.png
• Images/Tools/toolEasyLoader_16x16.png
• Images/Tools/toolEasyLoader_32x32.png
• Images/Layer/labelDisplayDialog_16x16.png
• Images/Layer/labelDisplayDialog_32x32.png
• Images/Layer/labelRulesDialog_16x16.png
• Images/Layer/labelRulesDialog_32x32.png
• Images/Mapping/saveCosmeticLayer_16x16.png
• Images/Mapping/saveCosmeticLayer_32x32.png
• Images/Mapping/sqlSelectSimple_16x16.png
• Images/Mapping/sqlSelectSimple_32x32.png
• Images/Application/openNoView_16x16.png
• Images/Application/openNoView_32x32.png
• Images/Application/saveWorkspaceAs_16x16.png
• Images/Application/saveWorkspaceAs_32x32.png
• Images/Mapping/selectAllFromSelection_32x32.png
• Images/Mapping/selectAllFromSelection_16x16.png
• Images/Mapping/selectionEditable_16x16.png
• Images/Mapping/selectionEditable_32x32.png
• Images/Spatial/circleFromTable_16x16.png
• Images/Spatial/circleFromTable_32x32.png
• Images/Spatial/convertToLine_16x16.png
• Images/Spatial/convertToLine_32x32.png
• Images/Spatial/dimensionLineContinuous_16x16.png
• Images/Spatial/dimensionLineContinuous_32x32.png
• Images/Spatial/dimensionLine_16x16.png
• Images/Spatial/dimensionLine_32x32.png
• Images/Spatial/disaggregateToLines_16x16.png
• Images/Spatial/disaggregateToLines_32x32.png
• Images/Spatial/lineFromTable_16x16.png
• Images/Spatial/lineFromTable_32x32.png
• Images/Spatial/modify_16x16.png
• Images/Spatial/modify_32x32.png
• Images/Spatial/moveAlongLine_16x16.png
• Images/Spatial/moveAlongLine_32x32.png
• Images/Spatial/parallel_16x16.png
• Images/Spatial/parallel_32x32.png
• Images/Spatial/polylineFromTable_16x16.png
• Images/Spatial/polylineFromTable_32x32.png
• Images/Spatial/scale_16x16.png
• Images/Spatial/scale_32x32.png
• Images/Spatial/segmenting_16x16.png
• Images/Spatial/segmenting_32x32.png
• Images/Spatial/selectByStyle_16x16.png
• Images/Spatial/selectByStyle_32x32.png
• Images/Spatial/traverseLine_16x16.png
• Images/Spatial/traverseLine_32x32.png
• Images/Tools/MapCAD_16x16.png
• Images/Tools/MapCAD_32x32.png
• Images/Tools/MapCAD_48x48.png
• Images/Mapping/textFromTable_16x16.png
• Images/Mapping/textFromTable_32x32.png
• Images/Mapping/textObjects_16x16.png
• Images/Mapping/textObjects_32x32.png
• Images/Mapping/textToTable_16x16.png
• Images/Mapping/textToTable_32x32.png
• Images/Mapping/newMapper_16x16.png
• Images/Mapping/newMapper_32x32.png
• Images/Window/lastDocumentWindow_16x16.png
• Images/Window/lastDocumentWindow_12x12.png
• Images/Application/dropdownButton_16x16.png
• Images/Application/dropdownButton_32x32.png
• Images/Application/menuButton_16x16.png
• Images/Application/menuButton_32x32.png
• Images/Application/ribbonButton_16x16.png
• Images/Application/ribbonButton_32x32.png
• Images/Application/splitButton_16x16.png
• Images/Application/splitButton_32x32.png
• Images/Application/toggleButton_16x16.png
• Images/Application/toggleButton_32x32.png
• Images/Mapping/redo_16x16.png
• Images/Mapping/redo_32x32.png
www.pitneybowes.com