GetAttributes from C++

GetAttributes from C++

Anonymous
Not applicable
814 Views
4 Replies
Message 1 of 5

GetAttributes from C++

Anonymous
Not applicable
Hi,

I have a COM object from an ATL project and I call this object from AutoCAD VBA. I have a problem with the GetAttributes, the variant contain a bad ptr. Anyone have an idea of what I'm doing wrong ? Here is my code, vAttributes contain invalid data.

CErr acadCTSpecExt::LoadAttributesToMap
(
IAcadEntity* in_ipEntity,
CMapStringToString* in_pMapAttributes
)
{
CComQIPtr ipBlockRef(in_ipEntity);
if (ipBlockRef && ipBlockRef->HasAttributes == VARIANT_TRUE)
{
_variant_t vAttributes(ipBlockRef->GetAttributes());
if (vAttributes.parray)
{
LONG lLow, lUp;
CK_HR_TO_ERR(SafeArrayGetLBound(vAttributes.parray, 1, &lLow));
CK_HR_TO_ERR(SafeArrayGetUBound(vAttributes.parray, 1, &lUp));
for (long i=lLow; i<=lUp; ++i)
{
long lIndex = i;
_variant_t vAttribute;
CK_HR_TO_ERR(SafeArrayGetElement(vAttributes.parray, &lIndex, &vAttribute));

IAcadAttributeReferencePtr ipAttributeRef(vAttribute.pdispVal);
if (ipAttributeRef)
{
CComBSTR bsTag, bsValue;
ipAttributeRef->get_TagString(&bsTag);
CString sTag(bsTag);
sTag.MakeUpper();
ipAttributeRef->get_TextString(&bsValue);
CString sValue(bsValue);
sValue.MakeUpper();
in_pMapAttributes->SetAt(sTag, sValue);
}
}
}
}
0 Likes
815 Views
4 Replies
Replies (4)
Message 2 of 5

Anonymous
Not applicable
Have you tried CComVariant instead?

--
http://www.caddzone.com

AcadXTabs: MDI Document Tabs for AutoCAD 2009
Supporting AutoCAD 2000 through 2009
http://www.acadxtabs.com

wrote in message news:5902028@discussion.autodesk.com...
Hi,

I have a COM object from an ATL project and I call this object from AutoCAD VBA. I have a problem with the GetAttributes, the variant contain a bad ptr. Anyone have an idea of what I'm doing wrong ? Here is my code, vAttributes contain invalid data.

CErr acadCTSpecExt::LoadAttributesToMap
(
IAcadEntity* in_ipEntity,
CMapStringToString* in_pMapAttributes
)
{
CComQIPtr ipBlockRef(in_ipEntity);
if (ipBlockRef && ipBlockRef->HasAttributes == VARIANT_TRUE)
{
_variant_t vAttributes(ipBlockRef->GetAttributes());
if (vAttributes.parray)
{
LONG lLow, lUp;
CK_HR_TO_ERR(SafeArrayGetLBound(vAttributes.parray, 1, &lLow));
CK_HR_TO_ERR(SafeArrayGetUBound(vAttributes.parray, 1, &lUp));
for (long i=lLow; i<=lUp; ++i)
{
long lIndex = i;
_variant_t vAttribute;
CK_HR_TO_ERR(SafeArrayGetElement(vAttributes.parray, &lIndex, &vAttribute));

IAcadAttributeReferencePtr ipAttributeRef(vAttribute.pdispVal);
if (ipAttributeRef)
{
CComBSTR bsTag, bsValue;
ipAttributeRef->get_TagString(&bsTag);
CString sTag(bsTag);
sTag.MakeUpper();
ipAttributeRef->get_TextString(&bsValue);
CString sValue(bsValue);
sValue.MakeUpper();
in_pMapAttributes->SetAt(sTag, sValue);
}
}
}
}
0 Likes
Message 3 of 5

Anonymous
Not applicable
Yes I tried CComVariant but didn't change anything. I fixed it here is the code that's work.

CErr acadCTSpecExt::LoadAttributesToMap
(
IAcadEntity* in_ipEntity,
CMapStringToString* in_pMapAttributes
)
{
CComQIPtr IAcadBlockReference> ipBlockRef(in_ipEntity);
if (ipBlockRef && ipBlockRef->HasAttributes == VARIANT_TRUE)
{
_variant_t vAttributes(ipBlockRef->GetAttributes());
if (vAttributes.parray)
{
LONG lLow, lUp;
CK_HR_TO_ERR(SafeArrayGetLBound(vAttributes.parray, 1, &lLow));
CK_HR_TO_ERR(SafeArrayGetUBound(vAttributes.parray, 1, &lUp));
for (long i=lLow; i<=lUp; ++i)
{
CComPtr IAcadObject> ipObject;
CK_HR_TO_ERR(SafeArrayGetElement(vAttributes.parray, &i, &ipObject));

CComQIPtr IAcadAttributeReference> ipAttributeRef(ipObject);
if (ipAttributeRef)
{
CComBSTR bsTag, bsValue;
ipAttributeRef->get_TagString(&bsTag);
CString sTag(bsTag);
sTag.MakeUpper();
ipAttributeRef->get_TextString(&bsValue);
CString sValue(bsValue);
sValue.MakeUpper();
in_pMapAttributes->SetAt(sTag, sValue);
}
}
}
}

return CErr::None;
}
0 Likes
Message 4 of 5

Anonymous
Not applicable
Sebastien:

> if (ipBlockRef && ipBlockRef->HasAttributes == VARIANT_TRUE)

Is that a typo, or did you forget parentheses after HasAttributes?


> _variant_t vAttributes(ipBlockRef->GetAttributes());

What is the variant type of vAttributes after this line executes? If it
is VT_BYREF, your following code will fail. Have you tried assignment
instead (as below)?
_variant_t vAttributes = ipBlockRef->GetAttributes();
--
Owen Wengerd
President, ManuSoft <>
VP Americas, CADLock, Inc. <>
0 Likes
Message 5 of 5

Anonymous
Not applicable
The reason were having the problem is because if the safearray is empty, the UBOUND is -1 (rather than the safearray pointer being NULL).

Never assume a safearray contains any elements, you should always check the ubound to see if its -1 before you try to access it.

--
http://www.caddzone.com

AcadXTabs: MDI Document Tabs for AutoCAD 2009
Supporting AutoCAD 2000 through 2009
http://www.acadxtabs.com

wrote in message news:5902229@discussion.autodesk.com...
Yes I tried CComVariant but didn't change anything. I fixed it here is the code that's work.

CErr acadCTSpecExt::LoadAttributesToMap
(
IAcadEntity* in_ipEntity,
CMapStringToString* in_pMapAttributes
)
{
CComQIPtr IAcadBlockReference> ipBlockRef(in_ipEntity);
if (ipBlockRef && ipBlockRef->HasAttributes == VARIANT_TRUE)
{
_variant_t vAttributes(ipBlockRef->GetAttributes());
if (vAttributes.parray)
{
LONG lLow, lUp;
CK_HR_TO_ERR(SafeArrayGetLBound(vAttributes.parray, 1, &lLow));
CK_HR_TO_ERR(SafeArrayGetUBound(vAttributes.parray, 1, &lUp));
for (long i=lLow; i<=lUp; ++i)
{
CComPtr IAcadObject> ipObject;
CK_HR_TO_ERR(SafeArrayGetElement(vAttributes.parray, &i, &ipObject));

CComQIPtr IAcadAttributeReference> ipAttributeRef(ipObject);
if (ipAttributeRef)
{
CComBSTR bsTag, bsValue;
ipAttributeRef->get_TagString(&bsTag);
CString sTag(bsTag);
sTag.MakeUpper();
ipAttributeRef->get_TextString(&bsValue);
CString sValue(bsValue);
sValue.MakeUpper();
in_pMapAttributes->SetAt(sTag, sValue);
}
}
}
}

return CErr::None;
}
0 Likes