frmQueryAttribe.lblInfo.Caption = ""
End If
End Sub
Private Sub ITool_OnMouseMove(ByVal button As Long, ByVal shift As Long, ByVal X As Long, ByVal Y As Long)
End Sub
Private Sub ITool_OnMouseUp(ByVal button As Long, ByVal shift As Long, ByVal X As Long, ByVal Y As Long)
End Sub
Private Sub ITool_Refresh(ByVal hdc As esriSystem.OLE_HANDLE)
End Sub
工具条实现ItoolBarDef接口的核心代码如下:
'类模块:ToolBarForDLG
Option Explicit
Implements IToolBarDef
Private Property Get IToolBarDef_Caption() As String
IToolBarDef_Caption = "DLG工具条 刘新定2007.7.3"
End Property
Private Sub IToolBarDef_GetItemInfo(ByVal pos As Long, ByVal itemDef As esriSystemUI.IItemDef)
Select Case pos
Case 0
itemDef.ID = "LxdArcMap.cmdOpenCoverage"
Case 1
itemDef.ID = "LxdArcMap.toolQueryAttribe"
Case 2
itemDef.Group = True
itemDef.ID = "LxdArcMap.cmdDockWinTest"
End Select
End Sub
Private Property Get IToolBarDef_ItemCount() As Long
IToolBarDef_ItemCount = 3
End Property
Private Property Get IToolBarDef_Name() As String
IToolBarDef_Name = "DLG工具条"
End Property
菜单实现IMenuDef、 IRootLevelMenu两个接口的核心代码如下:
'类模块:MenuForDLG.cls
Option Explicit
Implements IMenuDef
Implements IRootLevelMenu
Private Property Get IMenuDef_Caption() As String
IMenuDef_Caption = "DLG菜单"
End Property
Private Sub IMenuDef_GetItemInfo(ByVal pos As Long, ByVal itemDef As esriSystemUI.IItemDef)
Select Case pos
Case 0
itemDef.ID = "LxdArcMap.cmdOpenCoverage"
Case 1
itemDef.Group = True
itemDef.ID = "LxdArcMap.cmdDockWinTest"
Case 2
itemDef.Group = True
itemDef.ID = "LxdArcMap.cmdAbout"
End Select
End Sub
Private Property Get IMenuDef_ItemCount() As Long
IMenuDef_ItemCount = 3
End Property
Private Property Get IMenuDef_Name() As String
IMenuDef_Name = "DLG菜单"
End Property
泊钨窗实现IDockableWindowDef 接口,代码如下:
'类模块:dockwinTest.cls
Option Explicit
Implements IDockableWindowDef
Dim WithEvents mDoc As MxDocument '定义一个带事件的文档变量以接收文档改变事件
Private winDock As frmDockWinTest
Private Sub Class_Initialize()
Set winDock = New frmDockWinTest '建立新的窗口表单
End Sub
Private Sub Class_Terminate()
Set winDock = Nothing
End Sub
Private Property Get IDockableWindowDef_Caption() As String
IDockableWindowDef_Caption = "泊钨窗测试 刘新定2007.7.4"
End Property
Private Property Get IDockableWindowDef_ChildHWND() As esriSystem.OLE_HANDLE
IDockableWindowDef_ChildHWND = winDock.图形容器.hwnd 'frmDockWinTest.图形容器.hwnd
End Property
Private Property Get IDockableWindowDef_Name() As String
IDockableWindowDef_Name = "泊钨窗测试"
End Property
Private Sub IDockableWindowDef_OnCreate(ByVal hook As Object)
Set m_pArcMapApp = hook '获得Arcmap的application实例指针,将其保存到全局变量中
Set mDoc = m_pArcMapApp.Document '保存文档对象
Dim pDoc As IMxDocument
Set pDoc = m_pArcMapApp.Document
Set winDock.TheActiveView = pDoc.FocusMap '设置泊坞窗保存当前视图指针
End Sub
Private Sub IDockableWindowDef_OnDestroy()
'MsgBox "Destroy 泊钨窗"
Unload winDock
End Sub
Private Property Get IDockableWindowDef_UserData() As Variant
End Property
'视图改变时重设表单中的m_pActiveView指针,以使地图控件与当前地图同步
Private Function mDoc_ActiveViewChanged() As Boolean
Dim pDoc As IMxDocument
Set pDoc = m_pArcMapApp.Document
Set winDock.TheActiveView = pDoc.FocusMap
winDock.InitLayer '初始化:地图控制加入图层
End Function
'关闭文档时
Private Function mDoc_CloseDocument() As Boolean
Dim pDoc As IMxDocument
Set pDoc = m_pArcMapApp.Document
Set winDock.TheActiveView = Nothing
End Function
'地图改变时重设表单中的m_pActiveView指针,以使地图控件与当前地图同步
Private Function mDoc_MapsChanged() As Boolean
Dim pDoc As IMxDocument
Set pDoc = m_pArcMapApp.Document
Set winDock.TheActiveView = pDoc.FocusMap
winDock.InitLayer '初始化:地图控制加入图层
End Function
'新建文档时重设表单中的m_pActiveView指针,以使地图控件与当前地图同步
Private Function mDoc_NewDocument() As Boolean
Dim pDoc As IMxDocument
Set pDoc = m_pArcMapApp.Document
Set winDock.TheActiveView = pDoc.FocusMap
End Function
'打开文档时重设表单中的m_pActiveView指针,以使地图控件与当前地图同步
Private Function mDoc_OpenDocument() As Boolean
Dim pDoc As IMxDocument
Set pDoc = m_pArcMapApp.Document
Set winDock.TheActiveView = pDoc.FocusMap
winDock.InitLayer '初始化:地图控制加入图层
End Function
其他窗体模块的实现代码在这不再列表。对于以上接口的实现而言,最重要的是OnCreate事件,当应用创建COM对象时,会将一个应用本身的指针传递给COM对象,COM对象可以保存些指针,在以后的动作中使用,从而达到了在应用与COM对象之间互相通信的目的。故在一个全局模块中定义如下变量:
Public m_pArcMapApp As IApplication '全局应用指针,在自定义UI类的OnCreate中进行保存。
最后,编译生成DLL文件。
2.安装服务器组件
首先,启动ArcMap,选中菜单[Tools]中的[Customize…]项,显示如图2所示的对话框。

图2 选项设置
然后,点选按钮[Add from file…],浏览到我们编写的ActiveX DLL文件,ArcMap会提示在我们编写的组件库中找到如图3组件。

图3 显示组件
按[OK]确认。工具条和菜单及工具按钮等会出现在对话框中。选中自定义的工具条,则该工具条在ArcMap的窗口中出现。该工具条可以悬浮,也可以组合到其他工具条中。点选Commands面板,可以看到我们创建的工具按钮和交互工具:点中Commands面板中的[DLG菜单]将其拖到菜单区中,它将成为ArcMap的一个菜单。现在可以开始使用我们扩充的功能了。
由上面步骤可见,在修改定制时,ArcMap会自动对组件进行注册,下次启动ArcMap时,我们扩充的工具条和菜单会被自动调用。一个例外:其中鹰视泊钨窗需进行Dockable Windows种类注册,方可显示,注册界面如图4所示。

图4 注册界面
完整的运行界面如下图5所示。

图5 程序运行效果
测试环境:Windows XP 中文版 + Visual Basic 6.0 中文版 + ArcGIS9.2,通过测试。
四、结语
COM是一个功能十分强大同时也十分复杂的体制,它在很大程度上满足了软件开发人员以“搭积木”的形式构建软件系统的理想,为软件重用和功能扩充提供了很好的途径。COM主要用于微软的平台,而且也不是一项新技术,但对于微软不断推出的DCOM、COM+、.NET技术而言,COM可以说是它们的奠基石。与COM并行的技术还有CORBA、EJB,它们是由Sun提出来的,适用的操作系统平台更广,但可以用于开发的语言则有限,EJB主要用Java开发,而CORBA可以用Delphi等来开发
|