用MO时如何自定义填充样式? (50分)

具体步骤:

1).注册和导入AFCustom Type Libray;

AFCustom Type Library定义了Custom Symbol(点Marker、线Line、面Fill)的框架。

(a).注册AFCustom Type Library(TLB)
Files->Open(*.tlb),打开AFCustom Type library(C:/Program files/Common Files/Esri/AFCust20.tlb文件)。
Delphi将会列出其中的对象。把这个窗口弄大点,点击窗口上部由边有个Register按钮,
(在Refresh旁边),这就算把AFCustom注册罗。

(b).导入AFCustom Type Library
Project->Import Type Library
在弹出的Type Library列表中找到AFCustom(Version2.0),然后按"Install"按钮。

2).创建一个Delphi ActiveX Dll 项目.
Files->New,选ActiveX标签页,选ActiveX Library;

3).创建一个Automation Object,这将作为你的符号处理对象。 点、线、填充各为一个Automation Object.

Files->New,选Activex标签页, 选Automation Object;会出来个框,在CoClass编辑框中,

输入你给这对象的命名,如:Mo2AsFill. 其它参数为缺省设置。

OK后会出个窗口,那是这个项目的Type Library List.

如果不出这窗口,用View->Type Library可以让它出现.

4).给你的项目命名.
在Type Libary窗口左边有个TreeView,点根(如:project1),在右边Attributes标签页,把缺省名
(如Project1)改为你所要的名(Mo2As),这个名将作为你的DLL的文件名,也是你的OleObjectServer的名,
将来要用Regsvr32对它注册,或导入Type Library时也要用到它。

5).指定所要引用的Type Library.
和上步一样,在Type Libary窗口左边有个TreeView,点根(如:Mo2As),在右边选择Uses标签页,有个列表
列出当前所引用的Type Library。按鼠标右键会弹出一个Popup Menu,选择Show All Type Libraries项。
从列表中找到AFCustom 2.0 ,打上个勾。

6).指定新建Interface所继承的Interface
(以Custom Fill为例)
还在Type Library窗口, 点击新建的Automation Object,以I打头,如IMoAsFill。把Parent Interface中
的IDispatch改为ICustomFill(从ComboBox中选),Delphi将会自动生成框架,保存项目,
这就完成一大半罗。

7).根据你所生成的对象不同,所要加的方法也不同,如ICustomFill必须有以下方法:
function SetupDC(hDC: Integer;
dpi:do
uble;
const pBaseSym: IDispatch): HResult;
stdcall;
function ResetDC(hDC: Integer): HResult;
stdcall;
function Draw(hDC: Integer;
var points: Integer;
var partCounts:Integer;
numParts: Integer): HResult;
stdcall;

但Delphi不会自动完成这些,需要自己添加。

打开Unit,(View->Unit->....),你可以从AfCumtom20_TLB中,或把本文上面这段Copy,

粘贴到类声明中Protected...end;
中间. 如:

TMo2AsFill = class(TAutoObject, IMo2AsFill)
protected
{ Protected declarations }
function SetupDC(hDC: Integer;
dpi:do
uble;
const pBaseSym: IDispatch): HResult;
stdcall;
function ResetDC(hDC: Integer): HResult;
stdcall;
function Draw(hDC: Integer;
var points: Integer;
var partCounts:Integer;
numParts: Integer): HResult;
stdcall;
end;



8).实现你的方法
以由调用程序指定的Bitmap文件为画刷填充为例。

implementation

uses
ComServ, Graphics, Classes;
var
FFillBitmap : TBitmap;
FOutline : Boolean;
FOutlineColor : TColor;
FBitmapFileName : WideString;
//位图文件名,将来还有增加Property来设置它

//
//源码比较简单,我就不解释了。
//
function TMo2ASFill.Draw(hDC: Integer;
var points, partCounts: Integer;
numParts: Integer): HResult;
var
aCanvas : TCanvas;

begin

aCanvas := TCanvas.Create;
aCanvas.Handle := hDC;
if FOutline then

begin

aCanvas.Pen.Color := FOutlineColor;
aCanvas.Pen.Width := 1;
aCanvas.Pen.Style := psSolid;
end
else

aCanvas.Pen.Style := psClear;

aCanvas.Brush.Bitmap := FFillBitmap;
PolyPolygon( aCanvas.Handle, points, partCounts, numParts );
aCanvas.Free;

Result := 0;
end;


function TMo2ASFill.ResetDC(hDC: Integer): HResult;
begin

FFillBitmap.Free;
Result := 0;
end;


function TMo2ASFill.SetupDC(hDC: Integer;
dpi:do
uble;
const pBaseSym:
IDispatch): HResult;
begin


FOutline := Variant( pBaseSym ).Outline;
FOutlineColor := Variant( pBaseSym ).OutlineColor;

FFillBitmap := TBitmap.Create;
FFillBitmap.LoadFromFile(FBitmapFileName);
Result := 0;
end;


9).添加Property和Method
以添加Property设置位图文件名为例。
还在Type Library窗口, 点击新建的Automation Object,以I打头,如IMoAsFill。
右键弹出菜单New->Property或按 Property按钮。Delphi会自动为新建的
Property产生缺省名Property1和相应的Put和Get方法。
把新建的Property名该为BItmapName。并把Put和get方法的Type改为BSTR,
(BSTR在Delphi里就是WideString)。
保存项目后在你的Unit里找到Set_BitmapName和Get_BitmapName,作以下修改:

function TMo2AsFill.Get_BitmapName: WideString;
begin

Result := FBitmapFileName;
end;


procedure TMo2AsFill.Set_BitmapName(const Value: WideString);
begin

FBitmapFileName := Value;
end;




10).编译和注册新建Active Dll

Propject->Build后Delphi会生成个DLL文件。

注册有两种方法:
(a). Regsvr32 DllFileName;
(b). 在该项目的Type Library窗口中按Register按钮。(和注册AFCustom一样)

11).导入新建的Type Library
Project->Type Library;
找到新建的Type Library,(如:Mo2As), Install后,
在Delphi的ActiveX TAB中会多出一个Component(如Mo2AsFill)

12.绘图时如何调用
在你的Application中,把新建的Component(Mo2AsFill)拽到你的Form上或直接在
uses中添加。
下面是调用实例,假设你的Map名为MapMain,第0图层是个IMoMapLayer并且是个Polygon。
用C:/Pat1.bmp位图文件为画刷填充。

var
aMapLayer : IMoMapLayer;
MyFillSymbol: IMo2AsFill;
begin

//
//创建Fill Symbol
//
MyFillSymbol := CoMo2AsFill.Create;
//
//设置Custom Fill中使用的画刷位图文件名
//
MySymbol.BitmapName := 'C:/Pat1.bmp';

//取图层
aMapLayer := IMoMapLayer(MapMain._Layers.Item(0));

//设置多边界色
aMapLayer.Symbol.OutlineColor := RGB(255,0,0);
//
//指定Custom Fill对象
//
aMapLayer.Symbol.Custom := MyFillSymbol;
//
//重画
MapMain.refresh;
end;




水平有限,有许多错误,请大家谅解和指正。由于上网不便,常常不能及时答复,请谅解!

 
非常谢谢!
 
to tanyg and 黑天鹅: 你们好像好长时间没有上网了,我现在也碰到填充问题,如果你们有机会
看到这个帖子,请将你们解决问题的方法告诉我,十分感谢!
 
我的E-mai地址是taozhong@fzu.edu.cn,希望能跟你们取得联系
 
借你的宝地一用
我用DELPHI+MapObject开发GIS,但不知道怎么用Delphi编写在地图中执行空间数据查询。
比如:在地图中按地名、单位名称等信息查询并用高亮度显示结果。
 
我现在也在做这方面的东西
很多基础的东西都不是很清楚,比如说图形的数据信息都在dbf文件中,文件中字段以及如何查看都不是很清楚,希望大虾们赐教!
 
顶部