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

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

Embed Size (px)

Citation preview

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

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

Advanced ArcObjects/ATL applications

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

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

Lesson 4 overview

Integrated component solutions

Dockable windows

Custom layers

Property pages

Persistence

Exercise 4: Great circle custom layer

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

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

ArcObjects component integration

Applications often require integrating many objects

Logical groupings

1. External: Commands, toolbars, property pages, windows, layers

2. Internal: Application extensions, filters, persistence

3. Database: Custom features and class extensions

IExtension

Extension

DockableWindow

Command

Toolbar

IExtensionConfig

ICustom ClassExtension

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

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

Application startup revisited

1. Application

2. Document

3. Extensions

4. New or existing document

5. Registered dockable windows are created

6. Commands and toolbars

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

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

Dockable windows

Application-level customization

Application manages window creation

Visible state is saved in .mxt or .mxd

Show and hide window with a tool

Instructor DemoInstructor Demo

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

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

Implementing dockable windows

IDockableWindowDef OnCreate – Passed in an application reference when created

ChildHWND – Provide a child hWnd source

UserData – Window can maintain user data if necessary

// ICAoVBDockWindowpublic:// IDockableWindowDef

STDMETHOD(OnCreate)(IDispatch * hook);STDMETHOD(get_ChildHWND)(OLE_HANDLE * hWnd);STDMETHOD(get_Name)(BSTR * Name);STDMETHOD(get_Caption)(BSTR * Caption);STDMETHOD(OnDestroy)();STDMETHOD(get_UserData)(VARIANT * data);

private:IApplicationPtr m_ipApp;OLE_HANDLE m_childHwnd; //Child window

// ICAoVBDockWindowpublic:// IDockableWindowDef

STDMETHOD(OnCreate)(IDispatch * hook);STDMETHOD(get_ChildHWND)(OLE_HANDLE * hWnd);STDMETHOD(get_Name)(BSTR * Name);STDMETHOD(get_Caption)(BSTR * Caption);STDMETHOD(OnDestroy)();STDMETHOD(get_UserData)(VARIANT * data);

private:IApplicationPtr m_ipApp;OLE_HANDLE m_childHwnd; //Child window

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

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

Consuming VB window components

// PreviewDockWindow.h : Declaration of the CPreviewDockWindow

#import "..\AoVBServer\AoLib_VBServer.dll" raw_interfaces_only, raw_native_types, no_namespace, named_guids

HRESULT CAoDockWindow::FinalConstruct(){

return m_ipVBPreviewer.CreateInstance(CLSID_CAoWindowServer);}

STDMETHODIMP CAoDockWindow::get_ChildHWND(OLE_HANDLE * hWnd){

if (hWnd == NULL) return E_POINTER;m_ipVBPreviewer->get_hWnd(hWnd); // Get window from VB componentreturn S_OK;

}

// PreviewDockWindow.h : Declaration of the CPreviewDockWindow

#import "..\AoVBServer\AoLib_VBServer.dll" raw_interfaces_only, raw_native_types, no_namespace, named_guids

HRESULT CAoDockWindow::FinalConstruct(){

return m_ipVBPreviewer.CreateInstance(CLSID_CAoWindowServer);}

STDMETHODIMP CAoDockWindow::get_ChildHWND(OLE_HANDLE * hWnd){

if (hWnd == NULL) return E_POINTER;m_ipVBPreviewer->get_hWnd(hWnd); // Get window from VB componentreturn S_OK;

}

Create VB ActiveX DLL or OCX Add components to a frame

Create public member(s) to access window

Import into VC++

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

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

Finding the dockable window

STDMETHODIMP CAoDockableWindowCommand::OnCreate(IDispatch * hook){ m_ipApp = hook;

CComBSTR bsVal; ::StringFromCLSID(CLSID_PreviewDockWindow, &bsVal); // Dockable window to find

IUIDPtr ipUid(CLSID_UID); ipUid->put_Value(CComVariant(bsVal)); // Dockable window CLSID

IDockableWindowManagerPtr ipDockMgr(m_ipApp); // Get the window manager

IDockableWindowPtr ipDockWindow; ipDockMgr->GetDockableWindow(ipUID, &m_ipDockWindow); // Find the window

return S_OK;}

STDMETHODIMP CAoDockableWindowCommand::OnCreate(IDispatch * hook){ m_ipApp = hook;

CComBSTR bsVal; ::StringFromCLSID(CLSID_PreviewDockWindow, &bsVal); // Dockable window to find

IUIDPtr ipUid(CLSID_UID); ipUid->put_Value(CComVariant(bsVal)); // Dockable window CLSID

IDockableWindowManagerPtr ipDockMgr(m_ipApp); // Get the window manager

IDockableWindowPtr ipDockWindow; ipDockMgr->GetDockableWindow(ipUID, &m_ipDockWindow); // Find the window

return S_OK;}

Reference the application: Hook

Use IDockableWindowManager::GetDockableWindow()

Pass in the CLSID to find window

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

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

Controlling the visibility of the window

Use a command to manage the stateICommand::OnClick() to open and close

IDockableWindow::Dock(esriDockxxx)

ESRI constants: esriDockShow and esriDockHide

Deactivate your tool when the window is hidden

STDMETHODIMP CAoDockableWindowCommand::OnClick(){

m_bVisible = !m_bVisible; // Toggle this each time

HRESULT hr;if (m_bVisible)

hr = m_ipDockWindow->Dock(esriDockShow);else{

hr = m_ipDockWindow->Dock(esriDockHide);m_ipApp->putref_CurrentTool(0); // Deactivate the tool

}

return hr;}

STDMETHODIMP CAoDockableWindowCommand::OnClick(){

m_bVisible = !m_bVisible; // Toggle this each time

HRESULT hr;if (m_bVisible)

hr = m_ipDockWindow->Dock(esriDockShow);else{

hr = m_ipDockWindow->Dock(esriDockHide);m_ipApp->putref_CurrentTool(0); // Deactivate the tool

}

return hr;}

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

4-10

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

Dockable window design considerations

Window can be closed manually by user with the x

Manage ICommand, Enabled, and Checked properties

Match command with the window state// ICommandSTDMETHODIMP CAoDockableWindowCommand::get_Enabled(VARIANT_BOOL * Enabled){

VARIANT_BOOL bVisible;m_ipDockWindow->IsVisible(&bVisible);if (bVisible == VARIANT_FALSE) // Window was manually closed ‘x’{

m_ipApp->putref_CurrentTool(0); // Deactivate toolm_bVisible = FALSE; // Don't deactivate again!

}*Enabled = VARIANT_TRUE;return S_OK;

}

STDMETHODIMP CAoDockableWindowCommand::get_Checked(VARIANT_BOOL * Checked){

VARIANT_BOOL bVisible;m_ipDockWindow->IsVisible(&bVisible);*Checked = bVisible;return S_OK;

}

// ICommandSTDMETHODIMP CAoDockableWindowCommand::get_Enabled(VARIANT_BOOL * Enabled){

VARIANT_BOOL bVisible;m_ipDockWindow->IsVisible(&bVisible);if (bVisible == VARIANT_FALSE) // Window was manually closed ‘x’{

m_ipApp->putref_CurrentTool(0); // Deactivate toolm_bVisible = FALSE; // Don't deactivate again!

}*Enabled = VARIANT_TRUE;return S_OK;

}

STDMETHODIMP CAoDockableWindowCommand::get_Checked(VARIANT_BOOL * Checked){

VARIANT_BOOL bVisible;m_ipDockWindow->IsVisible(&bVisible);*Checked = bVisible;return S_OK;

}

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

4-11

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

Custom layers

Map-level customization

Very application specific Involve drawing (custom) elements to the screen

Used as an alternative to custom workspace factories

Design considerations Drawing and storing elements

Make as functional as an esriCore::FeatureLayer

May require writing custom tools and other components

Example: GreatCircleLayer

Instructor DemoInstructor Demo

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

4-12

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

Implementing a layer

ILayer Supports draw phases

Controls drawing behavior

Controls visibility

IGeoDataset Extent

Spatial reference

IPersist and IPersistStream Enables ILayer property data to be stored

Enables custom layer data to be stored

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

4-13

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

Drawing phases

Custom layer must identify the supported draw phases

Tells system how and when to draw the layer

tagesriDrawPhase

Each phase represents an off-screen bitmap (cache)

STDMETHODIMP CMyLayer::get_SupportedDrawPhases(long* pDrawPhases){ if (!pDrawPhases) return E_POINTER;

// We are only interested in the geography phase, can be or’ed *pDrawPhases = esriDPGeography;

return S_OK;}

STDMETHODIMP CMyLayer::get_SupportedDrawPhases(long* pDrawPhases){ if (!pDrawPhases) return E_POINTER;

// We are only interested in the geography phase, can be or’ed *pDrawPhases = esriDPGeography;

return S_OK;}

esriDPGeography 1 - Draw geography

esriDPAnnoation 2 - Draw annotation

esriDPSelection 4 – Draw selection

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

4-14

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

Layer caches

STDMETHODIMP CMyLayer::get_Cached(VARIANT_BOOL* pCached) {

if (!pCached) return E_POINTER;

*pCached = m_bCached; return S_OK;

}

STDMETHODIMP CMyLayer::put_Cached(VARIANT_BOOL cached) {

m_bCached = cached; return S_OK;

}

STDMETHODIMP CMyLayer::get_Cached(VARIANT_BOOL* pCached) {

if (!pCached) return E_POINTER;

*pCached = m_bCached; return S_OK;

}

STDMETHODIMP CMyLayer::put_Cached(VARIANT_BOOL cached) {

m_bCached = cached; return S_OK;

}

All layers are drawn into one cache

Any layer can be drawn into a separate cache

Improves drawing speed if refreshed frequently IActiveView::PartialRefresh(esriViewGeography, pUnkLayer, ipLayerExtent);

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

4-15

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

Drawing the layer

The system can ask to draw the layer at any time

Draw code must be ready in ILayer::Draw

Always verify the followingesriDrawPhase, pDisplay, and pTrackCancel

STDMETHODIMP CMyLayer::Draw(esriDrawPhase drawPhase, IDisplay* pDisplay, ITrackCancel* pTrackCancel){ if (!pDisplay) return E_POINTER;

if (drawPhase == esriDPGeography) {

VARIANT_BOOL continueDrawing;if (pTrackCancel)

pTrackCancel->Continue(&continueDrawing);

if (continueDrawing) // Ok to draw featuresDrawFeatures();

… }}

STDMETHODIMP CMyLayer::Draw(esriDrawPhase drawPhase, IDisplay* pDisplay, ITrackCancel* pTrackCancel){ if (!pDisplay) return E_POINTER;

if (drawPhase == esriDPGeography) {

VARIANT_BOOL continueDrawing;if (pTrackCancel)

pTrackCancel->Continue(&continueDrawing);

if (continueDrawing) // Ok to draw featuresDrawFeatures();

… }}

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

4-16

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

Drawing layer features

Draw each geometry manually

Decide on best methodology: Linear, by size, position…

Set symbol into the display first

Do not call StartDrawing() or FinishDrawing()

STDMETHODIMP CMyLayer::Draw(esriDrawPhase drawPhase, IDisplay* pDisplay, ITrackCancel* pTrackCancel){

if (!pDisplay) return E_POINTER;…

// Ok to draw feature(s)HRESULT hr = pDisplay->SetSymbol(m_pSymbol);if (FAILED(hr)) return hr;

hr = pDisplay->DrawPoint(pGeom);if (FAILED(hr)) return hr;

}

STDMETHODIMP CMyLayer::Draw(esriDrawPhase drawPhase, IDisplay* pDisplay, ITrackCancel* pTrackCancel){

if (!pDisplay) return E_POINTER;…

// Ok to draw feature(s)HRESULT hr = pDisplay->SetSymbol(m_pSymbol);if (FAILED(hr)) return hr;

hr = pDisplay->DrawPoint(pGeom);if (FAILED(hr)) return hr;

}

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

4-17

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

Georeferencing layers

All layers must support IGeoDataset

Defines the extent and spatial reference

Required by ArcMap to Control layer visibility from TOC

Control invalid drawing extent

Enable command tools (e.g., Zoom to layer)

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

4-18

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

Completing the layer implementation

IPersistStream

ILegendInfo

Others are optional See FeatureLayer

IPublishLayer for internet publishing

Associated objects may be required Specialized commands and tools

Specialized property page

Specialize event handling

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

4-19

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

Property sheets and pages

Instructor DemoInstructor Demo

Purpose: To view and edit attributes of objects Examples: Element, layer, or a map frame

Potential uses Show property sheets on-the-fly

Show custom sheets with selected property pages only

Create custom property pages for specific objects

Example: GCLPropertyPage

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

4-20

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

Showing property sheets and pages

ComPropertySheet

Automatically loads pages in a specific category

Populate an ISet to pass in filter objects (e.g., Layer)

EditProperties – Shows property sheet and pages

IComPropertySheetPtr ipComPropertySheet(CLSID_ComPropertySheet); // Generic sheet

IUIDPtr ipUID(CLSID_UID); // Define the category GUID v.bstrVal = ::SysAllocString(OLESTR("{1476C782-6F57-11D2-A2C6-080009B6F22B}")); ipUID->put_Value(v);

ipComPropertySheet->AddCategoryID(ipUID); // Filter pages by category

IUnknown* pUnk; if (FAILED(hr = pLayer->QueryInterface(&pUnk))) return hr;

ISetPtr ipSet(CLSID_Set); ipSet->Add(pUnk); // Search criteria is type ILayer

ipComPropertySheet->EditProperties(ipSet,(OLE_HANDLE) hParentWindow, &vb) // Show

IComPropertySheetPtr ipComPropertySheet(CLSID_ComPropertySheet); // Generic sheet

IUIDPtr ipUID(CLSID_UID); // Define the category GUID v.bstrVal = ::SysAllocString(OLESTR("{1476C782-6F57-11D2-A2C6-080009B6F22B}")); ipUID->put_Value(v);

ipComPropertySheet->AddCategoryID(ipUID); // Filter pages by category

IUnknown* pUnk; if (FAILED(hr = pLayer->QueryInterface(&pUnk))) return hr;

ISetPtr ipSet(CLSID_Set); ipSet->Add(pUnk); // Search criteria is type ILayer

ipComPropertySheet->EditProperties(ipSet,(OLE_HANDLE) hParentWindow, &vb) // Show

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

4-21

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

Loading property pages

ComponentCategories

2. Pass ISet

Load all pages that apply to ISet

Each page evaluates ISet

1. CATID

1. CATID:ESRI Layer Property Pages

2. ISet: ILayer

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

4-22

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

Custom property pages

Implement IPropertyPage

IPropertyPageContext

Design same as MS property pages

Key membersApplies, Show, and Apply

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

4-23

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

Designing a property page in ATL

Instructor DemoInstructor Demo

New ATL property page object

Provides default implementationIPropertyPageImpl<>

IPropertyPage

Need IPropertyPageContext

Use the Resource Wizard Add and position window elements

Event handling code must be added manually MSG_MAP

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

4-24

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

STDMETHODIMP CGCLayerPropertyPage::Applies(VARIANT unkArray, VARIANT_BOOL * Applies){

// Default Applies to False*Applies = VARIANT_FALSE;

SAFEARRAY *saArray;saArray = unkArray.parray;HRESULT hr = SafeArrayLock(saArray);if (FAILED(hr)) return hr;

// Look for object we can editlong lNumElements = saArray->rgsabound->cElements;for (long i = 0; i < lNumElements; i++){

// Attempt to QI for IEventCustomLayerIGreatCircleLayerPtr ipGCLayer(ippUnk[i]);if (ipGCLayer != 0){

// Interface and the property page therefore applies*Applies = VARIANT_TRUE;

}}return S_OK;

}

STDMETHODIMP CGCLayerPropertyPage::Applies(VARIANT unkArray, VARIANT_BOOL * Applies){

// Default Applies to False*Applies = VARIANT_FALSE;

SAFEARRAY *saArray;saArray = unkArray.parray;HRESULT hr = SafeArrayLock(saArray);if (FAILED(hr)) return hr;

// Look for object we can editlong lNumElements = saArray->rgsabound->cElements;for (long i = 0; i < lNumElements; i++){

// Attempt to QI for IEventCustomLayerIGreatCircleLayerPtr ipGCLayer(ippUnk[i]);if (ipGCLayer != 0){

// Interface and the property page therefore applies*Applies = VARIANT_TRUE;

}}return S_OK;

}

PropertySheet passes in an array of objects (ISet)

Page tells the sheet to load page or not

IPropertyPage::Applies

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

4-25

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

IPropertyPage::Show

STDMETHODIMP CGCLayerPropertyPage::Show(UINT nCmdShow){ // Let the ATL property page take care of showing and hiding the dialog hr = IPropertyPageImpl<CGCLayerPropertyPage>::Show(nCmdShow);

if (nCmdShow != SW_HIDE) { for (UINT i = 0; i < m_nObjects; i++) {

IGreatCircleLayerPtr ipGCLayer(m_ppUnk[i]);// Get the properties from the layerif ((ipGCLayer != 0) && (m_hWnd != 0)){

long lDelay;hr = ipGCLayer->get_Delay(&lDelay);SetDlgItemInt(IDC_TIMERINTERVAL, (UINT) (lDelay));

double dShift;hr = ipGCLayer->get_Shift(&dShift);SetDlgItemInt(IDC_SPEEDVALUE, (UINT) dShift);

}

} }}

STDMETHODIMP CGCLayerPropertyPage::Show(UINT nCmdShow){ // Let the ATL property page take care of showing and hiding the dialog hr = IPropertyPageImpl<CGCLayerPropertyPage>::Show(nCmdShow);

if (nCmdShow != SW_HIDE) { for (UINT i = 0; i < m_nObjects; i++) {

IGreatCircleLayerPtr ipGCLayer(m_ppUnk[i]);// Get the properties from the layerif ((ipGCLayer != 0) && (m_hWnd != 0)){

long lDelay;hr = ipGCLayer->get_Delay(&lDelay);SetDlgItemInt(IDC_TIMERINTERVAL, (UINT) (lDelay));

double dShift;hr = ipGCLayer->get_Shift(&dShift);SetDlgItemInt(IDC_SPEEDVALUE, (UINT) dShift);

}

} }}

Executes when the window itself is created

Opportunity to set the value of the page elements

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

4-26

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

IPropertyPage::Apply

Access property page array of objects

Find your object and set the new values

Synchronize property page values with object

STDMETHODIMP CGCLayerPropertyPage::Apply(void){ for (UINT i = 0; i < m_nObjects; i++) {

IGreatCircleLayerPtr ipGCLayer(m_ppUnk[i]);if (ipGCLayer != 0){

// Apply the changes from the property pagehr = ipGCLayer->put_Delay(GetDlgItemInt(IDC_TIMERINTERVAL)); if (FAILED(hr)) return hr;

hr = ipGCLayer->put_Shift((double) GetDlgItemInt(IDC_SPEEDVALUE));if (FAILED(hr)) return hr;

}

m_bDirty = FALSE; return S_OK;}

STDMETHODIMP CGCLayerPropertyPage::Apply(void){ for (UINT i = 0; i < m_nObjects; i++) {

IGreatCircleLayerPtr ipGCLayer(m_ppUnk[i]);if (ipGCLayer != 0){

// Apply the changes from the property pagehr = ipGCLayer->put_Delay(GetDlgItemInt(IDC_TIMERINTERVAL)); if (FAILED(hr)) return hr;

hr = ipGCLayer->put_Shift((double) GetDlgItemInt(IDC_SPEEDVALUE));if (FAILED(hr)) return hr;

}

m_bDirty = FALSE; return S_OK;}

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

4-27

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

Supporting persistence

Implement IPersistStream

Objects may contain other objects that support persistence Internal objects are automatically asked to persist themselves

(e.g., MxDocument > Map > Layers > Symbols)

Must be supported by all custom layers Store ILayer data: Name, visibility, min, and max scale

Store custom data if necessary

Example: GreatCircleLayer

Instructor DemoInstructor Demo

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

4-28

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

IPersistStream::Save

Save standard types and objects

STDMETHODIMP CGreatCircleLayer::Save(IStream * pStm, BOOL fClearDirty){ // Persist the relevant info to the stream pStm->Write(&cCurVers , sizeof(cCurVers), 0));

// ILayer members m_bsName.WriteToStream(pStm); pStm->Write(&m_bIsVisible, sizeof(m_bIsVisible), 0); pStm->Write(&m_bShowTips, sizeof(m_bShowTips), 0); pStm->Write(&m_bCached, sizeof(m_bCached), 0); pStm->Write(&m_dMinimumScale, sizeof(m_dMinimumScale), 0); pStm->Write(&m_dMaximumScale, sizeof(m_dMaximumScale), 0); pStm->Write(&m_dReferenceScale, sizeof(m_dReferenceScale), 0);

// IGreatCircleLayer members pStm->Write(&m_lDelay, sizeof(m_lDelay), 0); pStm->Write(&m_dShift, sizeof(m_dShift), 0);

IObjectStreamPtr ipObjectStream(CLSID_ObjectStream); ipObjectStream->putref_Stream(pStm);

hr = ipObjectStream->SaveObject(m_ipMovingSymbol); hr = ipObjectStream->SaveObject(m_ipAnimatePoint); hr = ipObjectStream->SaveObject(m_ipProjectedExtent);

m_bIsDirty = false; return S_OK;}

STDMETHODIMP CGreatCircleLayer::Save(IStream * pStm, BOOL fClearDirty){ // Persist the relevant info to the stream pStm->Write(&cCurVers , sizeof(cCurVers), 0));

// ILayer members m_bsName.WriteToStream(pStm); pStm->Write(&m_bIsVisible, sizeof(m_bIsVisible), 0); pStm->Write(&m_bShowTips, sizeof(m_bShowTips), 0); pStm->Write(&m_bCached, sizeof(m_bCached), 0); pStm->Write(&m_dMinimumScale, sizeof(m_dMinimumScale), 0); pStm->Write(&m_dMaximumScale, sizeof(m_dMaximumScale), 0); pStm->Write(&m_dReferenceScale, sizeof(m_dReferenceScale), 0);

// IGreatCircleLayer members pStm->Write(&m_lDelay, sizeof(m_lDelay), 0); pStm->Write(&m_dShift, sizeof(m_dShift), 0);

IObjectStreamPtr ipObjectStream(CLSID_ObjectStream); ipObjectStream->putref_Stream(pStm);

hr = ipObjectStream->SaveObject(m_ipMovingSymbol); hr = ipObjectStream->SaveObject(m_ipAnimatePoint); hr = ipObjectStream->SaveObject(m_ipProjectedExtent);

m_bIsDirty = false; return S_OK;}

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

4-29

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

IPersistStream::Load

Populate data values and objects

STDMETHODIMP CGreatCircleLayer::Load(IStream * pStm){ // Check the version of persistence short vers; if (FAILED(pStm->Read(&vers, sizeof(vers), 0))) return E_FAIL; if (vers > cCurVers) return E_FAIL; // Not forward compatible

// ILayer members m_bsName.ReadFromStream(pStm); pStm->Read(&m_bIsVisible, sizeof(m_bIsVisible), 0); pStm->Read(&m_bShowTips, sizeof(m_bShowTips), 0); pStm->Read(&m_bCached, sizeof(m_bCached), 0); pStm->Read(&m_dMinimumScale, sizeof(m_dMinimumScale), 0); pStm->Read(&m_dMaximumScale, sizeof(m_dMaximumScale), 0); pStm->Read(&m_dReferenceScale, sizeof(m_dReferenceScale), 0);

// IGreatCircleLayer members pStm->Read(&m_lDelay, sizeof(m_lDelay), 0); pStm->Read(&m_dShift, sizeof(m_dShift), 0); // Now the objects - use an object stream IObjectStreamPtr ipObjectStream(CLSID_ObjectStream); ipObjectStream->putref_Stream(pStm); hr = ipObjectStream->LoadObject((GUID*) &IID_ISymbol, 0, (IUnknown**) &m_ipMovingSymbol); … m_bIsDirty = false; return S_OK;}

STDMETHODIMP CGreatCircleLayer::Load(IStream * pStm){ // Check the version of persistence short vers; if (FAILED(pStm->Read(&vers, sizeof(vers), 0))) return E_FAIL; if (vers > cCurVers) return E_FAIL; // Not forward compatible

// ILayer members m_bsName.ReadFromStream(pStm); pStm->Read(&m_bIsVisible, sizeof(m_bIsVisible), 0); pStm->Read(&m_bShowTips, sizeof(m_bShowTips), 0); pStm->Read(&m_bCached, sizeof(m_bCached), 0); pStm->Read(&m_dMinimumScale, sizeof(m_dMinimumScale), 0); pStm->Read(&m_dMaximumScale, sizeof(m_dMaximumScale), 0); pStm->Read(&m_dReferenceScale, sizeof(m_dReferenceScale), 0);

// IGreatCircleLayer members pStm->Read(&m_lDelay, sizeof(m_lDelay), 0); pStm->Read(&m_dShift, sizeof(m_dShift), 0); // Now the objects - use an object stream IObjectStreamPtr ipObjectStream(CLSID_ObjectStream); ipObjectStream->putref_Stream(pStm); hr = ipObjectStream->LoadObject((GUID*) &IID_ISymbol, 0, (IUnknown**) &m_ipMovingSymbol); … m_bIsDirty = false; return S_OK;}

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

4-30

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

IPersistStream::GetSizeMax

Determine the size required to store all data

STDMETHODIMP CGreatCircleLayer::GetSizeMax(_ULARGE_INTEGER* pcbSize){ pcbSize->QuadPart = sizeof(cCurVers);

// Ilayer – Standard types pcbSize->QuadPart += m_bsName ? SysStringByteLen(m_bsName) + sizeof(OLECHAR) : 0; pcbSize->QuadPart += sizeof(m_bIsVisible); pcbSize->QuadPart += sizeof(m_bShowTips); pcbSize->QuadPart += sizeof(m_bCached); pcbSize->QuadPart += sizeof(m_dMinimumScale); pcbSize->QuadPart += sizeof(m_dMaximumScale); pcbSize->QuadPart += sizeof(m_dReferenceScale);

// IGreatCircleLayer – Standard types pcbSize->QuadPart += sizeof(m_lDelay); pcbSize->QuadPart += sizeof(m_dShift); pcbSize->QuadPart += sizeof(m_bActive); pcbSize->QuadPart += sizeof(m_dPlace);

_ULARGE_INTEGER objSize; // 64 bit unsigned integer struct

// IGreatCircleLayer – Objects IPersistStreamPtr ipPersistStream(m_ipMovingSymbol); ipPersistStream->GetSizeMax(&objSize); pcbSize->QuadPart += objSize.QuadPart;…}

STDMETHODIMP CGreatCircleLayer::GetSizeMax(_ULARGE_INTEGER* pcbSize){ pcbSize->QuadPart = sizeof(cCurVers);

// Ilayer – Standard types pcbSize->QuadPart += m_bsName ? SysStringByteLen(m_bsName) + sizeof(OLECHAR) : 0; pcbSize->QuadPart += sizeof(m_bIsVisible); pcbSize->QuadPart += sizeof(m_bShowTips); pcbSize->QuadPart += sizeof(m_bCached); pcbSize->QuadPart += sizeof(m_dMinimumScale); pcbSize->QuadPart += sizeof(m_dMaximumScale); pcbSize->QuadPart += sizeof(m_dReferenceScale);

// IGreatCircleLayer – Standard types pcbSize->QuadPart += sizeof(m_lDelay); pcbSize->QuadPart += sizeof(m_dShift); pcbSize->QuadPart += sizeof(m_bActive); pcbSize->QuadPart += sizeof(m_dPlace);

_ULARGE_INTEGER objSize; // 64 bit unsigned integer struct

// IGreatCircleLayer – Objects IPersistStreamPtr ipPersistStream(m_ipMovingSymbol); ipPersistStream->GetSizeMax(&objSize); pcbSize->QuadPart += objSize.QuadPart;…}

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

4-31

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

Exercise 4 overview

Implements ILayer…

Custom tools and toolbar

Property page and persistence

Challenge: Legend support

CGreatCircleLayer

IUnknown

CGCLayerPropertyPage

ILayerIGeoDataset

ILayerDrawPropertiesIPersistStream

ILegendInfo

IPropertyPage

IPropertyPageContext

CGCClear

CGCAnimate

CGCClear

IUnknown

ICommand

CGCDigitizeDestination

CGCDigitizeDeparture

CGCAddLayer

CGCLToolBarIToolBarDef

ICommand

ICommand

ICommand

ICommand

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

4-32

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

Review

Explain the start up sequence for commands and windows?

What object should control the visibility of a dockable window?

What interfaces should be implemented with ILayer?

When should a layer draw itself?

Describe the property page loading cycle?

How are data and objects persisted in VC++?