close

Se connecter

Se connecter avec OpenID

Advanced ArcObjects Component Developent with Visual …

IntégréTéléchargement
Programming
ArcObjects with VC++
Copyright © 2002 ESRI. All rights reserved.
Advanced ArcObjects Component Development II (C++)
Lesson 2 overview

VC++ and ArcObjects/COM programming review

How to import type libraries

Smart pointers

COM data types, HRESULTs, strings, and variants

Microsoft Visual Studio

Exercise 2: Simple console application
Copyright © 2002 ESRI. All rights reserved.
Advanced ArcObjects Component Development II (C++)
2-2
How VC++ facilitates ArcObjects development

Client-side COM support
 Native
compiler support: Direct-To-COM (DTC)
 #import
 Support

directive to import type libraries
classes for standard OLE types (BSTRs, VARIANTs, …)
Server-side COM support
 ATL
(Active Template Library)
 Templates
and wizards for building COM objects and servers
Copyright © 2002 ESRI. All rights reserved.
Advanced ArcObjects Component Development II (C++)
2-3
Importing the ArcObjects library

#import modifiers are required
// stdafx.h

#pragma warning(push)
// Sets the current warning state
#pragma warning(disable : 4146)
// Ignore –2147483648 for uint
#pragma warning(disable : 4192)
// Exclude‘name’ while importing
#import "c:\arcgis\arcexe81\bin\esriCore.olb" \
// Type lib to generate C++ mapping
raw_interfaces_only, \
// Don’t add raw_ to method names
raw_native_types, \
// Don’t map to DTC smart types
no_namespace, \
// Don’t wrap with C++ name space
named_guids, \
// Named guids and declspecs
exclude("OLE_COLOR", "OLE_HANDLE")
// Exclude conflicting types
#pragma warning(pop)
// Restores state of warnings – undo
Specify esriCore.olb path: Tools > Options > Directories
Instructor Demo
Copyright © 2002 ESRI. All rights reserved.
Advanced ArcObjects Component Development II (C++)
2-4
ArcObjects wrapper classes

#import automatically generates type library wrappers

Creates typedefs, smart pointers, structures…
// Created by Microsoft (R) C/C++ Compiler Version 12.00.8168.0 (d727fb44).
//
// c:\student\arcobjectscpp\exercises\(1) - cpp\aoconsoleapp_solution\debug\esriCore.tlh
//
// C++ source equivalent of Win32 type library esriCore.olb
// compiler-generated file created 12/20/01 at 11:33:49 - DO NOT EDIT!
…
/* interface */ IMap;
struct __declspec(uuid("34b2ef81-f4ac-11d1-a245-080009b6f22b"))
…
extern "C" const GUID __declspec(selectany)
CLSID_Map = {0xe6bdaa76,0x4d35,0x11d0,{0x98,0xbe,0x00,0x80,0x5f,0x7c,0xed,0x21}};
…
_COM_SMARTPTR_TYPEDEF(IMap, __uuidof(IMap));
Typedef _com_ptr_t<_com_IIID<IMap, __uuidof(IMap)>> IMapPtr;
…
struct __declspec(uuid("e6bdaa75-4d35-11d0-98be-00805f7ced21"))
IMap : IUnknown
{
// Raw methods provided by interface
virtual HRESULT __stdcall get_Name ( BSTR * Name ) = 0;
virtual HRESULT __stdcall put_Name ( BSTR Name ) = 0;
…
Copyright © 2002 ESRI. All rights reserved.
Advanced ArcObjects Component Development II (C++)
2-5
DTC smart types

VC++ classes that encapsulate data types

_com_ptr_t<>
Encapsulates a COM interface pointer (smart pointer)

_bstr_t
Encapsulates the BSTR data type

_variant_t
Encapsulates variant type and automatically initializes

_com_error
Represents a COM exception using IErrorInfo

Classes behave like raw types

Helpful constructors, functions, and operators

Maps all COM errors to C++ exceptions

Use to simplify ArcObjects code…
Copyright © 2002 ESRI. All rights reserved.
Advanced ArcObjects Component Development II (C++)
2-6
Initializing the COM library

Necessary for stand-alone ArcObjects applications

Steps
1. ::CoInitialize() - Loads the COM libraries
2. Cocreate and use ArcObjects objects
3. ::CoUninitialize() - Unloads COM libraries
#include "stdafx.h"
int main(int argc, char* argv[])
{
::CoInitialize(NULL);
IMapPtr ipMap(CLSID_Map);
// Simple code to create and call COM objects
int iLayers;
ipMap->get_LayerCount(&iLayers);
_tprint(“Number of layers: %i \n“, iLayers);
::CoUninitialize();
}
Copyright © 2002 ESRI. All rights reserved.
Advanced ArcObjects Component Development II (C++)
2-7
Creating new ArcObjects objects

COM API – ::CoCreateInstance()
// CoCreate a Map
IMap* pMap;
HRESULT hr = ::CoCreateInstance(
CLSID_Map,
0,
CLSCTX_ALL,
IID_IMap,
(void **) &pMap
);
if (FAILED(hr)) return hr;

//
//
//
//
//
Class identifier (CLSID) of the object
Pointer to outer unknown pointer
Context for running executable code
Reference to the interface identifier
Indirect pointer to requested interface
// Check HRESULT…
DTC smart pointers – Simplified but less control…
// CoCreate a Map
IMapPtr ipMap(CLSID_Map);
if (ipMap == NULL) return E_POINTER;
Copyright © 2002 ESRI. All rights reserved.
// Check for NULL
Advanced ArcObjects Component Development II (C++)
2-8
Querying interfaces

COM API – IUnknown::QueryInterface()
// CoCreate a Map
IMap* pIMap;
::CoCreateInstance(CLSID_Map, 0, CLSCTX_ALL, IID_IMap, (void **) &pMap);
IActiveView* pActiveView;
pMap->QueryInterface(IID_IActiveView, (void **) &pActiveView); // QI

DTC smart pointers – Use assignment operator
// CoCreate a Map
IMapPtr ipMap(CLSID_Map);
// QI
IActiveViewPtr
// QI
ipActiveView(ipMap);
// or use the assignment “=“ operator directly
IActiveViewPtr ipActiveView;
ipActiveView = ipMap;
Copyright © 2002 ESRI. All rights reserved.
// QI
Advanced ArcObjects Component Development II (C++)
2-9
Object lifetime control: Smart pointers
// Smart pointer reference count test
long refCount;
// CoCreate the SimpleObject
IUnknownPtr ipUnk(CLSID_SimpleObject);
// AddRef
ISimpleObjectPtr ipMagic(ipUnk);
// AddRef
ipMagic->get_ReferenceCount(&refCount);
IAnotherInterfacePtr ipMagic2(ipMagic); // AddRef
ipMagic->get_ReferenceCount(&refCount);
ipMagic2 = NULL; // What happens?
ipMagic->get_ReferenceCount(&refCount);
ipMagic = NULL; // What happens?
// What happens to ipUnk here?
::CoCreateInstance(CLSID_SimpleObject, 0, CLSCTX_ALL, IID_IUnknown, (void **) &ipUnk);
ipUnk = NULL;
Instructor Demo
Copyright © 2002 ESRI. All rights reserved.
Advanced ArcObjects Component Development II (C++)
2-10
COM data type mapping
Language
IDL
Microsoft C++
Visual Basic
Microsoft Java
Boolean
unsigned char
unsupported
char
byte
unsigned char
unsupported
char
small
char
unsupported
char
short
short
Integer
short
long
long
Long
int
Base
hyper
__int64
unsupported
long
Types
float
float
Single
float
double
double
Double
double
char
unsigned char
unsupported
char
wchar_t
wchar_t
Integer
short
enum
enum
Enum
int
Interface Pointer
Interface Pointer
Interface Ref.
Interface Ref.
Extended
VARIANT
VARIANT
Variant
ms.com.Variant
Types
BSTR
BSTR
String
java.lang.String
Boolean
[true/false]
VARIANT_BOOL short (-1 true/0 false)
Copyright © 2002 ESRI. All rights reserved.
Advanced ArcObjects Component Development II (C++)
2-11
BSTRs

COM API – SysAllocString, SysStringLen,
SysFreeString
int main(int argc, char* argv[])
{
BSTR bstrDBPath = ::SysAllocString(L"..\\..\\..\\Data\\US.mdb");
BSTR bstrFCName = ::SysAllocString(L"States");
IFeatureClassPtr ipFeatureClass;
SelectFeatureClass1(bstrDBPath, bstrFCName, &ipFeatureClass);
::SysFreeString(bstrDBPath);
::SysFreeString(bstrFCName);
}

DTC smart type – _bstr_t
int main(int argc, char* argv[])
{
_bstr_t bstrDBPath(L"..\\..\\..\\Data\\US.mdb");
_bstr_t bstrFCName(L"States");
IFeatureClassPtr ipFeatureClass;
SelectFeatureClass1(bstrDBPath, bstrFCName, &ipFeatureClass);
}
Copyright © 2002 ESRI. All rights reserved.
Advanced ArcObjects Component Development II (C++)
2-12
VARIANTs

COM API – VariantInit() and VariantClear()
long l = 1000;
VARIANT vValue1;
::VariantInit(&vValue1);
vValue1.vt = VT_R4;
vValue1.lVal = l;
printf("The value is: %d\n", vValue1.lVal);
// Set variant type here
::VariantClear(&vValue1);

DTC smart type – _variant_t
long l = 1000;
_variant_t vValue2(l);
printf("The value is: %d\n", vValue2.lVal);
Copyright © 2002 ESRI. All rights reserved.
Advanced ArcObjects Component Development II (C++)
2-13
Not so smart smart types

Understand the behavior beforehand
// Variant and smart pointer test
IUnknownPtr ipUnk(CLSID_SimpleObject);
// Create an object #1
_variant_t vValue;
vValue.vt = VT_UNKNOWN;
vValue.punkVal = ipUnk; // What happens?
ipMagic = ipUnk;
ipMagic->get_ReferenceCount(&refCount);
// Release these
ipMagic = 0;
ipUnk = 0;
vValue.punkVal->QueryInterface(&ipMagic2); // What happens?
ipMagic2 = 0;
vValue.vt = VT_EMPTY;
// What happens now?
What is missing from this code?
Instructor Demo
Copyright © 2002 ESRI. All rights reserved.
Advanced ArcObjects Component Development II (C++)
2-14
HRESULTs

Always check HRESULTs returned by ArcObjects

Use SUCCEEDED() or FAILED() macros

Non-zero severity means failed
HRESULT hr;
IWorkspaceFactoryPtr ipWorkspaceFactory(CLSID_AccessWorkspaceFactory);
if (ipWorkspaceFactory == NULL) return E_FAIL;
IWorkspacePtr ipWorkspace;
if (FAILED(hr = ipWorkspaceFactory->OpenFromFile(bstrDatabasePath, NULL, &ipWorkspace)))
return hr;
…
Copyright © 2002 ESRI. All rights reserved.
Advanced ArcObjects Component Development II (C++)
2-15
Formatting HRESULTs

Possible to get and display the error code message
int main(int argc, char* argv[])
{
IMapPtr ipMap(CLSID_Map);
IMxDocument ipMxDoc;
if (FAILED(hr = ipMap->QueryInterface(&ipMxDoc))) // Force a failed HRESULT
HRESULTMESSAGE(hr);
}
inline void HRESULTMESSAGE( HRESULT hr )
{
LPVOID lpMsgBuf;
::FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_SYSTEM,
NULL,
hr,
// HRESULT
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
(LPTSTR) &lpMsgBuf,
0,
NULL );
_TCHAR buf[256];
_stprintf( buf, "%s", (_TCHAR *) lpMsgBuf );
::LocalFree( lpMsgBuf );
MessageBox(0, buf, _T("HRESULT ERROR MESSAGE"), MB_OK | MB_ICONINFORMATION );
}
Copyright © 2002 ESRI. All rights reserved.
Advanced ArcObjects Component Development II (C++)
2-16
Exception handling for DTC types

Native DTC classes throw _com_error exceptions

_com_error
 Wraps
IErrorInfo object
 Returns:
Description, HelpContext, HelpFile, Source
try
{
// Force smart pointer error...
IMapPtr ipMap;
IActiveViewPtr ipAV;
ipMap->QueryInterface(&ipAV);
}
catch (_com_error & err)
{
ErrorHandler(err);
}
void ErrorHandler(_com_error err)
{
_bstr_t bstrError;
if (&err == NULL) return;
bstrError = _T("Smart type error:"+
err.Description().length() > 0 ? (LPCTSTR)
err.Description() : err.ErrorMessage());
::MessageBox(NULL, bstrError, _T("Generic Error"),
MB_OK | MB_TASKMODAL);
}
Copyright © 2002 ESRI. All rights reserved.
Advanced ArcObjects Component Development II (C++)
2-17
Developing console applications

Database related – Adding, deleting, and updating

Utility applications – Print jobs, describe feature classes
int main(int argc, char* argv[])
{
CoInitialize(NULL);
HRESULT hr;
IFeatureClassPtr ipFeatureClass;
_bstr_t bstrDBPath(L"..\\..\\..\\Data\\US.mdb");
_bstr_t bstrFCName(L"States");
hr = SelectFeatureClass1(bstrDBPath, bstrFCName, &ipFeatureClass);
if (FAILED(hr))
return -1;
::MessageBox(0, _T("Found feature class!"), _T("Console Applicaiton"), MB_OK);
hr = PrintFeatureClassInformation(ipFeatureClass);
if (FAILED(hr))
return -1;
::MessageBox(0, _T("Printed feature class info!"), _T("Console Applicaiton"), MB_OK);
CoUninitialize();
return 0;
}
Copyright © 2002 ESRI. All rights reserved.
Advanced ArcObjects Component Development II (C++)
2-18
Writing ArcObjects/Visual Studio exercises

Some VS projects are written from scratch

Format-related
 All
code inserts are prefixed with file name (e.g., File.h)
 ‘…’
means ‘scroll down until you find’
 Some
 Bold
steps have ‘step insert numbers’
means ‘write code’
Copyright © 2002 ESRI. All rights reserved.
// MBFeature.h : Declaration of the CMBFeature
…
public:
CMBFeature() : m_pInnerUnk(NULL)
{
}
// ----------- Step 2.6 ---------DECLARE_GET_CONTROLLING_UNKNOWN()
…
BEGIN_COM_MAP(CMBFeature)
COM_INTERFACE_ENTRY(IMBFeature)
COM_INTERFACE_ENTRY(ISupportErrorInfo)
COM_INTERFACE_ENTRY(IFeatureDraw)
END_COM_MAP()
};
Advanced ArcObjects Component Development II (C++)
2-19
More exercise hints…

Follow conventions
 Project
and class names
 Project
and file paths

Copy and paste ExerciseFunctions.h file

Use exercise shortcuts

Be careful cutting and pasting solutions
Copyright © 2002 ESRI. All rights reserved.
Advanced ArcObjects Component Development II (C++)
2-20
Exercise 2 overview

Create a single ArcObjects COM client

Import the esriCore.olb correctly

Initialize the COM library

Accesses a geodatabase

Print featureclass name and field information

Challenge: Provide client-side error handling
Copyright © 2002 ESRI. All rights reserved.
Advanced ArcObjects Component Development II (C++)
2-21
Review

What is the first thing you need to do to work with
ArcObjects in VC++?

Why might you want to create an ArcObjects consoletype application?

What are the dangers of using smart types?

True or False:
VARIANT_TRUE = 1 and VARIANT_FALSE = 0?
Copyright © 2002 ESRI. All rights reserved.
Advanced ArcObjects Component Development II (C++)
2-22
Auteur
Документ
Catégorie
Без категории
Affichages
8
Taille du fichier
146 Кб
Étiquettes
1/--Pages
signaler