Presentation is loading. Please wait.

Presentation is loading. Please wait.

Advanced ArcObjects/ATL applications

Similar presentations

Presentation on theme: "Advanced ArcObjects/ATL applications"— Presentation transcript:

1 Advanced ArcObjects/ATL applications
Advanced ArcObjects Component Development II (C++)

2 Lesson 4 overview Integrated component solutions Dockable windows
Custom layers Property pages Persistence Exercise 4: Great circle custom layer Advanced ArcObjects Component Development II (C++)

3 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 Toolbar Command Dockable Window Component development for ArcObjects can be roughly grouped into three categories: external, internal, and geodatabase. When building applications, it is often necessary to develop objects from more than one category and glue these components together with extensions. The components involved in application development may cross all three levels of customization. For example, the availability of custom commands may be controlled by application extensions, but they may be able to take advantage of the enhanced functionality provided by a feature class extension. IExtension Extension IExtensionConfig ICustom ClassExtension Advanced ArcObjects Component Development II (C++)

4 Application startup revisited
2. Document 3. Extensions 4. New or existing document 5. Registered dockable windows are created 6. Commands and toolbars When ArcMap starts, the Application and Document object are created and then the extensions are loaded. If the ArcMap.exe was executed, a new empty document is created. If a user double-clicks on an existing .mxd file, this document is loaded. Before all of the commands and command bars are created, the registered dockable windows are created. The commands are loaded last. Advanced ArcObjects Component Development II (C++)

5 Dockable windows Application-level customization
Application manages window creation Visible state is saved in .mxt or .mxd Show and hide window with a tool Dockable windows are Application-level extensions because they are created when the application starts. The docking state and visibility are stored in the document when it is saved. A command should be used to control the visible state of the dockable window. Ensure that the command’s state reflects the dockable window state. If the window is docked, the button should be checked. If the window is not docked (invisible), then the button should not be checked. Instructor Demo Advanced ArcObjects Component Development II (C++)

6 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 // ICAoVBDockWindow public: // 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 Implementing a dockable window is very simple. The key is creating a child window when the dockable window is created, and passing that window’s hWnd back to the application. You can store user data with the window itself if necessary. Other applications and components can access this data by acquiring a reference to the window via the IDockableWindowManager interface. Advanced ArcObjects Component Development II (C++)

7 Consuming VB window components
Create VB ActiveX DLL or OCX Add components to a frame Create public member(s) to access window Import into VC++ // 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 component return S_OK; In this example, FinalConstruct and FinalRelease are used to control the lifetime of the VB window object. When the OnCreate member is called, the Application reference is passed back to the VB object. When ChildHWND is called, hWnd from the VB window is returned to the dockable window. Notice that #import is used here to generate the necessary wrapper files required to access the VB component and interfaces. Advanced ArcObjects Component Development II (C++)

8 Finding the dockable window
Reference the application: Hook Use IDockableWindowManager::GetDockableWindow() Pass in the CLSID to find 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; } The Application object implements IDockableWindowManager. This interface allows you to find your window after the system has created it. Note that you never cocreate the object; the system creates all dockable windows in the ESRI Mx Dockable Windows component category when the application starts. Since dockable windows are created before commands, it is always safe to use ICommand::OnCreate to find a dockable window and hold on to its reference. This command will also be in charge of showing and hiding the window itself. Advanced ArcObjects Component Development II (C++)

9 Controlling the visibility of the window
Use a command to manage the state ICommand::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; The docking state of a dockable window can be controlled by a command or any other component by changing the IDockableWindow::Dock() property. Study the enumerations available in order to determine which one to use for the type of docking your application requires. The visibility of the window is controlled here using esriDockShow and esriDockHide. Advanced ArcObjects Component Development II (C++)

10 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 // ICommand STDMETHODIMP 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 tool m_bVisible = FALSE; // Don't deactivate again! } *Enabled = VARIANT_TRUE; return S_OK; STDMETHODIMP CAoDockableWindowCommand::get_Checked(VARIANT_BOOL * Checked) *Checked = bVisible; Dockable windows can be closed by the user at any time if they close the window with the mouse. The problem is that the command that enabled the window has no idea the window was closed because there is no IDockableWindowDef::OnClose member. A messaging system or even an outbound interface could be used to solve this problem, but a more simple solution is to use the command to check the visible property of the window and see when it is out of synchronization with its visible member. Since ICommand::Enabled is called immediately after any dockable window closes, the command can check for the synchronization and then respond by setting the current tool to NULL if the window was closed. This will deactivate the button and synchronize the state of the command with the window. If the dockable window is visible when a user closes ArcMap, then the application will store the visible state in the .mxt or .mxd file. When the application restarts, the window is restored to the old window state. The issue is that the command that controls the window also needs to be synchronized with the window state. It the window is visible, then the command should be checked. If the window is invisible, then the command should be unchecked. To resolve this issue, use ICommand::Checked to synchronize the window visibility with the checked state of the command. Advanced ArcObjects Component Development II (C++)

11 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 Custom layers are a very specific type of advanced ArcObjects customization. They are generally created for the purpose of animation, custom tracking, or displaying custom data. Custom tools are generally created for these layers in order to provide some level of user interaction and specialized behavior. A number of interfaces can be implemented and creating a layer as functional as a esriCore::FeatureLayer is very difficult. Instructor Demo Advanced ArcObjects Component Development II (C++)

12 Implementing a layer ILayer IGeoDataset IPersist and IPersistStream
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 At a minimum, three interfaces must be implemented by every custom layer. The main interface, ILayer, is used by the system to control the visibility and drawing behavior of the layer. IGeodataset and IPersistStream must also be implemented so the layer can be georeference, and so the properties of the layer can be persisted in the document. Advanced ArcObjects Component Development II (C++)

13 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) esriDPGeography 1 - Draw geography esriDPAnnoation 2 - Draw annotation esriDPSelection 4 – Draw selection 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; } The system maintains three off-screen bitmaps. Your custom layer needs to tell the system which bitmap it should be associated with in order to control and optimize drawing. Geographic features should be drawn with esriDPGeography, annotation-type features with esriDPAnnotation, and selection features with esriDPSelection. Advanced ArcObjects Component Development II (C++)

14 Layer caches 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); 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; By setting the ILayer::Cached property to true, the system creates its own cache for your layer. This is highly desirable if you have a layer that requires refreshing on a frequent basis or if it needs to be refreshed separately from the other layers. Advanced ArcObjects Component Development II (C++)

15 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 features DrawFeatures(); } Depending on which draw phase your layer supports, it is possible that the layer will be asked to draw itself at any time. You should always check the state of the draw phase, display, and cancel tracker before drawing features to the screen. Checking the status of the cancel tracker is important because the user can stop drawing by selecting the Esc key, so you want your layer to stop drawing as well if this happens. Advanced ArcObjects Component Development II (C++)

16 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); } You must draw each feature in your layer manually when ILayer:Draw is called. It is not necessary to start or stop drawing because the system invokes these methods for you beforehand. Remember, if you have to draw many features, you need to come up with a drawing scheme that best suits the type of data and the application you are developing. Drawing features linearly or by position are both options, but this logic needs to be built into your layer. Advanced ArcObjects Component Development II (C++)

17 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) A custom layer must support IGeoDataset so that the map knows the extent of your features and how to project them when drawn. This interface also tells the map and the active view the extent of the layer and what area needs to be invalidated with it is time to redraw. Implementing the interface also allows other parts of the system like the Zoom to layer command and the Display TOC to interact with your layer correctly. Advanced ArcObjects Component Development II (C++)

18 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 If you look at the FeatureLayer object, you can see that a number of interfaces have been implemented. Ultimately, the interfaces you decide to use depend on the functionality desired. IPersistStream must be implemented however, so the system can store the attributes such as the name and visibility for the layer. Other custom data associated with the layer can also be stored into the stream, but be sure not to store entire datasets or large objects into the stream, because it will result in the generation of large .mxd files and poor performance. Implementing ILegendInfo should also be supported so that the TOC can render a symbol and/or renderer symbols for the layer. As mentioned before, other components such as tools and toolbars are generally required to allow the user to interact with the layer and use its custom behavior. Advanced ArcObjects Component Development II (C++)

19 Property sheets and pages
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 The general purpose of a property sheet and page is to give the user a way to view and set the attributes of an object. One example includes the MapFrame, where a user may be interested in changing the default projection. PropertySheet coclasses can be created on the fly and displayed to a user via a command, right-click, or any Windows message. Property pages, on the other hand, must be created by implementing interfaces and writing custom server components. Property pages are consumed by property sheets. Instructor Demo Advanced ArcObjects Component Development II (C++)

20 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-A2C B6F22B}")); 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 To display a property sheet containing property pages you need to use the ComPropertySheet coclass. Members of the IComPropertySheet interface must be set to tell the coclass which property page component category it needs to reference, and which objects it will pass into the pages so it knows which pages can be loaded or not. IComPropertyPage::EditProperties actually displays the window and pages that meet the aforementioned criteria. Alternatively, property pages can be manually added to the sheet if the automated methodology of querying the component category is not desired. Advanced ArcObjects Component Development II (C++)

21 Loading property pages
1. CATID: ESRI Layer Property Pages 2. ISet: ILayer 1. CATID Load all pages that apply to ISet Component Categories After the property sheet coclass is created, the filter property tells the object which component category to query. The property sheed then passes each property page in the category the ISet. Each page is then responsible for looking at the objects in the ISet and determining whether it applies or not. If the page applies, then the sheet loads the page is displayed. Steps: Property sheet is created Component category is queried Each page is queried to see if it applies Pages that apply are loaded Each page evaluates ISet 2. Pass ISet Advanced ArcObjects Component Development II (C++)

22 Custom property pages Implement Design same as MS property pages
IPropertyPage IPropertyPageContext Design same as MS property pages Key members Applies, Show, and Apply Custom property pages can be created by implementing IPropertyPage and IPropertyPageContext. When working in ATL, you can use the property page wizard which provides a default implementation of these interfaces for you in the IPropertyPageImpl class. To customize the behavior of the page, you should override selected members of this class. Advanced ArcObjects Component Development II (C++)

23 Designing a property page in ATL
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 Inserting a property page with the ATL wizard enables you to use the resource editor to create a custom GUI for the page. Event handling code must be added manually however. Use the MSG_MAP macros to help expose the window messages that are executed when a user interacts with the controls. Instructor Demo Advanced ArcObjects Component Development II (C++)

24 IPropertyPage::Applies
PropertySheet passes in an array of objects (ISet) Page tells the sheet to load page or not 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 edit long lNumElements = saArray->rgsabound->cElements; for (long i = 0; i < lNumElements; i++) // Attempt to QI for IEventCustomLayer IGreatCircleLayerPtr ipGCLayer(ippUnk[i]); if (ipGCLayer != 0) // Interface and the property page therefore applies *Applies = VARIANT_TRUE; } return S_OK; When you override the IPropertyPage::Applies member, you must return a Boolean value indicating whether your page applies to the objects in the array. In this example, the property page only applies to the GreatCircleLayer object, and if this object is not found, then a Boolean value of false is returned to the property sheet. The property sheet responds by not loading this page. Advanced ArcObjects Component Development II (C++)

25 IPropertyPage::Show Executes when the window itself is created
Opportunity to set the value of the page elements 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 layer if ((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); } IPropertyPage::Show is called just before the actual property page is drawn in the window. This is your opportunity to set any of the control elements properties such as checkboxes or textboxes. In this example, the property page finds the GreatCircleLayer and queries its custom interface for the the Delay and Shift properties. The m_nObjects is a member variable of the property page. This is populated when the property page applies and is created by a property sheet. Advanced ArcObjects Component Development II (C++)

26 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 page hr = ipGCLayer->put_Delay(GetDlgItemInt(IDC_TIMERINTERVAL)); if (FAILED(hr)) return hr; hr = ipGCLayer->put_Shift((double) GetDlgItemInt(IDC_SPEEDVALUE)); } m_bDirty = FALSE; return S_OK; When IPropertyPage::Apply is called, you should edit the object associated with the property page. In this example, the values of the dialog controls are passed into the Delay and Shift public members of IGreatCircleLayer. This synchronizes the values the user set with the object itself. Advanced ArcObjects Component Development II (C++)

27 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 Many ArcObjects objects support persistence. These objects often have references to other objects which also support persistence. For example, a map stores layers, so when a document is saved, the persist stream is passed down through the hierarchy of objects that support IPersistStream, and all of the objects are responsible for saving themselves. Instructor Demo Advanced ArcObjects Component Development II (C++)

28 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; } In this example, the standard ILayer members are persisted in the .mxd when the document is saved. Other data specific to the custom layer itself is also stored, such as a symbol and the extent. Notice that the data stored are either standard data types or small objects, in an effort not to over-inflate the size of the document. Advanced ArcObjects Component Development II (C++)

29 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; } When IPersistStream::Load is called for the layer, all of the ILayer specific members are rehydrated according to what their value was when the document was saved. Notice that the custom layer data is also retrieved and the local member variables are set. Advanced ArcObjects Component Development II (C++)

30 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; } Regardless of whether you are storing standard data types or objects into a stream, you must tell the stream how much storage space is required in the .mxd document in order to save your objects. _ULARGE_INTEGER simply equates to a 64-bit unsigned integer. Advanced ArcObjects Component Development II (C++)

31 CGCDigitizeDeparture CGCDigitizeDestination CGCLayerPropertyPage
Exercise 4 overview IUnknown Implements ILayer… Custom tools and toolbar Property page and persistence Challenge: Legend support IToolBarDef CGCClear CGCLToolBar IUnknown ICommand CGCAddLayer ICommand CGCDigitizeDeparture ICommand CGCDigitizeDestination ICommand CGCClear ILayer CGreatCircleLayer ICommand CGCAnimate IGeoDataset ILayerDrawProperties IPersistStream ILegendInfo IPropertyPage CGCLayerPropertyPage IPropertyPageContext Advanced ArcObjects Component Development II (C++)

32 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++? Advanced ArcObjects Component Development II (C++)

Download ppt "Advanced ArcObjects/ATL applications"

Similar presentations

Ads by Google