copyright © 2002 esri. all rights reserved. advanced arcobjects component development ii (c++)...
TRANSCRIPT
Copyright © 2002 ESRI. All rights reserved. Advanced ArcObjects Component Development II (C++)
ArcObjects/MFC applications
6-2Advanced ArcObjects Component Development II (C++)Copyright © 2002 ESRI. All rights reserved.
Lesson 6 overview
Application development in MFC
Advantages and disadvantages
Document architecture and MDI applications
ESRI ActiveX controls
Document and object persistence
Exercise 6: Simple MDI application
6-3Advanced ArcObjects Component Development II (C++)Copyright © 2002 ESRI. All rights reserved.
Stand-alone application development
First decide if this is the right direction - see Advanced ArcObjects Component Development I
A full ArcGIS install is still required
Stand-alone development licenses will be available
Question: How much of ArcMap do you want to rebuild?
6-4Advanced ArcObjects Component Development II (C++)Copyright © 2002 ESRI. All rights reserved.
Microsoft Foundation Classes (MFC)
Set of classes and templates that can be used for ArcObjects/Windows development
Supports OLE and provides easy access to COM objects
Structured storage documents
Many wizards: Class and Resource Wizards
Downside Large memory footprint
Somewhat outdated
6-5Advanced ArcObjects Component Development II (C++)Copyright © 2002 ESRI. All rights reserved.
Main frame
Toolbars
Child frame(s): SDI or MDI
Views: Map and TOC
Document
A MFC mapping application components
Instructor DemoInstructor Demo
6-6Advanced ArcObjects Component Development II (C++)Copyright © 2002 ESRI. All rights reserved.
Application architecture
CAoMapView
CAoTocView
CChildFrame
CMainFrame
*
1
1
OpenMapDocument()SaveMapDocument()
GetMapView()GetMapControl()GetMap()m_wndTocViewm_wndMapView SetMap()
GetActiveLayer()m_TocControl
m_ipMapm_ipActiveViewm_MapControl
CMDIApp CMDIDoc
GetActiveTool()SetActiveTooCursor()GetActiveMap()GetActiveToc()
6-7Advanced ArcObjects Component Development II (C++)Copyright © 2002 ESRI. All rights reserved.
Main frame: The foundation
CMainFrame – Parent window for the application
Supports child frame(s): SDI/MDI
Provides framework for User controls: Toolbars, tools, menus
Event sink to allow tools to be enabled
Get the active child framethis > MDIGetActive()
6-8Advanced ArcObjects Component Development II (C++)Copyright © 2002 ESRI. All rights reserved.
MFC documents
CDocument – Save and retrieve document data
CDocument::Serialize Save data into the file when the document is saved
Read data out when the document is opened
// AoMapMDIDoc.h : interface of the CAoMapMDIDoc class…void CAoMapMDIDoc::Serialize(CArchive& ar){
if (ar.IsStoring()){
// TODO: add storing code herear.WriteString(m_strUserData);ar.WriteObject(m_pSomeObject);
}else{
// TODO: add loading code herear.ReadString(&m_strUserData);ar.ReadObject(&m_pSomeObject);
}}
// AoMapMDIDoc.h : interface of the CAoMapMDIDoc class…void CAoMapMDIDoc::Serialize(CArchive& ar){
if (ar.IsStoring()){
// TODO: add storing code herear.WriteString(m_strUserData);ar.WriteObject(m_pSomeObject);
}else{
// TODO: add loading code herear.ReadString(&m_strUserData);ar.ReadObject(&m_pSomeObject);
}}
6-9Advanced ArcObjects Component Development II (C++)Copyright © 2002 ESRI. All rights reserved.
Child frames
CFrame – Parent window for views
Responsible for creating the view
Can support multiple views TOC, map, page layout, and table view
// ChildFrm.cpp : implementation of the CChildFrame class…
BOOL CChildFrame::OnCreateClient(LPCREATESTRUCT lpcs, CCreateContext* pContext) { // Create a splitter window: tree on left, map on right if( !m_wndSplitter.CreateStatic(this,1,2)) return FALSE;
if (m_wndSplitter.CreateView(0,0,RUNTIME_CLASS(CAoTocView), CSize(150,0),pContext))
if (m_wndSplitter.CreateView(0,1,RUNTIME_CLASS(CAoMapView), CSize(0,0),pContext))
m_wndSplitter.SetActivePane(0, 1); // Activate the map view
return TRUE;}
// ChildFrm.cpp : implementation of the CChildFrame class…
BOOL CChildFrame::OnCreateClient(LPCREATESTRUCT lpcs, CCreateContext* pContext) { // Create a splitter window: tree on left, map on right if( !m_wndSplitter.CreateStatic(this,1,2)) return FALSE;
if (m_wndSplitter.CreateView(0,0,RUNTIME_CLASS(CAoTocView), CSize(150,0),pContext))
if (m_wndSplitter.CreateView(0,1,RUNTIME_CLASS(CAoMapView), CSize(0,0),pContext))
m_wndSplitter.SetActivePane(0, 1); // Activate the map view
return TRUE;}
6-10
Advanced ArcObjects Component Development II (C++)Copyright © 2002 ESRI. All rights reserved.
Views
CView – Responsible for showing document data
Only one view is active at a timethis > GetActiveView()
When the document changes Call UpdateAllViews()
Common MFC view classesCFormView, CCtrlView, CEditView
CListView, CTreeView
6-11
Advanced ArcObjects Component Development II (C++)Copyright © 2002 ESRI. All rights reserved.
Views and ActiveX controls
MFC creates a CFormView class for controls
Use the Resource Dialog Editor to Create a wrapper class for control itself (e.g., CMapControl)
Wrap IDispatch calls for control members
Attaches the control window to the view
// AoMapView.h : interface of the CAoMapView class
class CAoMapView : public CFormView {…// Attributespublic:…
//{{AFX_DATA(CAoMapView)enum { IDD = IDD_MAPCONTROL };CMapControl m_MapControl;//}}AFX_DATA
// AoMapView.h : interface of the CAoMapView class
class CAoMapView : public CFormView {…// Attributespublic:…
//{{AFX_DATA(CAoMapView)enum { IDD = IDD_MAPCONTROL };CMapControl m_MapControl;//}}AFX_DATA
6-12
Advanced ArcObjects Component Development II (C++)Copyright © 2002 ESRI. All rights reserved.
ESRI controls
ESRI Map Control
ESRI Layout Control
3-D Analyst Control
Coming soon TOC
North arrow
Legend
Scale bar
6-13
Advanced ArcObjects Component Development II (C++)Copyright © 2002 ESRI. All rights reserved.
Maintaining an active tool
Use the MainFrame window Create accessor function – CMainFrame::GetActiveTool()
Sink command eventsOnUpdate() and OnCommand()
Similar to ICommand::Enabled and ICommand::OnClick
// MainFrm.cpp : implementation of the CMainFrame class…void CMainFrame::OnCommandZoomin() {
m_iIDActiveTool = ID_COMMAND_ZOOMIN;SetActiveToolCursor();
}
void CMainFrame::OnUpdateCommandZoomin(CCmdUI* pCmdUI)
pCmdUI->SetCheck(m_iIDActiveTool == ID_COMMAND_ZOOMIN); // Button depressedpCmdUI->Enable(EnableCommand(pCmdUI->m_nID));
}
// MainFrm.cpp : implementation of the CMainFrame class…void CMainFrame::OnCommandZoomin() {
m_iIDActiveTool = ID_COMMAND_ZOOMIN;SetActiveToolCursor();
}
void CMainFrame::OnUpdateCommandZoomin(CCmdUI* pCmdUI)
pCmdUI->SetCheck(m_iIDActiveTool == ID_COMMAND_ZOOMIN); // Button depressedpCmdUI->Enable(EnableCommand(pCmdUI->m_nID));
}
6-14
Advanced ArcObjects Component Development II (C++)Copyright © 2002 ESRI. All rights reserved.
Visual C++ resource editor
Application Wizard: Creates default tools and toolbars
Toolbar and Menu resource editor Add new, edit, modify, and configure user controls
Image resource editors Add, edit, and modify bitmaps, icons, cursors
All resources have a global ID name IDD_xxx, IDC_xxx, IDB_xxx, IDI_xxx,
6-15
Advanced ArcObjects Component Development II (C++)Copyright © 2002 ESRI. All rights reserved.
OLE structured storage: MXD and MXT
Storage is a file (document) Save user customizations
Storage can contain many streams
Can persist any object Must support IPersistStream
Visual Studio DocFile Viewer Example: Map Document (MXD)
6-16
Advanced ArcObjects Component Development II (C++)Copyright © 2002 ESRI. All rights reserved.
Writing to a custom document
// Create the storageIStoragePtr ipStorage;HRESULT hr = ::StgCreateDocfile(bsDocumentPath, STGM_DIRECT | STGM_READWRITE | STGM_CREATE | STGM_SHARE_EXCLUSIVE, 0, &ipStorage);
// Create an ObjectStream that will restore object associations correctly.IObjectStreamPtr ipObjectStream(CLSID_ObjectStream);
// Save the mapIStreamPtr ipStream;hr = ipStorage->CreateStream(L"Map Control Document", STGM_DIRECT | STGM_CREATE | STGM_WRITE | STGM_SHARE_EXCLUSIVE, 0, 0, &ipStream);
hr = ipObjectStream->putref_Stream(ipStream); hr = ipObjectStream->SaveObject(pMap); // Save the map into the document
// Create the storageIStoragePtr ipStorage;HRESULT hr = ::StgCreateDocfile(bsDocumentPath, STGM_DIRECT | STGM_READWRITE | STGM_CREATE | STGM_SHARE_EXCLUSIVE, 0, &ipStorage);
// Create an ObjectStream that will restore object associations correctly.IObjectStreamPtr ipObjectStream(CLSID_ObjectStream);
// Save the mapIStreamPtr ipStream;hr = ipStorage->CreateStream(L"Map Control Document", STGM_DIRECT | STGM_CREATE | STGM_WRITE | STGM_SHARE_EXCLUSIVE, 0, 0, &ipStream);
hr = ipObjectStream->putref_Stream(ipStream); hr = ipObjectStream->SaveObject(pMap); // Save the map into the document
::StgCreateDocfile – To create the storage (document)
::CreateStream – To create the stream
Save object into an ObjectStream
6-17
Advanced ArcObjects Component Development II (C++)Copyright © 2002 ESRI. All rights reserved.
Reading from a custom document
// Open the storageIStoragePtr ipStorage;HRESULT hr = ::StgOpenStorage(bsDocumentPath, 0, dwFlags, 0, 0, &ipStorage);
// Create an ObjectStream that will restore object associations correctly.IObjectStreamPtr ipObjectStream(CLSID_ObjectStream);
// Load the maps.IStreamPtr ipStream;hr = ipStorage->OpenStream(L"Map Control Document", 0, dwFlags, 0, &ipStream);if (SUCCEEDED(hr)) { hr = ipObjectStream->putref_Stream(ipStream); if (FAILED(hr)) return hr; IUnknown* pUnk; IMapPtr pMapInDoc;
hr = ipObjectStream->LoadObject((GUID*) &IID_IMap, 0, &pUnk); // Find obj by GUID pMapInDoc = pUnk; // Get a reference to the map}
// Open the storageIStoragePtr ipStorage;HRESULT hr = ::StgOpenStorage(bsDocumentPath, 0, dwFlags, 0, 0, &ipStorage);
// Create an ObjectStream that will restore object associations correctly.IObjectStreamPtr ipObjectStream(CLSID_ObjectStream);
// Load the maps.IStreamPtr ipStream;hr = ipStorage->OpenStream(L"Map Control Document", 0, dwFlags, 0, &ipStream);if (SUCCEEDED(hr)) { hr = ipObjectStream->putref_Stream(ipStream); if (FAILED(hr)) return hr; IUnknown* pUnk; IMapPtr pMapInDoc;
hr = ipObjectStream->LoadObject((GUID*) &IID_IMap, 0, &pUnk); // Find obj by GUID pMapInDoc = pUnk; // Get a reference to the map}
::StgOpenStorage – Open a storage (document)
Open a stream by name
Locate objects by GUID
6-18
Advanced ArcObjects Component Development II (C++)Copyright © 2002 ESRI. All rights reserved.
Retrieving objects from an MXD
// Open the storageIStoragePtr ipStorage;DWORD dwFlags = STGM_READ | STGM_TRANSACTED;HRESULT hr = ::StgOpenStorage(bsDocumentPath, 0, dwFlags, 0, 0, &ipStorage);
// Create an ObjectStream that will restore object associations correctly.IObjectStreamPtr ipObjectStream(CLSID_ObjectStream);dwFlags = STGM_READ | STGM_SHARE_EXCLUSIVE;
// Load the maps.IStreamPtr ipStream;hr = ipStorage->OpenStream(L"Maps", 0, dwFlags, 0, &ipStream);hr = ipObjectStream->putref_Stream(ipStream);LONG cMaps = 0;hr = ipObjectStream->Read(&cMaps, sizeof(cMaps), 0); // Ensure a map exists
if ((lIndex < 0) || (lIndex >= cMaps)) return E_INVALIDARG;
IUnknown* pUnk;IMapPtr pMapInDoc;for (int i = 0; i < cMaps; i++) // May be more than one map…{ hr = ipObjectStream->LoadObject((GUID*) &IID_IMap, 0, &pUnk); // Load each map if (i == lIndex) {
pMapInDoc = pUnk;*pMap = pMapInDoc; // Only take the first map at index 0return S_OK;
}}
// Open the storageIStoragePtr ipStorage;DWORD dwFlags = STGM_READ | STGM_TRANSACTED;HRESULT hr = ::StgOpenStorage(bsDocumentPath, 0, dwFlags, 0, 0, &ipStorage);
// Create an ObjectStream that will restore object associations correctly.IObjectStreamPtr ipObjectStream(CLSID_ObjectStream);dwFlags = STGM_READ | STGM_SHARE_EXCLUSIVE;
// Load the maps.IStreamPtr ipStream;hr = ipStorage->OpenStream(L"Maps", 0, dwFlags, 0, &ipStream);hr = ipObjectStream->putref_Stream(ipStream);LONG cMaps = 0;hr = ipObjectStream->Read(&cMaps, sizeof(cMaps), 0); // Ensure a map exists
if ((lIndex < 0) || (lIndex >= cMaps)) return E_INVALIDARG;
IUnknown* pUnk;IMapPtr pMapInDoc;for (int i = 0; i < cMaps; i++) // May be more than one map…{ hr = ipObjectStream->LoadObject((GUID*) &IID_IMap, 0, &pUnk); // Load each map if (i == lIndex) {
pMapInDoc = pUnk;*pMap = pMapInDoc; // Only take the first map at index 0return S_OK;
}}
6-19
Advanced ArcObjects Component Development II (C++)Copyright © 2002 ESRI. All rights reserved.
Limited use of ArcObjects?
Not all ArcObjects objects can be used outside of ArcMap and ArcCatalog
Any object tied to the application interfacesIMxApplication
IGxApplication
Some examples Property pages: Dependent on application and document
Window dialogs: Magnification and editing dialogs
Anything that depends on an application extension
6-20
Advanced ArcObjects Component Development II (C++)Copyright © 2002 ESRI. All rights reserved.
Exercise 6 overview
Integrate MapControl and TOC OCX
Add Zoom, Pan, and Identify tools
Add MXD support
Show the Layer property pages
Enable persistence to a Map Control Document (MCD)
Challenge: Transfer layers between frames
6-21
Advanced ArcObjects Component Development II (C++)Copyright © 2002 ESRI. All rights reserved.
Review
Why might you want to avoid writing stand-alone apps?
Which MFC class can you use to display the ESRI MapControl window?
How are Button events handled in MFC?
Describe the process of reading objects out of an MXD?
6-22
Advanced ArcObjects Component Development II (C++)Copyright © 2002 ESRI. All rights reserved.