MapInfo概论
?第一讲 MapInfo简介及基本概念
?第二讲 MapInfo基本操作 —表
?第三讲 MapInfo查询及分析
?第四讲 空间分析及属性信息图形化
?第五讲 OLE 嵌入与 MapBasic 简介
?第六讲 MapInfo集成地图开发
?第七讲 组件式 GIS与 MapX基础
?第八讲 MapX二次开发
上节总结:
1,MapBasic的软件集成环境,
( 1) 文本编辑器,用于程序的编辑与修改;
( 2) 程序编译器,用于源程序编译,生成可执行程序;
( 3) 程序链接器,将若干独立的模块链接成一个应用程序;
( 4) 联机帮助,提供 MapBasic 每条语句或函数的详细说明资料
mb文件 → mbx文件; mb文件 → mbo文件+ mbp文件 → mbx文件
2、创建、编译和链接项目文件( Project File ),
[link]- Application- Module
mbp文件+ mbo文件- mbx可执行文件 (实例)
3、程序组织,Include,mapbasic.def”
Type … End Type
Declare/Declare function
Define /Global
Sub Main … End Sub
Sub … End Sub
Function … End Function
4、事件处理程序:
单击鼠标或其他由用户发出的动作称为事件。
事件处理程序,WinClosedHandler,WinChangedHandler、
ToolHandler, EndHandler 等
程序运行时,MapBasic自动调用相应程序,不需要在主过程中调用
,只在程序开头声明即可。
5,对于 定长字符串 变量,MapBasic总是用 空格 去填充不足部分 ;
6,如果在字符串常量里本身就有 双引号,那么需要插入 两个连续
的双引号到这个字符串中,例如:
Note,The Table,“World”” is already open.”
这个语句的运行结果是显示下面的一条信息:
The Table,World” is already open.
7,值参数传递 ( ByVal)
( 1) 在 Call语句中不必一定要为参数指定一个变量名 。 可以指定一个
变量名, 常量值或其他的表达式 。
( 2) 如果在子过程中赋了一个新的值给值参数, 将不影响调用者 。 换
句说话, 子过程不能通过值参数把一个值返回给调用者 。
8、访问表的指定列:
tablename.columnname; tablename.coln; tablename.col(n)
9、创建一个新表,Create table tablename
用 Create Index给一个表增加索引
Create Index on Cust(CustID)
用 Create Map使一张表可地图化
Create Map For Cust Coordsys Earthy
10、修改表结构,Alter Table
修改之前应该先保存该表,Commit Table
或放弃当前编辑,Rollback Table
11、顺序文件的输入 /输出:
Open File filename For Input/Output/Append As #1
用 Input#或 Line input#语句读文件,用 Write#语句写数据到文件中。
12、随机文件的输入 /输出:
Open File,filename” For Random As #1 Len=length
用 Get和 Put语句读写数据
13、二进制文件的输入 /输出:
Open File,filename” For Binary As #1
可以用 Get和 Put语句读写数据
14、如何查询、创建、修改地图对象,Obj
?第六讲 MapInfo集成地图开发
一、创建用户界面
1.1 菜单( menu)
1.2 工具条 ( ButtonPads)
1.3 对话框 ( Dialog)
1.4 窗口( Windows)
二,MapInfo集成地图开发
2.1 集成地图开发的概念
2.2 MapInfo集成地图开发过程
2.3 回调( Callbacks)
2.4 程序运行语句
一、创建用户界面
1.1 菜单( menu)
菜单栏- Menu Bar ;菜单- Menu ; 菜单项- Menu Item
① 新建菜单,Create Menu,MenuName” as“SubMenuName” calling Sub
② 新建菜单栏,Create Menu Bar As
恢复 MapInfo标准菜单栏,Create Menu Bar As Default
③ 增加 /移除菜单项,Alter Menu add / remove
加分割线, (-”
④ 增加 /移除菜单,Alter Menu Bar Add / remove,Menuname”
建立好的菜单需要把它加到菜单栏上才能看得见,
Alter Menu,Menuname” Add,Menuname1” As,Menuname1”
⑤ 修改菜单项,Alter Menu Item 过程 Enable/Disable/Check/Uncheck
灰化一个菜单项,在菜单项名字的第一个字母前加,(”
快捷键的定义,用键盘来使用菜单,在想定义的快捷键的字母前加字符 &
热键的定义,执行菜单命令的组合键
·PushButton——触发式按钮 。 如图层控制按钮,
特点,用户单击一个触发式按钮时, 按钮仍会弹回来 。
·ToggleButton——开关式按钮 。 如图例窗口显示 /隐藏按钮,
特点,用户单击按钮时, 按钮变成两种状态中的一种, 即
按下或弹起 。
·ToolButton——工具按钮, 如选择按钮,
特点,用户单击按钮时, 一个工具将处于激活状态, 直到
用户选择了另一个按钮 。
新建工具条:
Create ButtonPad,名称, as PushButton/ToggleButton/ToolButton
一、创建用户界面
1.2 工具条( ButtonPads)
修改工具条的属性,AlterButtonPad“主 /绘图, Add/Remove
可以重定位, 显示 /隐藏工具条或增加删除工具条中的工具 。
修改单个工具的状态,Alter Button
查询用户使用按钮的信息,Commandinfo()
工具条信息,ButtonPadInfo()
恢复标准工具条,Create ButtonPads As Default
一、创建用户界面
1.3 对话框( Dialog)
1、标准对话框:
( 1)询问对话框,Ask ( prompt,ok_text,cancel_text )
Dim more As Logical
more = Ask("Do you want to continue?","OK","Stop")
( 2)显示信息对话框,Note message
Note "Total # of records processed," + Str$( i_count )
( 3)状态条,ProgressBar
ProgressBar "Writing data..." Calling write_out Range 600000
( 4) FileOpenDlg( path,filename,filetype,prompt )
Dim s_filename As String
s_filename = FileOpenDlg("","","TAB","Open Table")
( 5) FileSaveAsDlg ( path,filename,filetype,prompt )
2、创建用户自定义对话框:
Dialog
[ Title title ]
[ Width w ] [ Height h ] [ Position x,y ]
[ Calling handler ]
Control control_clause
[ Control control_clause,,, ]
MapBasic对话框控件类型,Control 子句控制
3、修改对话框:
Alter MapInfoDialog dialog_ID
Alter MapInfoDialog dialog_ID Default
一、创建用户界面
1.4 窗口( Windows)
Map,Browse,Graph,Layout; Create Redistricter
1、显示 /隐藏窗口,Open/Close Window
MapBasic,Statistics,Legend,Info,Ruler,Help,Message
2、新建窗口,Map From
统计窗口,Graph Country,Population From Selection
Layout Position (0,0) Width 2 Height 4
创建重新分区窗口:
Create Redistricter source_table By district_column
创建图例窗口,Create Legend
[ From Window window_ID ]
[ { Show | Hide } ]
3、窗口 ID号:
获取活动窗口所 ID号,FrontWindow()
例,Dim map_win_id As Integer
Open Table "states"
Map From states
map_win_id = FrontWindow()
4、设置各种不同的窗口,
Set browse ; Set Legend; Set Map; Set Window;
Set Paper Units; Set LayOut,Set Redistrict
5、保存窗口:
Save Window ; Save WorkSapce
例,Save Window i_mapper_ID As "riskmap.wmf" Type "WMF "
6、计算窗口数目:
NumWindows(),NumAllWindows()
二,MapInfo集成地图开发
2.1 集成地图的概念
1、集成地图开发的概念:
将 MapInfo地图窗口集成在用其它语言编写的应用程序中
的开发方式,叫做 集成地图开发 。
利用其它平台能够调用 MapInfo环境下的数据、图形等,
应用程序可以控制集成地图的外观、部分执行过程,甚至生成
完全不同于 MapInfo界面的应用程序。
注意:
MapInfo在后台运行。
可以用 Visul Basic,VC++,Delphi等可视化的开发环境,
集成 MapInfo窗口到非 MapBasic应用程序中,特别是原有成熟
的应用系统中,增加 GIS的功能。
集成地图开发是在程序中调用语句( MapBasic语句)来在
后台启动 MapInfo应用程序,MapInfo在后台运行,并不显示
启动窗口。集成地图窗口与 MapInfo中的地图窗口没有本质的
区别。
在集成地图应用程序中,首先构造代表 MapBasic语句的字
符串,然后使用 OLE技术或者 DDE技术(动态数据交换)将字
符串发送给 MapInfo,从而可以操纵 MapInfo,MapInfo会像
处理 MapBasic语句一样处理这些命令字符串。
例如,打开地图窗口,在 MapBasic编程中采用 Map From 语
句即可。但是,在集成地图应用程序中,必须给出附加的语句
(如 Set Next document Parent ),使地图窗口首先成为当前
应用程序的子窗口。该过程通常称为,重父化( reparenting)
窗口”。然后才可以使用 Map From 语句打开地图窗口。
二,MapInfo集成地图开发
2.2 MapInfo集成地图开发过程
客户应用程序
VB,VC++ MapInfo应用程序OLE,DDE
发送 MapBasic语句
MapInfo返回信息 —回调
MapBasic程序
可选
OLE 自动化,不是 OLE嵌入
重父化,hWnd
一个简单的示例程序:
集成地图的 VB编程开发步骤如下:
1、启动 MapInfo
调用 VB的 CreateObject()函数,并对返回的 VB对象变量进
行赋值,可将该对象定义为全局变量。如:
Dim miApp as object
Set miApp =CreateObject(“mapinfo.application”)
miApp.do,set application window, & Form1.hWnd
要调用已运行的 MapInfo,则使用 GetObject()函数连结
Set mapinfo= GetObjec (,,mapinfo.application”)
CreateObject ()和 GetObject()函数均使用 OLE自动对象连结
MapInfo,DDE技术在此不做介绍。
2、向 MapInfo传送命令
启动 MapInfo后,就可构造代表 MapBasic语句的字符串。
如希望 MapInfo执行 MapBasic的打开表,需构造如下字符串:
msg=“open table”“world.tab”“Interactive”
然后使用 Do方法,向 MapInfo发送字符串命令,例如
miApp.do msg ( miApp 为定义的启动 MapInfo的全局变量 )
可以在一条命令行中合并多个 MapBasic语句,利用 &连结。
msg=,open table”“usa”“Interactive”
msg=msg &,Set Next Document Parent, & Form1.hwnd &,Style1”
msg=msg &,Map from usa”
Miapp.do msg
注意:关键词后面的空格是必要的! 重父化
因为存在空格,当 MapInfo解析命令行时,能自动检测出 msg
包含 3个独立的 MapBasic语句,Open table,Set Next Document,
Map From,MapInfo通过保留关键字 Open,Set,Map来辨别。
3、从 MapInfo中查询数据
如果需要查询 MapBasic表达式的值,需构造代表该表达式
的字符串。例如,如果希望判断 MapBasic的 WindowID(0)函数
的返回值,在 VB中可以按照如下方式构造:
① msg=“WindowID(0)”
② 采用 OLE自动化:
Dim result as String
result=miApp.Eval,WindowID(0)”
解释,MapInfo将该字符串解释为 MapBasic表达式,确定
该表达式的值,然后以字符串的形式返回给 VB应用程序。
注意,MapBasic语句中关键词后的 空格, 双引号里面的语
句最后有一个空格,如,set application window,,否则与 VB
语句连接时将出错!
4、定位 MapInfo窗口
(1) 重定位 MapInfo父窗口
启动 MapInfo后,采用 MapBasic语句的 Set Application
Window语句可以使客户程序拥有 MapInfo的对话框和错误信
息对话框。
Msg=“Set Application Window, & Form1.hWnd
miApp.do msg
(2) 重定位文件窗口
需要在 VB应用程序中集成 MapInfo窗口时,需要向 MapInfo
发送 MapBasic创建窗体的 Set Next Document 语句,以及创建
该窗口的 MapBasic语句。如:
Msg="Set Next Document Parent " & Form1.hWnd & "
Style 1/Style2/Style3 "
Mymap.do msg
Mymap.do "Map from world"
mapid=Val(miApp.eval(“WindowID(0)”))
重父化窗口为窗口重新指定一个父窗口,指定应用程
序中一控件的句柄,下次当创建 MapInfo窗口,使用 Map、
Browse,LayOut或 Create Legend语句时,新建的窗口被
重父化好了,这些地图窗口就将已指定的应用程序作为
它们的父窗口。
即使地图窗口重新指定了父窗口,MapInfo仍然能够
维护该窗口,如果部分窗口需要刷新,MapInfo自动刷新
该窗口,因此客户应用程序可以不考虑擦除和刷新重父
化的窗口。
Set Next Document 多个地图窗口
(3) 重定位图例和特殊窗口
① 特殊窗口
MapInfo包括信息 (Info)、标尺 (Ruler)、消息 (Message)和统
计 (Statics)窗口等特殊的浮动窗口,重父化这些窗口,需要
MapBasic的 Set Window语句。如:
miApp.do,Set window Info Parent,& form1.hWnd
重父化信息窗口与重父化地图窗口不同原因:
MapInfo可有多个地图窗口,但 只有一个 信息窗口。
② 图例窗口
,Set Next Document, &地图窗口,hWnd。
再用 Create Legend语句 不同于 MapInfo的默认图例窗口
自定义的图例窗口不会自动刷新
图例窗口与地图窗口或统计图窗口绑在一起。
miApp.do,Set Window Info Parent, & Form1.hWnd
5、允许用户定义地图窗口大小
MapInfo不会依据新窗口的大小自动重新设置地图以填满窗
口,因此要实现改变地图窗口大小的功能,必须利用 Windows
API函数 MoveWindow编写代码来实现
Declare Function MoveWindow Lib "user32" (ByVal hwnd As Long,_
ByVal x As Long,ByVal y As Long,_
ByVal nWidth As Long,ByVal nHeight As Long,_
ByVal bRepaint As Long) As Long
Private Sub Form_Resize()
dim mHwnd as long
mHwnd=Val(miApp.Eval(“WindowInfo(FrontWindow(),WIN_INFO_WND)”))
MoveWindow(mHwnd,0,0,ScaleWidth,ScaleHeight,0)
End Sub
FrontWindow():返回当前活动窗口的整型 ID号,
WindowInfo(要返回的信息的窗口的整型 ID号 )
Scalemode属性设置为 Pixels(象素)
由示例程序演示( API函数浏览器)
6、集成 MapInfo工具按钮
在 VB应用程序中可集成 MapInfo中所有工具按钮的功能,如
放大、缩小等,但是由于不能对 MapInfo的工具栏进行重父化,
因此如果在应用程序中需要工具按钮,只能在应用程序开发环
境中自己创建。如果希望所创建的 VB工具栏按钮能仿效标准的
MapInfo按钮,可以使用 MapInfo的 RunMenuCommand方法。
可设置信息提示如下:
miApp.RunMenuCommand 1707/M_TOOLS_PNT_QUERY
既可以使用数字,也可使用 标识符,若使用标识符,必须在
程序中包含 MapBasic头文件,如果开发环境是:
VB——MapBasic.bas;
VC++(C++ Builder)——MapBasic.h;
MapBasic——MapBasic.def
Main工具条:
选择,M_TOOLS_SELECTOR = 1701
矩形选择,M_TOOLS_SEARCH_RECT = 1722
圆选择,M_TOOLS_SEARCH_RADIUS = 1703
多边形选择, M_TOOLS_SEARCH_BOUNDARY = 1704
放大,M_TOOLS_EXPAND = 1705
缩小,M_TOOLS_SHRINK = 1706
平移,M_TOOLS_RECENTER = 1702
信息查询,M_TOOLS_PNT_QUERY = 1707
标注,M_TOOLS_LABELER = 1708
拖放窗口,M_TOOLS_DRAGWINDOW = 1734
标尺,M_TOOLS_RULER = 1710
Draw工具条:
点符号,M_TOOLS_POINT = 1711
直线, M_TOOLS_LINE = 1712
折线,M_TOOLS_POLYLINE = 1713
弧,M_TOOLS_ARC = 1716
多边形,M_TOOLS_POLYGON = 1714
椭圆,M_TOOLS_ELLIPSE = 1715
矩形,M_TOOLS_RECTANGLE = 1717
圆角矩形,M_TOOLS_ROUNDEDRECT = 1718
文本,M_TOOLS_TEXT = 1709
框架,M_TOOLS_FRAME = 1719
增加节点,M_TOOLS_ADD_NODE = 1723
7、子定义 MapInfo快捷菜单
可以使用 MapBasic语句增加 /删除快捷菜单中的一个或多个
命令。
Alter Menu…Add Calling OLE 增加
Alter Menu…Remove 删除
可使用 Create Menu语句重新定义菜单,并使用,(-”代码作
为新菜单定义。
如删除 MapInfo地图窗口中的快捷菜单:
miApp.do "Create Menu ""MapperShortcut"" ID 17 as ""(- "" "
8、打印 MapInfo集成窗口
应用 MapBasic的,PrintWin”语句可以打印 MapInfo窗口。
MiApp.do,PrintWin”
也可先利用 MapBasic的,Save Window”语句输出一个窗口
图元文件 (WMF)来替代地图的打印,然后应用 VB的
,PrintForm”
9,错误捕获
VB,On Error GoTo
VC++,try ….catch….finally
10、终止 MapInfo的运行
通过 CreateObject()创建 MapInfo应用程序对象,如果
释放该对象变量,则终止 MapInfo的运行。所以 miApp应
该作为全局变量,如果是局部变量的话,子程序结束时,
miApp就会释放,MapInfo终止运行。
Set miApp =Nothing
二,MapInfo集成地图开发
2.3 回调( Callbacks)
1、回调概述
前面介绍了如何向 MapInfo发送命令,我们还希望
MapInfo能把信息发送到应用程序中。如当地图窗口改变时,
希望 MapInfo能通知应用程序,并告知改变的窗口 ID,程序
员可在应用程序中编写相应的响应代码。
这种获得 MapInfo发送回来的消息的通讯机制称作 回调 。
下面几种情况下,允许 MapInfo向客户应用程序发送信息,
( 1) 用户使用自定义工具与 MapInfo窗口进行交互。 如用
户在地图窗口中单击并拖动鼠标绘制一条直线,MapInfo可
以告诉客户程序用户选择的 x,y坐标;
( 2) 用户选择了菜单命令。 假如应用程序自定义了
MapInfo的快捷菜单,当用户从快捷菜单中选择了命令时,
MapInfo可以通知客户程序来调用该菜单事件;
( 3) 当地图窗口发生改变时。 如果用户选择了地图窗口中
的内容,(如增加或删除了图层,或漫游地图 ),MapInfo可以
告诉客户程序该 窗口的 ID号,与 MapBasic的特殊处理进程
winChangedHandler类似;
( 4) 当 MapInfo状态栏中的文本发生改变时。 MapInfo的状
态栏不会显示在集成地图窗口中,如果希望模拟 MapInfo的
效果,必须编写 代码 。无论状态栏文本发生何种变化,
MapInfo都能通知应用程序。
利用 OLE自动服务器功能完成回调。
2、如何使用 OLE回调
( 1)采用 VB4.0以上版本或其它能支持 OLE服务器的语言,创
建一个能定义一个或多个 OLE方法 的 类 ;
( 2)如果模拟 MapInfo的状态栏,创建 SetStatusText方法,对
该方法进行定义使其能获取一个 字符串变量 ;
( 3)如果希望在每次地图窗口改变时 MapInfo能通知客户程序,
创建 WindowContentsChanged方法,定义该方法能获取一个 4
字节 整数大小的 变量,代表该 MapInfo窗口的 ID号;
( 4)如果使用自定义菜单命令或按钮,希望 MapInfo能通知客
户程序,可以创建一个或多个 额外的方法,所定义的每一个方
法能获取一个 字符串变量 ;
( 5) 用自定义的类来创建对象,
Public myCallback As New CMyClass
( 6)在程序启动 MapInfo后,调用 MapInfo的 SetCallback方法,
然后指定该对象名:
mapinfo.SetCallback myCallback
( 7)如果希望当用户在使用自定义工具栏按钮时,MapInfo向
客户程序发出通知,可以自定义按钮,如:
Alter ButtonPad…Add Calling OLE
( 8)如果希望当用户使用菜单命令时,MapInfo向客户程序发
出通知,可以使用诸如, Alter Menu…Add Calling OLE”的
语句来 自定义菜单命令;
( 9) 在所定义的方法内,编制必要的处理程序来处理 MapInfo
传送来的变量 。
3、处理回调数据
在集成地图应用程序中,创建自定义的 MapInfo菜单命令和
工具按钮后,使用回调机制来处理 MapInfo发送给应用程序的
数据。当用户选择这些命令和按钮后,MapInfo向 OLE方法发
送一个 由逗号分隔的包含 8个元素的字符串 。
例如:
MI,-73.5548,42.122,F,F,-72.867702,43.025,202,
如果熟悉 MapBasic的 CommandInfo()函数, 那么很容易明
白该逗号分隔的字符串的内容 。 编写 MBX应用程序时是通过
调用 MapBasic处理程序的子过程句柄, 来实现自定义菜单命令
和自定义按钮的 。
在子过程句柄中, 通过调用 CommandInfo()函数来判断当前
事件的不同信息 。 如判定在 MapBasic编程中使用自定义绘制工
具按钮时是否按下 shift键 。
Log_variable=CommandInfo(CMD_INFO_SHIFT)
CommandInfo()函数的意义:
1 CMD_INFO_X 第 1点的 X坐标
2 CMD_INFO_Y 第 1点的 Y坐标
3 CMD_INFO_SHIF 按下 Shift
4 CMD_INFO_CTRL 按下 Ctrl
5 CMD_INFO_X 第 2点的 X坐标
6 CMD_INFO_Y 第 2点的 Y坐标
7 CMD_INFO_TOOLBTN 用户点击的 ButtonID
8 CMD_INFO_MENUITEM 用户点击的 MenuID
当创建自定义的菜单或按钮,并使用, Calling OLE方法名,
语句指定该菜单命令或按钮相应的方法后,MapInfo就会使
用上述 8个返回值构造一个由逗号分割的字符串 。该字符串始
终以, MI:”为前缀,通过该前缀,OLE服务器可以判断是
MapInfo调用了该方法。
MapInfo发送给方法的字符串结构如下:
,MI:”+”CommandInfo(1)”+,CommandInfo(2)”
+,CommandInfo(3)” +,CommandInfo(4)”
+,CommandInfo(5)” +,CommandInfo(6)”
+,CommandInfo(7)” +,CommandInfo(8)”
如果在集成地图应用程序中,MapInfo的快捷 菜单 中增加了
一个自定义菜单 (ID:101),则 MapInfo发送的字符串为,
MI:,,,,,,,101
如果用户创建了一个自定义 按钮,实现用户在地图窗口中
单击并拖动鼠标绘制一条直线,则 MapInfo发送的字符串为:
Mi:-10.26,42.12,F,F,-80.13,100.2,2002,
x1 y1 x2 y2 ButtonID,空值
如果为每个自定义的按钮指定了唯一的 ID,可以让按钮调
用同一个方法,然后在方法中通过检验字符串的第 7个元素,来
判断用户选择的是哪个按钮。
一旦 MapInfo将由逗号分割的字符串发送给应用程序的方法,
方法中必须增加代码来解析字符串,执行代码。
二,MapInfo集成地图开发
2.4 程序运行语句
1、运行 MapBasic应用程序 (MBX)或添加 MapInfo工作空间
Run Application file(可执行文件)
终止,Terminate Application
例如:
MiApp.do,Run Application,“C:\mapbasic\app\report.mbx”””
MiApp.do,Run Application,“parcels.wor”””
2、运行其他程序
Run Program Program_spec 命令字符串
例如,Run Program,notepad.exe readme.txt”
注意尽量避免多任务处理可能引起的冲突,可将 Run Program
语句放置在处理事件语句之后。
欢迎多提宝贵意见!
谢谢!
?第一讲 MapInfo简介及基本概念
?第二讲 MapInfo基本操作 —表
?第三讲 MapInfo查询及分析
?第四讲 空间分析及属性信息图形化
?第五讲 OLE 嵌入与 MapBasic 简介
?第六讲 MapInfo集成地图开发
?第七讲 组件式 GIS与 MapX基础
?第八讲 MapX二次开发
上节总结:
1,MapBasic的软件集成环境,
( 1) 文本编辑器,用于程序的编辑与修改;
( 2) 程序编译器,用于源程序编译,生成可执行程序;
( 3) 程序链接器,将若干独立的模块链接成一个应用程序;
( 4) 联机帮助,提供 MapBasic 每条语句或函数的详细说明资料
mb文件 → mbx文件; mb文件 → mbo文件+ mbp文件 → mbx文件
2、创建、编译和链接项目文件( Project File ),
[link]- Application- Module
mbp文件+ mbo文件- mbx可执行文件 (实例)
3、程序组织,Include,mapbasic.def”
Type … End Type
Declare/Declare function
Define /Global
Sub Main … End Sub
Sub … End Sub
Function … End Function
4、事件处理程序:
单击鼠标或其他由用户发出的动作称为事件。
事件处理程序,WinClosedHandler,WinChangedHandler、
ToolHandler, EndHandler 等
程序运行时,MapBasic自动调用相应程序,不需要在主过程中调用
,只在程序开头声明即可。
5,对于 定长字符串 变量,MapBasic总是用 空格 去填充不足部分 ;
6,如果在字符串常量里本身就有 双引号,那么需要插入 两个连续
的双引号到这个字符串中,例如:
Note,The Table,“World”” is already open.”
这个语句的运行结果是显示下面的一条信息:
The Table,World” is already open.
7,值参数传递 ( ByVal)
( 1) 在 Call语句中不必一定要为参数指定一个变量名 。 可以指定一个
变量名, 常量值或其他的表达式 。
( 2) 如果在子过程中赋了一个新的值给值参数, 将不影响调用者 。 换
句说话, 子过程不能通过值参数把一个值返回给调用者 。
8、访问表的指定列:
tablename.columnname; tablename.coln; tablename.col(n)
9、创建一个新表,Create table tablename
用 Create Index给一个表增加索引
Create Index on Cust(CustID)
用 Create Map使一张表可地图化
Create Map For Cust Coordsys Earthy
10、修改表结构,Alter Table
修改之前应该先保存该表,Commit Table
或放弃当前编辑,Rollback Table
11、顺序文件的输入 /输出:
Open File filename For Input/Output/Append As #1
用 Input#或 Line input#语句读文件,用 Write#语句写数据到文件中。
12、随机文件的输入 /输出:
Open File,filename” For Random As #1 Len=length
用 Get和 Put语句读写数据
13、二进制文件的输入 /输出:
Open File,filename” For Binary As #1
可以用 Get和 Put语句读写数据
14、如何查询、创建、修改地图对象,Obj
?第六讲 MapInfo集成地图开发
一、创建用户界面
1.1 菜单( menu)
1.2 工具条 ( ButtonPads)
1.3 对话框 ( Dialog)
1.4 窗口( Windows)
二,MapInfo集成地图开发
2.1 集成地图开发的概念
2.2 MapInfo集成地图开发过程
2.3 回调( Callbacks)
2.4 程序运行语句
一、创建用户界面
1.1 菜单( menu)
菜单栏- Menu Bar ;菜单- Menu ; 菜单项- Menu Item
① 新建菜单,Create Menu,MenuName” as“SubMenuName” calling Sub
② 新建菜单栏,Create Menu Bar As
恢复 MapInfo标准菜单栏,Create Menu Bar As Default
③ 增加 /移除菜单项,Alter Menu add / remove
加分割线, (-”
④ 增加 /移除菜单,Alter Menu Bar Add / remove,Menuname”
建立好的菜单需要把它加到菜单栏上才能看得见,
Alter Menu,Menuname” Add,Menuname1” As,Menuname1”
⑤ 修改菜单项,Alter Menu Item 过程 Enable/Disable/Check/Uncheck
灰化一个菜单项,在菜单项名字的第一个字母前加,(”
快捷键的定义,用键盘来使用菜单,在想定义的快捷键的字母前加字符 &
热键的定义,执行菜单命令的组合键
·PushButton——触发式按钮 。 如图层控制按钮,
特点,用户单击一个触发式按钮时, 按钮仍会弹回来 。
·ToggleButton——开关式按钮 。 如图例窗口显示 /隐藏按钮,
特点,用户单击按钮时, 按钮变成两种状态中的一种, 即
按下或弹起 。
·ToolButton——工具按钮, 如选择按钮,
特点,用户单击按钮时, 一个工具将处于激活状态, 直到
用户选择了另一个按钮 。
新建工具条:
Create ButtonPad,名称, as PushButton/ToggleButton/ToolButton
一、创建用户界面
1.2 工具条( ButtonPads)
修改工具条的属性,AlterButtonPad“主 /绘图, Add/Remove
可以重定位, 显示 /隐藏工具条或增加删除工具条中的工具 。
修改单个工具的状态,Alter Button
查询用户使用按钮的信息,Commandinfo()
工具条信息,ButtonPadInfo()
恢复标准工具条,Create ButtonPads As Default
一、创建用户界面
1.3 对话框( Dialog)
1、标准对话框:
( 1)询问对话框,Ask ( prompt,ok_text,cancel_text )
Dim more As Logical
more = Ask("Do you want to continue?","OK","Stop")
( 2)显示信息对话框,Note message
Note "Total # of records processed," + Str$( i_count )
( 3)状态条,ProgressBar
ProgressBar "Writing data..." Calling write_out Range 600000
( 4) FileOpenDlg( path,filename,filetype,prompt )
Dim s_filename As String
s_filename = FileOpenDlg("","","TAB","Open Table")
( 5) FileSaveAsDlg ( path,filename,filetype,prompt )
2、创建用户自定义对话框:
Dialog
[ Title title ]
[ Width w ] [ Height h ] [ Position x,y ]
[ Calling handler ]
Control control_clause
[ Control control_clause,,, ]
MapBasic对话框控件类型,Control 子句控制
3、修改对话框:
Alter MapInfoDialog dialog_ID
Alter MapInfoDialog dialog_ID Default
一、创建用户界面
1.4 窗口( Windows)
Map,Browse,Graph,Layout; Create Redistricter
1、显示 /隐藏窗口,Open/Close Window
MapBasic,Statistics,Legend,Info,Ruler,Help,Message
2、新建窗口,Map From
统计窗口,Graph Country,Population From Selection
Layout Position (0,0) Width 2 Height 4
创建重新分区窗口:
Create Redistricter source_table By district_column
创建图例窗口,Create Legend
[ From Window window_ID ]
[ { Show | Hide } ]
3、窗口 ID号:
获取活动窗口所 ID号,FrontWindow()
例,Dim map_win_id As Integer
Open Table "states"
Map From states
map_win_id = FrontWindow()
4、设置各种不同的窗口,
Set browse ; Set Legend; Set Map; Set Window;
Set Paper Units; Set LayOut,Set Redistrict
5、保存窗口:
Save Window ; Save WorkSapce
例,Save Window i_mapper_ID As "riskmap.wmf" Type "WMF "
6、计算窗口数目:
NumWindows(),NumAllWindows()
二,MapInfo集成地图开发
2.1 集成地图的概念
1、集成地图开发的概念:
将 MapInfo地图窗口集成在用其它语言编写的应用程序中
的开发方式,叫做 集成地图开发 。
利用其它平台能够调用 MapInfo环境下的数据、图形等,
应用程序可以控制集成地图的外观、部分执行过程,甚至生成
完全不同于 MapInfo界面的应用程序。
注意:
MapInfo在后台运行。
可以用 Visul Basic,VC++,Delphi等可视化的开发环境,
集成 MapInfo窗口到非 MapBasic应用程序中,特别是原有成熟
的应用系统中,增加 GIS的功能。
集成地图开发是在程序中调用语句( MapBasic语句)来在
后台启动 MapInfo应用程序,MapInfo在后台运行,并不显示
启动窗口。集成地图窗口与 MapInfo中的地图窗口没有本质的
区别。
在集成地图应用程序中,首先构造代表 MapBasic语句的字
符串,然后使用 OLE技术或者 DDE技术(动态数据交换)将字
符串发送给 MapInfo,从而可以操纵 MapInfo,MapInfo会像
处理 MapBasic语句一样处理这些命令字符串。
例如,打开地图窗口,在 MapBasic编程中采用 Map From 语
句即可。但是,在集成地图应用程序中,必须给出附加的语句
(如 Set Next document Parent ),使地图窗口首先成为当前
应用程序的子窗口。该过程通常称为,重父化( reparenting)
窗口”。然后才可以使用 Map From 语句打开地图窗口。
二,MapInfo集成地图开发
2.2 MapInfo集成地图开发过程
客户应用程序
VB,VC++ MapInfo应用程序OLE,DDE
发送 MapBasic语句
MapInfo返回信息 —回调
MapBasic程序
可选
OLE 自动化,不是 OLE嵌入
重父化,hWnd
一个简单的示例程序:
集成地图的 VB编程开发步骤如下:
1、启动 MapInfo
调用 VB的 CreateObject()函数,并对返回的 VB对象变量进
行赋值,可将该对象定义为全局变量。如:
Dim miApp as object
Set miApp =CreateObject(“mapinfo.application”)
miApp.do,set application window, & Form1.hWnd
要调用已运行的 MapInfo,则使用 GetObject()函数连结
Set mapinfo= GetObjec (,,mapinfo.application”)
CreateObject ()和 GetObject()函数均使用 OLE自动对象连结
MapInfo,DDE技术在此不做介绍。
2、向 MapInfo传送命令
启动 MapInfo后,就可构造代表 MapBasic语句的字符串。
如希望 MapInfo执行 MapBasic的打开表,需构造如下字符串:
msg=“open table”“world.tab”“Interactive”
然后使用 Do方法,向 MapInfo发送字符串命令,例如
miApp.do msg ( miApp 为定义的启动 MapInfo的全局变量 )
可以在一条命令行中合并多个 MapBasic语句,利用 &连结。
msg=,open table”“usa”“Interactive”
msg=msg &,Set Next Document Parent, & Form1.hwnd &,Style1”
msg=msg &,Map from usa”
Miapp.do msg
注意:关键词后面的空格是必要的! 重父化
因为存在空格,当 MapInfo解析命令行时,能自动检测出 msg
包含 3个独立的 MapBasic语句,Open table,Set Next Document,
Map From,MapInfo通过保留关键字 Open,Set,Map来辨别。
3、从 MapInfo中查询数据
如果需要查询 MapBasic表达式的值,需构造代表该表达式
的字符串。例如,如果希望判断 MapBasic的 WindowID(0)函数
的返回值,在 VB中可以按照如下方式构造:
① msg=“WindowID(0)”
② 采用 OLE自动化:
Dim result as String
result=miApp.Eval,WindowID(0)”
解释,MapInfo将该字符串解释为 MapBasic表达式,确定
该表达式的值,然后以字符串的形式返回给 VB应用程序。
注意,MapBasic语句中关键词后的 空格, 双引号里面的语
句最后有一个空格,如,set application window,,否则与 VB
语句连接时将出错!
4、定位 MapInfo窗口
(1) 重定位 MapInfo父窗口
启动 MapInfo后,采用 MapBasic语句的 Set Application
Window语句可以使客户程序拥有 MapInfo的对话框和错误信
息对话框。
Msg=“Set Application Window, & Form1.hWnd
miApp.do msg
(2) 重定位文件窗口
需要在 VB应用程序中集成 MapInfo窗口时,需要向 MapInfo
发送 MapBasic创建窗体的 Set Next Document 语句,以及创建
该窗口的 MapBasic语句。如:
Msg="Set Next Document Parent " & Form1.hWnd & "
Style 1/Style2/Style3 "
Mymap.do msg
Mymap.do "Map from world"
mapid=Val(miApp.eval(“WindowID(0)”))
重父化窗口为窗口重新指定一个父窗口,指定应用程
序中一控件的句柄,下次当创建 MapInfo窗口,使用 Map、
Browse,LayOut或 Create Legend语句时,新建的窗口被
重父化好了,这些地图窗口就将已指定的应用程序作为
它们的父窗口。
即使地图窗口重新指定了父窗口,MapInfo仍然能够
维护该窗口,如果部分窗口需要刷新,MapInfo自动刷新
该窗口,因此客户应用程序可以不考虑擦除和刷新重父
化的窗口。
Set Next Document 多个地图窗口
(3) 重定位图例和特殊窗口
① 特殊窗口
MapInfo包括信息 (Info)、标尺 (Ruler)、消息 (Message)和统
计 (Statics)窗口等特殊的浮动窗口,重父化这些窗口,需要
MapBasic的 Set Window语句。如:
miApp.do,Set window Info Parent,& form1.hWnd
重父化信息窗口与重父化地图窗口不同原因:
MapInfo可有多个地图窗口,但 只有一个 信息窗口。
② 图例窗口
,Set Next Document, &地图窗口,hWnd。
再用 Create Legend语句 不同于 MapInfo的默认图例窗口
自定义的图例窗口不会自动刷新
图例窗口与地图窗口或统计图窗口绑在一起。
miApp.do,Set Window Info Parent, & Form1.hWnd
5、允许用户定义地图窗口大小
MapInfo不会依据新窗口的大小自动重新设置地图以填满窗
口,因此要实现改变地图窗口大小的功能,必须利用 Windows
API函数 MoveWindow编写代码来实现
Declare Function MoveWindow Lib "user32" (ByVal hwnd As Long,_
ByVal x As Long,ByVal y As Long,_
ByVal nWidth As Long,ByVal nHeight As Long,_
ByVal bRepaint As Long) As Long
Private Sub Form_Resize()
dim mHwnd as long
mHwnd=Val(miApp.Eval(“WindowInfo(FrontWindow(),WIN_INFO_WND)”))
MoveWindow(mHwnd,0,0,ScaleWidth,ScaleHeight,0)
End Sub
FrontWindow():返回当前活动窗口的整型 ID号,
WindowInfo(要返回的信息的窗口的整型 ID号 )
Scalemode属性设置为 Pixels(象素)
由示例程序演示( API函数浏览器)
6、集成 MapInfo工具按钮
在 VB应用程序中可集成 MapInfo中所有工具按钮的功能,如
放大、缩小等,但是由于不能对 MapInfo的工具栏进行重父化,
因此如果在应用程序中需要工具按钮,只能在应用程序开发环
境中自己创建。如果希望所创建的 VB工具栏按钮能仿效标准的
MapInfo按钮,可以使用 MapInfo的 RunMenuCommand方法。
可设置信息提示如下:
miApp.RunMenuCommand 1707/M_TOOLS_PNT_QUERY
既可以使用数字,也可使用 标识符,若使用标识符,必须在
程序中包含 MapBasic头文件,如果开发环境是:
VB——MapBasic.bas;
VC++(C++ Builder)——MapBasic.h;
MapBasic——MapBasic.def
Main工具条:
选择,M_TOOLS_SELECTOR = 1701
矩形选择,M_TOOLS_SEARCH_RECT = 1722
圆选择,M_TOOLS_SEARCH_RADIUS = 1703
多边形选择, M_TOOLS_SEARCH_BOUNDARY = 1704
放大,M_TOOLS_EXPAND = 1705
缩小,M_TOOLS_SHRINK = 1706
平移,M_TOOLS_RECENTER = 1702
信息查询,M_TOOLS_PNT_QUERY = 1707
标注,M_TOOLS_LABELER = 1708
拖放窗口,M_TOOLS_DRAGWINDOW = 1734
标尺,M_TOOLS_RULER = 1710
Draw工具条:
点符号,M_TOOLS_POINT = 1711
直线, M_TOOLS_LINE = 1712
折线,M_TOOLS_POLYLINE = 1713
弧,M_TOOLS_ARC = 1716
多边形,M_TOOLS_POLYGON = 1714
椭圆,M_TOOLS_ELLIPSE = 1715
矩形,M_TOOLS_RECTANGLE = 1717
圆角矩形,M_TOOLS_ROUNDEDRECT = 1718
文本,M_TOOLS_TEXT = 1709
框架,M_TOOLS_FRAME = 1719
增加节点,M_TOOLS_ADD_NODE = 1723
7、子定义 MapInfo快捷菜单
可以使用 MapBasic语句增加 /删除快捷菜单中的一个或多个
命令。
Alter Menu…Add Calling OLE 增加
Alter Menu…Remove 删除
可使用 Create Menu语句重新定义菜单,并使用,(-”代码作
为新菜单定义。
如删除 MapInfo地图窗口中的快捷菜单:
miApp.do "Create Menu ""MapperShortcut"" ID 17 as ""(- "" "
8、打印 MapInfo集成窗口
应用 MapBasic的,PrintWin”语句可以打印 MapInfo窗口。
MiApp.do,PrintWin”
也可先利用 MapBasic的,Save Window”语句输出一个窗口
图元文件 (WMF)来替代地图的打印,然后应用 VB的
,PrintForm”
9,错误捕获
VB,On Error GoTo
VC++,try ….catch….finally
10、终止 MapInfo的运行
通过 CreateObject()创建 MapInfo应用程序对象,如果
释放该对象变量,则终止 MapInfo的运行。所以 miApp应
该作为全局变量,如果是局部变量的话,子程序结束时,
miApp就会释放,MapInfo终止运行。
Set miApp =Nothing
二,MapInfo集成地图开发
2.3 回调( Callbacks)
1、回调概述
前面介绍了如何向 MapInfo发送命令,我们还希望
MapInfo能把信息发送到应用程序中。如当地图窗口改变时,
希望 MapInfo能通知应用程序,并告知改变的窗口 ID,程序
员可在应用程序中编写相应的响应代码。
这种获得 MapInfo发送回来的消息的通讯机制称作 回调 。
下面几种情况下,允许 MapInfo向客户应用程序发送信息,
( 1) 用户使用自定义工具与 MapInfo窗口进行交互。 如用
户在地图窗口中单击并拖动鼠标绘制一条直线,MapInfo可
以告诉客户程序用户选择的 x,y坐标;
( 2) 用户选择了菜单命令。 假如应用程序自定义了
MapInfo的快捷菜单,当用户从快捷菜单中选择了命令时,
MapInfo可以通知客户程序来调用该菜单事件;
( 3) 当地图窗口发生改变时。 如果用户选择了地图窗口中
的内容,(如增加或删除了图层,或漫游地图 ),MapInfo可以
告诉客户程序该 窗口的 ID号,与 MapBasic的特殊处理进程
winChangedHandler类似;
( 4) 当 MapInfo状态栏中的文本发生改变时。 MapInfo的状
态栏不会显示在集成地图窗口中,如果希望模拟 MapInfo的
效果,必须编写 代码 。无论状态栏文本发生何种变化,
MapInfo都能通知应用程序。
利用 OLE自动服务器功能完成回调。
2、如何使用 OLE回调
( 1)采用 VB4.0以上版本或其它能支持 OLE服务器的语言,创
建一个能定义一个或多个 OLE方法 的 类 ;
( 2)如果模拟 MapInfo的状态栏,创建 SetStatusText方法,对
该方法进行定义使其能获取一个 字符串变量 ;
( 3)如果希望在每次地图窗口改变时 MapInfo能通知客户程序,
创建 WindowContentsChanged方法,定义该方法能获取一个 4
字节 整数大小的 变量,代表该 MapInfo窗口的 ID号;
( 4)如果使用自定义菜单命令或按钮,希望 MapInfo能通知客
户程序,可以创建一个或多个 额外的方法,所定义的每一个方
法能获取一个 字符串变量 ;
( 5) 用自定义的类来创建对象,
Public myCallback As New CMyClass
( 6)在程序启动 MapInfo后,调用 MapInfo的 SetCallback方法,
然后指定该对象名:
mapinfo.SetCallback myCallback
( 7)如果希望当用户在使用自定义工具栏按钮时,MapInfo向
客户程序发出通知,可以自定义按钮,如:
Alter ButtonPad…Add Calling OLE
( 8)如果希望当用户使用菜单命令时,MapInfo向客户程序发
出通知,可以使用诸如, Alter Menu…Add Calling OLE”的
语句来 自定义菜单命令;
( 9) 在所定义的方法内,编制必要的处理程序来处理 MapInfo
传送来的变量 。
3、处理回调数据
在集成地图应用程序中,创建自定义的 MapInfo菜单命令和
工具按钮后,使用回调机制来处理 MapInfo发送给应用程序的
数据。当用户选择这些命令和按钮后,MapInfo向 OLE方法发
送一个 由逗号分隔的包含 8个元素的字符串 。
例如:
MI,-73.5548,42.122,F,F,-72.867702,43.025,202,
如果熟悉 MapBasic的 CommandInfo()函数, 那么很容易明
白该逗号分隔的字符串的内容 。 编写 MBX应用程序时是通过
调用 MapBasic处理程序的子过程句柄, 来实现自定义菜单命令
和自定义按钮的 。
在子过程句柄中, 通过调用 CommandInfo()函数来判断当前
事件的不同信息 。 如判定在 MapBasic编程中使用自定义绘制工
具按钮时是否按下 shift键 。
Log_variable=CommandInfo(CMD_INFO_SHIFT)
CommandInfo()函数的意义:
1 CMD_INFO_X 第 1点的 X坐标
2 CMD_INFO_Y 第 1点的 Y坐标
3 CMD_INFO_SHIF 按下 Shift
4 CMD_INFO_CTRL 按下 Ctrl
5 CMD_INFO_X 第 2点的 X坐标
6 CMD_INFO_Y 第 2点的 Y坐标
7 CMD_INFO_TOOLBTN 用户点击的 ButtonID
8 CMD_INFO_MENUITEM 用户点击的 MenuID
当创建自定义的菜单或按钮,并使用, Calling OLE方法名,
语句指定该菜单命令或按钮相应的方法后,MapInfo就会使
用上述 8个返回值构造一个由逗号分割的字符串 。该字符串始
终以, MI:”为前缀,通过该前缀,OLE服务器可以判断是
MapInfo调用了该方法。
MapInfo发送给方法的字符串结构如下:
,MI:”+”CommandInfo(1)”+,CommandInfo(2)”
+,CommandInfo(3)” +,CommandInfo(4)”
+,CommandInfo(5)” +,CommandInfo(6)”
+,CommandInfo(7)” +,CommandInfo(8)”
如果在集成地图应用程序中,MapInfo的快捷 菜单 中增加了
一个自定义菜单 (ID:101),则 MapInfo发送的字符串为,
MI:,,,,,,,101
如果用户创建了一个自定义 按钮,实现用户在地图窗口中
单击并拖动鼠标绘制一条直线,则 MapInfo发送的字符串为:
Mi:-10.26,42.12,F,F,-80.13,100.2,2002,
x1 y1 x2 y2 ButtonID,空值
如果为每个自定义的按钮指定了唯一的 ID,可以让按钮调
用同一个方法,然后在方法中通过检验字符串的第 7个元素,来
判断用户选择的是哪个按钮。
一旦 MapInfo将由逗号分割的字符串发送给应用程序的方法,
方法中必须增加代码来解析字符串,执行代码。
二,MapInfo集成地图开发
2.4 程序运行语句
1、运行 MapBasic应用程序 (MBX)或添加 MapInfo工作空间
Run Application file(可执行文件)
终止,Terminate Application
例如:
MiApp.do,Run Application,“C:\mapbasic\app\report.mbx”””
MiApp.do,Run Application,“parcels.wor”””
2、运行其他程序
Run Program Program_spec 命令字符串
例如,Run Program,notepad.exe readme.txt”
注意尽量避免多任务处理可能引起的冲突,可将 Run Program
语句放置在处理事件语句之后。
欢迎多提宝贵意见!
谢谢!