在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")