Arcreader Arcobjects
Arcreader Arcobjects
ArcReader
Mark Cederholm
Unisource Energy Services
Why ArcReader?
Free deployment for field applications
Fully disconnected apps: no need for
ArcGIS Server or Mobile
ArcMap-quality cartography
But: out-of-the-box functionality is limited
Workaround: create a custom object that
resides in the map and can be persisted to
the PMF
A custom ArcReader object:
Create a COM object that implements
IPersistVariant
In ArcMap, assign the PageLayout as a
member variable which is saved and
loaded in IPersistVariant
Attach the object to some point of
persistence in the map, such as a custom
layer or the CustomProperty of a graphic
element
Problem: how to communicate with the
custom object?
Application architecture
The ArcReader control resides The actual map resides
in the main application in a separate process
called ArcReaderHost
<StructLayout(LayoutKind.Sequential)> _
Private Structure COPYDATASTRUCT
Public dwData As IntPtr
Public cbData As Integer
Public lpData As IntPtr
End Structure
b.Serialize(stream, DataString)
stream.Flush()
iDataSize = stream.Length
ReDim bytes(iDataSize - 1)
stream.Seek(0, SeekOrigin.Begin)
stream.Read(bytes, 0, iDataSize)
stream.Close()
pData = Marshal.AllocCoTaskMem(iDataSize)
Marshal.Copy(bytes, 0, pData, iDataSize)
cds.lpData = pData
cds.cbData = iDataSize
cds.dwData = New IntPtr(100)
Deserializing data
Dim cds As New COPYDATASTRUCT
Dim cdsType As Type
Dim iDataSize As Integer
Dim bytes() As Byte
Dim b As New BinaryFormatter
Dim stream As MemoryStream
Dim sData As String
cdsType = cds.GetType
cds = CType(m.GetLParam(cdsType), COPYDATASTRUCT)
iDataSize = cds.cbData
ReDim bytes(iDataSize)
Marshal.Copy(cds.lpData, bytes, 0, iDataSize)
stream = New MemoryStream(bytes)
sData = b.Deserialize(stream)
TestHostClass
<ComClass(TestHostClass.ClassId, TestHostClass.InterfaceId, _
TestHostClass.EventsId), ProgId("TestHost.TestHostClass")> _
Public Class TestHostClass
Implements ITestHost
Implements IPersistVariant
...
Private m_pPageLayout As IPageLayout
Private WithEvents m_Communicator As Communicator
Private m_sData As String
...
End Class
Initializing (in ArcMap)
def AddTestHost():
. . .
# Get application and install TestHost
pApp = GetApp()
pFact = CType(pApp, esriFramework.IObjectFactory)
pDoc = pApp.Document
pMxDoc = CType(pDoc, esriArcMapUI.IMxDocument)
pLayout = pMxDoc.PageLayout
pUnk = pFact.Create(CLSID(TestHost.TestHostClass))
pTestHost = CType(pUnk, TestHost.ITestHost)
bResult = pTestHost.Init(pLayout)
print bResult
Main Application (TestApp)
TIP: Creating the ArcReader control programmatically avoids
consuming a Publisher license at design time
http://www.pierssen.com/arcgis/misc.htm