Copyright © 2002 ESRI. All rights reserved. Advanced ArcObjects Component Development II (C++)...

22
Copyright © 2002 ESRI. All rights reserved. Advanced ArcObjects Component Development II (C++) ArcObjects/MFC applications

Transcript of Copyright © 2002 ESRI. All rights reserved. Advanced ArcObjects Component Development II (C++)...

Page 1: Copyright © 2002 ESRI. All rights reserved. Advanced ArcObjects Component Development II (C++) ArcObjects/MFC applications.

Copyright © 2002 ESRI. All rights reserved. Advanced ArcObjects Component Development II (C++)

ArcObjects/MFC applications

Page 2: 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

Page 3: Copyright © 2002 ESRI. All rights reserved. Advanced ArcObjects Component Development II (C++) ArcObjects/MFC applications.

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?

Page 4: Copyright © 2002 ESRI. All rights reserved. Advanced ArcObjects Component Development II (C++) ArcObjects/MFC applications.

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

Page 5: Copyright © 2002 ESRI. All rights reserved. Advanced ArcObjects Component Development II (C++) ArcObjects/MFC applications.

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

Page 6: Copyright © 2002 ESRI. All rights reserved. Advanced ArcObjects Component Development II (C++) ArcObjects/MFC applications.

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()

Page 7: Copyright © 2002 ESRI. All rights reserved. Advanced ArcObjects Component Development II (C++) ArcObjects/MFC applications.

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()

Page 8: Copyright © 2002 ESRI. All rights reserved. Advanced ArcObjects Component Development II (C++) ArcObjects/MFC applications.

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);

}}

Page 9: Copyright © 2002 ESRI. All rights reserved. Advanced ArcObjects Component Development II (C++) ArcObjects/MFC applications.

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;}

Page 10: Copyright © 2002 ESRI. All rights reserved. Advanced ArcObjects Component Development II (C++) ArcObjects/MFC applications.

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

Page 11: Copyright © 2002 ESRI. All rights reserved. Advanced ArcObjects Component Development II (C++) ArcObjects/MFC applications.

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

Page 12: Copyright © 2002 ESRI. All rights reserved. Advanced ArcObjects Component Development II (C++) ArcObjects/MFC applications.

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

Page 13: Copyright © 2002 ESRI. All rights reserved. Advanced ArcObjects Component Development II (C++) ArcObjects/MFC applications.

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));

}

Page 14: Copyright © 2002 ESRI. All rights reserved. Advanced ArcObjects Component Development II (C++) ArcObjects/MFC applications.

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,

Page 15: Copyright © 2002 ESRI. All rights reserved. Advanced ArcObjects Component Development II (C++) ArcObjects/MFC applications.

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)

Page 16: Copyright © 2002 ESRI. All rights reserved. Advanced ArcObjects Component Development II (C++) ArcObjects/MFC applications.

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

Page 17: Copyright © 2002 ESRI. All rights reserved. Advanced ArcObjects Component Development II (C++) ArcObjects/MFC applications.

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

Page 18: Copyright © 2002 ESRI. All rights reserved. Advanced ArcObjects Component Development II (C++) ArcObjects/MFC applications.

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;

}}

Page 19: Copyright © 2002 ESRI. All rights reserved. Advanced ArcObjects Component Development II (C++) ArcObjects/MFC applications.

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

Page 20: Copyright © 2002 ESRI. All rights reserved. Advanced ArcObjects Component Development II (C++) ArcObjects/MFC applications.

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

Page 21: Copyright © 2002 ESRI. All rights reserved. Advanced ArcObjects Component Development II (C++) ArcObjects/MFC applications.

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?

Page 22: Copyright © 2002 ESRI. All rights reserved. Advanced ArcObjects Component Development II (C++) ArcObjects/MFC applications.

6-22

Advanced ArcObjects Component Development II (C++)Copyright © 2002 ESRI. All rights reserved.