代码名称:《Mapbasic高级编程技术》资料

作者/收集者:2721218

开发环境:MapBasic

代码:

在VB6中使用callback

我将MapBasic提供的关于如何在Visual Basic 中使用CallBack的样例程序,在VB6中打开运行时,VB会报出如下的错误信息:
“实时错误 98:一个属性或方法调用不能包含对一个私有对象的调用,无论是作为参数还是返回值。” Why?
Re:
这个错误信息完全是由用户的 VisualBasic 调试环境设置不当造成的,与MapBaic提供的程序无关。
解决如下:由 “工程” > “工程属性” 进入工程属性对话框,并进行如下的设置。
通用:工程类型,ActiveX EXE;启动对象 Sub Main;升级ActiveX 控件。
生成:删除有关未使用的ActiveX控件的信息
部件:启动模式,独立方式。
调试:启动工程时等待创建部件。
如果用户还未在自己的工程中建立 Sub Main,则应当在模块中建立一个 Sub Main过程。

在 Delphi 中调用 callback

在用Delphi调用MapBasic的Callback时,Delphi的函数并未被调用.我是用
Delphi中的ActiveX作为Callback类,是否能提供关于Callback的Delphi例子."。
答:我想你在Delphi中定义一个包含OLE事件的类后,应该把自己定义的Delphi函数名在这个类程序中声明一下,作为一个OLE对象(我估计这个函数是你自己的custom command),再在Delphi应用程序中用map application给这个对象赋予一个ID号,就可以调用了。我手上有一段例子,是用map application的setcallback进行调用的,copy给你,希望有所启发:
{以下这个单元用来定义包含OLE事件的类并声明你自己定义的Delphi函数名}
unit MyAuto;
interface
uses OleAuto,forms,windows,controls,messages,sysutils,classes;
type
TMyAuto = class(TAutoObject)
private
FMyProp: string;
function GetMyProp: string;
procedure SetMyProp(S: string);
public
constructor Create; override;
automated
procedure querytool(s:string); // 你自己定义的对象名
property MyProp: string read GetMyProp write SetMyProp;
end;
implementation
uses
Dialogs;
constructor TMyAuto.Create;
begin
inherited Create;
end;

procedure TMyAuto.SetMyProp(S: string);
begin
FMyProp := S;
end;

procedure TMyAuto.querytool(s:string);
begin
fgdmain.searchpoint(s); //Delphi程序中调用的函数名
end;

function TMyAuto.GetMyProp: string;
begin
Result := FMyProp;
end;

procedure RegisterMyAuto;
const
AutoClassInfo: TAutoClassInfo = (
AutoClass: TMyAuto;
ProgID: 'AUTOPROJ.MyAuto';
ClassID: '{FE67CF61-2EDD-11CF-B536-0080C72EFD43}';
Description: 'Sam';
Instancing: acInternal);
begin
Automation.RegisterClass(AutoClassInfo);
end;

initialization
RegisterMyAuto;
end.

{以下是在Delphi应用程序中调用,因程序太长,我就不全盘copy了}:
procedure Tform1.FormCreate(Sender: TObject);
var myauto1:tmyauto; mi,miresp:variant;
begin
mi:=createOleObject('mapinfo.application');
myauto1:=Tmyauto.create;
miresp:=myauto1.oleobject;
mi.do('set application window '+ intTostr(handle));
mi.setcallback (miresp); //在mbapplication中只有setcallback调用OLE对象
mi.do('Create Buttonpad "Callback" As Toolbutton ID 2001 Cursor 138 Calling OLE "QueryTool"'); //此处ID号你可任意指定。
end;

procedure Tfgdmain.searchPoint(s:string);//你自己定义的完成某种mapinfo 功能的函数,其中s 是你在图形上点击以后产生的包含x、y坐标信息的字符串。
var x,y,cmd : string;
i:integer;
mi_obj,mi_rid:string;
begin
delete(s,1,3);
i:=pos(',',s);
x:=copy(s,1,i-1);
delete(s,1,i);
i:=pos(',',s);
y:=copy(s,1,i-1);
cmd:='searchPoint( frontWindow() , ' + x + ' , ' +y+ ' )';
id:=mi.eval(cmd);
mi_obj:=mi.eval('searchinfo(1,1)');
if mi_obj='sctq_gx' then
begin
mi_rid:=mi.eval('searchinfo(1,2)');
mi.do('fetch rec '+mi_rid+' from '+mi_obj) ;
id:=mi.eval(mi_obj+'.col1');
popupmenu1.Popup(300,200);
end;
end;

设置地图窗口经纬度坐标单位

我们先来看一下两个 MapBasic 语句。
Set Map XY Units unitname:该语句用来为当前地图窗口设置X,Y坐标单位。
Set Map CoordSys NonEarth Units unitname:该语句用来设定当前地图的
投影方式。如果针对当前地图窗口执行了如下的一条语句:
Set Map XY Units "m" CoordSys NonEarth Units "m",
此时,如果你利用 "地图" > "选项" 来查看当前地图窗口的属性,你会发现
当前地图窗口的坐标单位为“m”,投影方式为“Non-Earth(m)”。

所以如果用户在新建一个Non-Earth(Km)投影 Bounds (0,0)(100,100)的图层后,
欲利用MapBasic语句向其中增加地图对象时,或是想通过程序从该地图上获取点的
X,Y坐标信息,则一定要先利用
set map Window frontwindow() xy units "Km" coordsys NonEarth Units "mm"

Set Map XY Units "mm" Distance Units "mm" CoordSys NonEarth Units "mm"

来初置MapBasic的缺省坐标系统,否则会由于MapBasic的初置投影系统与用户地图窗口的投影
系统不一致,而导致MapBasic程序的异常结果。对于其它投影方式也都应当进行同样的处理。

如何在VB中创建Mapinfo的地图图例

Question:
Is it possible to re-parent a cartographic legend in an Integrated Mapping Application? Reading the
MapBasic Help there is a topic on "Re-parenting Legends and Other Special Windows" but it refers to
a standard Legend Window only (which works fine) not a cartographic legend.

Answer:

There is a problem in MapInfo Professional relating to this but it does not completely prevent the
cartographic legend window from being re-parented. The window is created, but it is created invisible.
The workaround is to obtain the hWnd of the cartographic legend window and use this value in a call
to ShowWindow.

Declare Function ShowWindow Lib "user32" Alias "ShowWindow" (ByVal hwnd As Long,
ByVal nCmdShow As Long) As Long
Public Const SHOW_FULLSCREEN = 3
Public Const SHOW_ICONWINDOW = 2
Public Const SHOW_OPENNOACTIVATE = 4
Public Const SHOW_OPENWINDOW = 1

The sequence of calls would look something like this:

mapinfo.Do "Set Next Document Parent " & Picture1.hWnd & " Style 1"
mapinfo.Do "Create Cartographic Legend From Window " & mapwinid & " Frame From Layer 1"
hWnd = mapinfo.Eval("WindowInfo(0,12)")
rc = ShowWindow(hWnd, SHOW_OPENNOACTIVATE)

如何提高点的坐标精度

1. 在mapbaic中如果想获取地图中某个固定点的坐标,最好不要采用通过鼠标点击,然后用
CommandInfo(CMD_INFO_X)和CommandInfo(CMD_INFO_Y)来获取该点的坐标。应当:
先利用selector 工具选中该点,再利用CentroidX(selection.obj) , CentroidY(selection.obj),来确定该点的坐标。

2.现在MapBasic 能返回的坐标值的最高精度为:小数点后6位。

假定一个区域其经度值在112度左右,纬度在32度左右。为了提高坐标值的精度,
应作如下的处理:

dim x,y as float
x=Format$((commandinfo(cmd_info_x)-112),"##.######")+112
y=Format$((commandinfo(cmd_info_x)-32),"##.######")+32

如何去掉 Mapinfo 的软件封面

利用VB来实现此功能:
1。新建一个VB工程,包含一个Form(FrmSplash)做应用程序的封面,一个模块(名叫Module1)。
2。在FrmSplash上添加一个时钟控件(Timer1),将其Interval设为1000。
3。在Timer_click()事件中加入如下代码:

Private Sub Timer1_Timer()
If i >= 3 Then
Unload frmsplash
Exit Sub
End If
i = i + 1
End Sub

4。在Module1中加入如下代码:

Sub main()
frmsplash.Show
Dim a As Double
a = Shell("C:\MapInfo\Professional\mapinfow.exe -nosplash C:\MapInfo\Professional\1.mbx", vbNormalFocus)
End Sub

如何利用Mapbasic语言打开bmp图像

1.首先向tab文件中写入一些相关信息
open file "D:\test\bmp\" & danyuan_name & ".tab" for output as #1
print #1, "!table"
print #1, "!version 300"
print #1, "!charset WindowsSimpChinese"
print #1, ""
print #1, "Definition Table"
print #1, " File "& """" & danyuan_name & ".bmp" & """"
print #1, " Type " & """" & "RASTER" & """"
print #1, " (0,0) (0,0) Label " & """""" & ","
print #1, " (1,0) (1,0) Label """","
print #1, " (0,1) (0,1) Label """""
print #1, " CoordSys NonEarth Units " & """" & "ft" & """"
print #1, " Units " & """" & "ft" & """"
close file #1

2.打开该tab文件(表)
Open Table "D:\test\bmp\" & danyuan_name & ".tab" Interactive
Map From "_" & danyuan_name 或者:Map From danyuan_name

关于Message 窗口的各种使用问题

To clear the Message window, print a string which includes the form-feed character (code 12):

Print Chr$(12) 'This statement clears the Message window

By embedding the line-feed character (code 10) in a message, you can force a single message to be split onto two or more lines. The following Print statement produces a two-line message:

Print "Map Layers:" + Chr$(10) + " World, Capitals"

The Print statement converts each Tab character (code 09) to a space (code 32).

Example

The following example displays the Message window, sets the window's size (three inches wide by one inch high), sets the window's font (Helvetica, bold, 10-point), and prints a message to the window.

Include "MAPBASIC.DEF" ' needed for color name 'BLUE'
Open Window Message ' open Message window
Set Window Message Font ("Helv", 1, 10, BLUE) ' Helvetica bold...
Position (0.25, 0.25) ' place in upper left
Width 3.0 ' make window 3" wide
Height 1.0 ' make window 1" high
Print "MapBasic Dispatcher now on line"

vb 和 MapBasic 变量的互相赋值

1。如何在VB中,对利用MapBasic语句定义的变量进行赋值?

olemap.Do "dim a as string"
olemap.Do "a = ""abd df fsd c !!"""

2。如何将VB程序中的变量 VBVar 的值赋给在 MapBasic 中定义的变量 MBVar?

Dim b As String
b = """addd kkll jjj !"""
olemap.Do "dim a as string"
olemap.Do "a = " & b

3。如何将MapBasic程序中的变量 MBVar 的值赋给在 VB 中定义的变量 VBVar?
Dim b As String
olemap.Do "dim a as string"
olemap.Do "a = ""abd df fsd c !!"""
b = olemap.Eval("a")