advanced arcobjects/atl applications

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

Upload: turner

Post on 17-Mar-2016

138 views

Category:

Documents


4 download

DESCRIPTION

Advanced ArcObjects/ATL applications. Lesson 4 overview. Integrated component solutions Dockable windows Custom layers Property pages Persistence Exercise 4: Great circle custom layer. ArcObjects component integration . Applications often require integrating many objects - PowerPoint PPT Presentation

TRANSCRIPT

Page 1: Advanced ArcObjects/ATL applications

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

Advanced ArcObjects/ATL applications

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

DockableWindowCommand

Toolbar

IExtensionConfigICustom ClassExtension

Page 4: 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: 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: 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 createdChildHWND – Provide a child hWnd sourceUserData – 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

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

}

Create VB ActiveX DLL or OCX Add components to a frame Create public member(s) to access window

Import into VC++

Page 8: 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;}

Reference the application: Hook Use IDockableWindowManager::GetDockableWindow() Pass in the CLSID to find window

Page 9: 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 state

ICommand::OnClick() to open and closeIDockableWindow::Dock(esriDockxxx) ESRI constants: esriDockShow and esriDockHide

Deactivate your tool when the window is hiddenSTDMETHODIMP 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: Advanced ArcObjects/ATL applications

4-10Advanced 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;

}

Page 11: Advanced ArcObjects/ATL applications

4-11Advanced 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: Advanced ArcObjects/ATL applications

4-12Advanced 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: Advanced ArcObjects/ATL applications

4-13Advanced 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;}

esriDPGeography 1 - Draw geography

esriDPAnnoation 2 - Draw annotation

esriDPSelection 4 – Draw selection

Page 14: Advanced ArcObjects/ATL applications

4-14Advanced 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;

}

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: Advanced ArcObjects/ATL applications

4-15Advanced 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 following

esriDrawPhase, 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();

… }}

Page 16: Advanced ArcObjects/ATL applications

4-16Advanced 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;

}

Page 17: Advanced ArcObjects/ATL applications

4-17Advanced 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: Advanced ArcObjects/ATL applications

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

Completing the layer implementation IPersistStream ILegendInfo Others are optional

See FeatureLayerIPublishLayer for internet publishing

Associated objects may be required Specialized commands and tools Specialized property page Specialize event handling

Page 19: Advanced ArcObjects/ATL applications

4-19Advanced 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: Advanced ArcObjects/ATL applications

4-20Advanced 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

Page 21: Advanced ArcObjects/ATL applications

4-21Advanced 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: Advanced ArcObjects/ATL applications

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

Custom property pages Implement

IPropertyPage IPropertyPageContext

Design same as MS property pages Key members

Applies, Show, and Apply

Page 23: Advanced ArcObjects/ATL applications

4-23Advanced 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 implementation

IPropertyPageImpl<>IPropertyPage Need IPropertyPageContext

Use the Resource Wizard Add and position window elements

Event handling code must be added manually MSG_MAP

Page 24: Advanced ArcObjects/ATL applications

4-24Advanced 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;

}

PropertySheet passes in an array of objects (ISet) Page tells the sheet to load page or not

IPropertyPage::Applies

Page 25: Advanced ArcObjects/ATL applications

4-25Advanced 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);

}

} }}

Executes when the window itself is created Opportunity to set the value of the page elements

Page 26: Advanced ArcObjects/ATL applications

4-26Advanced 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;}

Page 27: Advanced ArcObjects/ATL applications

4-27Advanced 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: Advanced ArcObjects/ATL applications

4-28Advanced 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;}

Page 29: Advanced ArcObjects/ATL applications

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

IPersistStream::Load Populate data values and objectsSTDMETHODIMP 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: Advanced ArcObjects/ATL applications

4-30Advanced 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;…}

Page 31: Advanced ArcObjects/ATL applications

4-31Advanced 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

IPropertyPageIPropertyPageContext

CGCClear

CGCAnimate

CGCClear

IUnknown

ICommand

CGCDigitizeDestination

CGCDigitizeDeparture

CGCAddLayer

CGCLToolBarIToolBarDef

ICommand

ICommand

ICommand

ICommand

Page 32: Advanced ArcObjects/ATL applications

4-32Advanced 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++?