Close

Relief for ODA Team in Ukraine

Learn more
ODA Drawings SDK
Identifying Objects using a Handle

A handle stores the unique identifier of an object within the scope of a single database. The database associates a handle with an object and stores the handle together with the object. When a database is saved in a file, handles are also saved with the objects, and they persist from one run-time session to another. Programmatically, a handle is a 64-bit integer value that is initialized by a database when a new object is added.

The OdDbHandle class implements a handle and represents the interface for getting and modifying an identification value. The OdDbHandle class does not inherit the standard database functionality; it is a number used for associating objects of a database. This class declares the OdUInt64 member that stores the identification value, methods for getting the value, and operators for modifying or comparing a handle. This class works with a handle either as an integer value or string value, and represents it in hexadecimal format.

Creating a handle

To create a handle, use its constructor. The OdDbHandle class has an overloaded constructor that creates an instance using an integer value, ASCII string, wide-character string, 64-bit integer value, or other handle as an argument. A constructor without arguments initializes the handle with zero. For example:


// default value
OdDbHandle h1;
odPrintConsoleString(L"\nH1 = %llx", h1);      // H1 = 0

// an integer value
OdDbHandle h2(0x1F4A);
odPrintConsoleString(L"\nH2 = %llx", h2);      // H2 = 1f4a

// ascii-character string value
OdDbHandle h3("2CB5E3");
odPrintConsoleString(L"\nH3 = %llx", h3);      // H3 = 2cb5e3

// wide-character string value
OdDbHandle h4(OD_T("3C57B21E"));
odPrintConsoleString(L"\nH4 = %llx", h4);      // H4 = 3c57b21e

// 64-bit integer value
OdUInt64 vInt64 = 456123;
OdDbHandle h5(vInt64);
odPrintConsoleString(L"\nH5 = %llx", h5);      // H5 = 6f5bb

// OdString value
OdString sValue = L"42ED18AC"
OdDbHandle h6(sValue);
odPrintConsoleString(L"\nH6 = %llx", h6);      // H6 = 42ed18ac

// handle value
OdDbHandle hh(h4);
odPrintConsoleString(L"\nH = %llx", hh);       // H = 3c57b21e

Getting a handle

To get a handle, use the handle() and getDbHandle() methods of the object and the getHandle() methodof object ID associated with the object. For details, see Getting an Identifier.

Getting a handle value

To get a handle as a string value, use the ascii() method which returns the string of hexadecimal digits as a value of the OdString type. For example:


odPrintConsoleString(L"\nH = %s", hh.ascii().c_str());
// or
wcout << L"\nH = " << hh.ascii();              // H = 3C57B21E

To get a handle as a null-terminated string, use the getInfoAsciiBuffer() method which requires a pointer to an array of characters at least 17 bytes long and fills this array using hexadecimal digits obtained by dividing a 64-bit integer value by half-bytes. For example:


OdChar buffer[17];

hh.getIntoAsciiBuffer(buffer);

odPrintConsoleString(L"\n\"%s\"", buffer);     // "3C57B21E"

To get a handle as an array of bytes, use the bytes() method which requires a pointer to an array containing eight values of the OdUInt8 type and fills this array using 8-bit integer values obtained by dividing a 64-bit integer value by 8 bytes. For example:


OdUInt8 chunk[8];

hh.bytes(chunk);

odPrintConsoleString(L"\nArray: ");
for(i=7 ; i >= 0 ; i--)
  odPrintConsoleString(L"%x,", chunk[i]);      // 0,0,0,0,3c,57,b2,1e,

To check whether a handle has an identifier, use the isNull() method which returns True when the 64-bit integer value equals zero or returns False when the handle is set to an identifier. A zero value denotes NULL for a handle. For example:


// H1 is null
odPrintConsoleString(L"\nH1 %s", (h1.isNull()) ? L"is null" : L"is not null");
// H2 is not null
odPrintConsoleString(L"\nH2 %s", (h2.isNull()) ? L"is null" : L"is not null");

Setting a handle value

To set a value in a handle, use the assignment operator that modifies an instance using an integer, 64-bit integer, ASCII string, wide-character string, or handle values. For example:


// an integer value
h2 = 0x2A3B4C;
odPrintConsoleString(L"\nH2 = %llx", h2);      // H2 = 2a3b4c

// ascii-character string value
h3 = "1AD2E3";
odPrintConsoleString(L"\nH3 = %llx", h3);      // H3 = 1ad2e3

// wide-character string value
h4 = OD_T("3C57B2");
odPrintConsoleString(L"\nH4 = %llx", h4);      // H4 = 3c57b2

// 64-bit integer value
h5 = vInt64;
odPrintConsoleString(L"\nH5 = %llx", h5);      // H5 = 6f5bb

// handle value
h6 = h4;
odPrintConsoleString(L"\nH6 = %llx", h6);      // H6 = 3c57b2

To modify a handle, use the addition operator which adds a 64-bit integer value to the current value of a handle. For example:


hh = 0x1F;
hh += 0x0E;
odPrintConsoleString(L"\nH = %llx", hh);       // H = 2d
// or
hh = 0xA3B6 + 0x1E2C;
odPrintConsoleString(L"\nH = %llx", hh);       // H = c1e2

Comparing and forcing a handle

To compare handles, use the comparison operators that compare the handles as 64-bit integer values and have an implementation for pairs: (handle ? handle) and (handle ? UInt64). For example:


h2 = 5;    h3 = 8;    h4 = 5;
odPrintConsoleString(L"\n(h2 < h3)  = %d, (h2 > h3)  = %d", (h2 < h3),  (h2 > h3));
odPrintConsoleString(L"\n(h3 <= h2) = %d, (h3 >= h2) = %d", (h3 <= h2), (h3 >= h2));
odPrintConsoleString(L"\n(h2 <= h4) = %d, (h2 >= h4) = %d", (h2 <= h4), (h2 >= h4));
odPrintConsoleString(L"\n(h2 == h3) = %d, (h2 != h3) = %d", (h2 == h3), (h2 != h3));
odPrintConsoleString(L"\n(h2 == h4) = %d, (h2 != h4) = %d", (h2 == h4), (h2 != h4));

// Result is following:
// (h2 < h3)  = 1, (h2 > h3)  = 0
// (h3 <= h2) = 0, (h3 >= h2) = 1
// (h2 <= h4) = 1, (h2 >= h4) = 1
// (h2 == h3) = 0, (h2 != h3) = 1
// (h2 == h4) = 1, (h2 != h4) = 0

A handle has an operator that casts it to a 64-bit integer value. For example:


hh = L"1D3F2C4B"

vInt64 = hh;
odPrintConsoleString(L"\nH = %llx", vInt64);   // H = 1D3F2C4B

vInt64 = h1;
odPrintConsoleString(L"\nH = %llx", vInt64);   // H = 0

The handle can be entered as a 64-bit integer value which can be assigned to an existing handle or can be passed as an argument of a function. For example:


wcin >> hex >> vInt64 >> dec;

OdDbHandle handle = vInt64;

OdResBufPtr pRb = newRb(OdResBuf::kDxfXdHandle, vInt64);

Note: You can cast a 64-bit integer value to a handle, or you can cast a handle to a 64-bit integer value.

Setting a custom handle value for a database entity

The following code reserves a specified number of object handle values in an OdDbDatabase, and then supplies a custom handle value for an entity that is added to the database:


// Create a database but do NOT initialize the default objects in the database.
OdDbDatabasePtr pDb = myServices.createDatabase(false); 

// Reserve myHandSeed handle value, which causes all future object 
// handles created automatically to be greater than myHandSeed. 
pDatabase->getOdDbObjectId(myHandSeed, true);    // Create if not found

// Default objects created starting with handle myHandSeed + 1.
pDb->initialize();

// Create a new entity
OdDbCirlePtr pCirc = OdDbCircle::createObject();
// Set circle params...

// Add the circle to database with a specified handle 
pDb->addOdDbObject(pCircle,                      // Entity to add
                   OdDbObjectId::kNull,          // OwnerId is set when entity is added to block
                   MyCircleHandle);              // Custom object handle

// Add the entity to a block
pBlockRecord->appendOdDbEntity(pCircle);

See Also

Identifying the Objects of Databases

Copyright © 2002 – 2022. Open Design Alliance. All rights reserved.