18.04.2015 Views

ArcGIS Engine Developer Guide

ArcGIS Engine Developer Guide

ArcGIS Engine Developer Guide

SHOW MORE
SHOW LESS

Create successful ePaper yourself

Turn your PDF publications into a flip-book with our unique Google optimized e-Paper software.

VISUAL C++<br />

::SetWindowText(m_hWnd, OLE2CT(bstrTitle));<br />

}<br />

return S_OK;<br />

Implementing noncreatable classes<br />

Noncreatable classes are COM objects that cannot be created by CoCreateInstance.<br />

Instead, the object is created within a method call of a different object, and an<br />

interface pointer to the noncreatable class is returned. This type of object is<br />

found in abundance in the geodatabase model. For example, FeatureClass is<br />

noncreatable and can only be obtained by calling one of a number of methods;<br />

one example is the IFeatureWorkspace::OpenFeatureClass method.<br />

One advantage of a noncreatable class is that it can be initialized with private<br />

data using method calls that are not exposed in a COM API. Below is a simplified<br />

example of returning a noncreatable object:<br />

// Foo is a cocreatable object.<br />

IFooPtr ipFoo;<br />

HRESULT hr = ipFoo.CreateInstance(CLSID_Foo);<br />

// Bar is a noncreatable object; cannot use ipBar.CreateInstance(CLSID_Bar).<br />

IBarPtr ipBar;<br />

// Use a method on Foo to create a new Bar object.<br />

hr = ipFoo->CreateBar(&ipBar);<br />

ipBar->DoSomething();<br />

The steps required to change a cocreatable ATL class into a noncreatable class are<br />

shown below:<br />

1. Add “noncreatable” to the .idl file’s coclass attributes.<br />

[<br />

uuid(DCB87952-0716-4873-852B-F56AE8F9BC42),<br />

noncreatable<br />

]<br />

coclass Bar<br />

{<br />

[default] interface IUnknown;<br />

interface IBar;<br />

};<br />

2. Change the class factory implementation to fail any cocreate instances of the<br />

noncreatable class. This happens via ATL’s object map in the main DLL<br />

module.<br />

BEGIN_OBJECT_MAP(ObjectMap)<br />

OBJECT_ENTRY(CLSID_Foo, CFoo)<br />

// Creatable object<br />

OBJECT_ENTRY_NON_CREATEABLE(CLSID_Bar, CBar) // Noncreatable object<br />

END_OBJECT_MAP()<br />

3. Optionally, the registry entries can be removed. First, remove the registry<br />

script for the object from the resources (Bar.rgs in this example). Then change<br />

the class definition DECLARE_REGISTRY_RESOURCEID(IDR_BAR) to<br />

DECLARE_NO_REGISTRY().<br />

Chapter 4 • <strong>Developer</strong> environments • 107

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!