Author Topic: Writing handles to a text file problem in .net 2005  (Read 5717 times)

0 Members and 1 Guest are viewing this topic.

DaveW

  • Guest
Writing handles to a text file problem in .net 2005
« on: June 27, 2006, 09:15:15 PM »
I have this code below that is suppose to write the handles of the objects in the selection set to a text file.

It was created for .net 2002. A c++ programmer tried to make some changes to it for the unicode text issue in .net 2005.

This piece of code sometimes drops the last letter or number and always has spaces in between the letters and numbers of each of the output handles.

Can anyone out there fix a couple of lines and make this work correctly?


Thank you,

Dave

Code: [Select]

  FILE *f = _tfopen( _T("c:\\SL-DXF\\handles.txt"), _T("wt") );
  for (int i = 0; i < testLen; i++)
  {
  ads_name entname;
  ads_ssname( solidGroup, i, entname );
  AcDbObjectId id;
  acdbGetObjectId( id, entname );
  AcDbObject *obj;
  acdbOpenAcDbObject( obj, id, AcDb::kForRead );
  AcDbHandle h;
  obj->getAcDbHandle( h );
  obj->close();
  TCHAR buf[ 32 ];
  h.getIntoAsciiBuffer( buf );
  _tcscat( buf, _T("\n") );
  fwrite( buf, _tcslen( buf ), 1, f );
  }
  fclose( f );

MickD

  • Gator
  • Posts: 3314
  • (x-in)->[process]->(y-out)
Re: Writing handles to a text file problem in .net 2005
« Reply #1 on: June 28, 2006, 03:04:56 AM »
Works ok for me?? <edit - tested in 2006 />

Code: [Select]
static void TestSS(void)
{
ads_name sset;
// Retrieve all entities.
acedSSGet("A", NULL, NULL, NULL, sset);
long testLen;
acedSSLength(sset, &testLen);

FILE *f = _tfopen( _T("c:\\DCS_3D\\handles.txt"), _T("wt") );
for (int i = 0; i < testLen; i++)
{
ads_name entname;
ads_ssname( sset, i, entname );
AcDbObjectId id;
acdbGetObjectId( id, entname );
AcDbObject *obj;
acdbOpenAcDbObject( obj, id, AcDb::kForRead );
AcDbHandle h;
obj->getAcDbHandle( h );
obj->close();
TCHAR buf[ 32 ];
h.getIntoAsciiBuffer( buf );
_tcscat( buf, _T("\n") );
fwrite( buf, _tcslen( buf ), 1, f );
}
fclose( f );
acedSSFree(sset);
}
Forth is like the Tao: it is a Way, and is realized when followed.
Its fragility is its strength; its simplicity is its direction - Michael Ham

Lao Tzu: “To attain knowledge, add things
every day; to obtain wisdom, remove things every day.”

Draftek

  • Water Moccasin
  • Posts: 1501
Re: Writing handles to a text file problem in .net 2005
« Reply #2 on: June 28, 2006, 07:55:56 AM »
I'll give it a try in 2007 sometime today.

For now, I need COFFEE!
Soli Deo Gloria

SteveAtCADfx

  • Guest
Re: Writing handles to a text file problem in .net 2005
« Reply #3 on: June 28, 2006, 09:56:44 AM »
Since 2007 requires UNICODE, you're going to need to cast the buf to a CStringA and divide the length by two, so

fwrite( buf, _tcslen( buf ), 1, f );

becomes

fwrite(CStringA(buf), _tcslen( buf ) / 2, 1, f );

Also, to keep compatibility with older versions of AutoCAD you will need to add the following to your project (typically in stdAfx.h for ObjectARX applications):

#ifndef R17
#define CStringA CString
#endif

This is of course assuming you defined R17 in your Preprocessor Definitions.
Regards,
Steve
« Last Edit: June 28, 2006, 10:02:16 AM by SteveAtCADfx »

Draftek

  • Water Moccasin
  • Posts: 1501
Re: Writing handles to a text file problem in .net 2005
« Reply #4 on: June 28, 2006, 10:45:42 AM »
First of all, I'm a C++ hack so Steve's is probably the best solution but since I got it to work, I'm going to post it damnit! :)

I took a different approach:

AutoCAD requires UNICODE as mentioned but since fwrite is not an autocad method I used an ATL macro to convert the handle result back to a char*.

Code: [Select]
                 ads_name sset;
// Retrieve all entities.
acedSSGet(_T("A"), NULL, NULL, NULL, sset);
long testLen;
acedSSLength(sset, &testLen);

FILE *f = _tfopen( _T("c:\\handles.txt"), _T("wt") );
for (int i = 0; i < testLen; i++)
{
ads_name entname;
ads_ssname( sset, i, entname );
AcDbObjectId id;
acdbGetObjectId( id, entname );
AcDbObject *obj;
acdbOpenAcDbObject( obj, id, AcDb::kForRead );
AcDbHandle h;
obj->getAcDbHandle( h );
obj->close();
TCHAR buf[ 32 ];
h.getIntoAsciiBuffer( buf );
USES_CONVERSION;
char *oldBuf = W2A(buf);
strcat(oldBuf, "\n");
fwrite( oldBuf, strlen( oldBuf ), 1, f );
}
fclose( f );
acedSSFree(sset);
you will need an include to the atl macro in <atlconv.h> in the header
Soli Deo Gloria

DaveW

  • Guest
Re: Writing handles to a text file problem in .net 2005
« Reply #5 on: June 28, 2006, 11:16:15 AM »
I tried both.

Steve must have missed something, becasue I still get the same error. I went ahead and just asked him to fix it.

I tried your code Draftek and got this error:
Error   5   error LNK2019: unresolved external symbol "unsigned int (__stdcall* ATL::g_pfnGetThreadACP)(void)" (?g_pfnGetThreadACP@ATL@@3P6GIXZA) referenced in function "unsigned int __stdcall ATL::_AtlGetConversionACP(void)" (?_AtlGetConversionACP@ATL@@YGIXZ)   STRETCH.obj


I have no clue what it means.

I did add the include# as requested.

Thanks,

Dave   

LE

  • Guest
Re: Writing handles to a text file problem in .net 2005
« Reply #6 on: June 28, 2006, 11:29:34 AM »
Still have not done any of the updates for A2007, see if the below change does a difference.

Code: [Select]
fwrite( buf, (_tcslen(buf) * sizeof(TCHAR)), 1, f );

DaveW

  • Guest
Re: Writing handles to a text file problem in .net 2005
« Reply #7 on: June 28, 2006, 11:59:21 AM »
Le,

Did not help.

Everyone,

I just got off the phone with Steve. He said my project does not have ATL or MFC, so neither CStringA or USES_CONVERSION will work.

He is working on it now and will post the solution back here when done.

Thanks for all you help everyone. I had no idea that this was nearly as involved as it is.

SteveAtCADfx

  • Guest
Re: Writing handles to a text file problem in .net 2005
« Reply #8 on: June 28, 2006, 12:04:30 PM »
ok, thanks to our internal guru, here is the solution for non ATL or MFC applications:

        for (int i = 0; i < testLen; i++)
        {
           ads_name entname;
           ads_ssname( solidGroup, i, entname );
           AcDbObjectId id;
           acdbGetObjectId( id, entname );
           AcDbObject *obj;
           acdbOpenAcDbObject( obj, id, AcDb::kForRead );
           AcDbHandle h;
           obj->getAcDbHandle( h );
           obj->close();
           TCHAR buf[ 32 ];
           h.getIntoAsciiBuffer( buf );
           _tcscat( buf, _T("\n") );

           int strl = wcslen( buf );
           BOOL used;
           int sz = WideCharToMultiByte( CP_ACP, WC_COMPOSITECHECK, buf, strl, NULL, 0, NULL, &used );
           char *buf2 = new char[ sz ];
           WideCharToMultiByte( CP_ACP, WC_COMPOSITECHECK, buf, strl, buf2, sz, NULL, &used );
           fwrite( buf2, sz, 1, f );
           delete [] buf2;

        }

For this to work you need to include windows.h

DaveW

  • Guest
Re: Writing handles to a text file problem in .net 2005
« Reply #9 on: June 28, 2006, 12:25:46 PM »
Works great Steve.

Thank you.

LE

  • Guest
Re: Writing handles to a text file problem in .net 2005
« Reply #10 on: June 28, 2006, 12:27:35 PM »
Great introduction Steve, welcome to theSwamp!

MickD

  • Gator
  • Posts: 3314
  • (x-in)->[process]->(y-out)
Re: Writing handles to a text file problem in .net 2005
« Reply #11 on: June 28, 2006, 05:52:51 PM »
Ditto^^, Welcome Steve.

I can see some very frustrated ARX coders now, it's going to be a nightmare to change all legacy code to support UC but what do you do?


Forth is like the Tao: it is a Way, and is realized when followed.
Its fragility is its strength; its simplicity is its direction - Michael Ham

Lao Tzu: “To attain knowledge, add things
every day; to obtain wisdom, remove things every day.”

LE

  • Guest
Re: Writing handles to a text file problem in .net 2005
« Reply #12 on: June 28, 2006, 05:56:23 PM »

Draftek

  • Water Moccasin
  • Posts: 1501
Re: Writing handles to a text file problem in .net 2005
« Reply #13 on: June 28, 2006, 09:02:49 PM »
Yeah. I've only got a few utility apps but it's taken me several days to get everything up to code (no pun intended). I can't imagine a large project or several projects.
Soli Deo Gloria

DaveW

  • Guest
Re: Writing handles to a text file problem in .net 2005
« Reply #14 on: June 29, 2006, 03:45:12 PM »
The above code was originally written for acad 2004 - 2006. I was doing this for a port to 2007.

Now that that is handled, her eis the original coded used in 2004-4006:
Code: [Select]
  FILE *f = fopen( "c:\\SL-DXF\\handles.txt", "wt" );
  for (int i = 0; i < testLen; i++)
  {
  ads_name entname;
  ads_ssname( solidGroup, i, entname );
  AcDbObjectId id;
  acdbGetObjectId( id, entname );
  AcDbObject *obj;
  acdbOpenAcDbObject( obj, id, AcDb::kForRead );
  AcDbHandle h;
  obj->getAcDbHandle( h );
  obj->close();
  char buf[ 32 ];
  h.getIntoAsciiBuffer( buf );
  strcat( buf, "\n" );
  fwrite( buf, strlen( buf ), 1, f );
  }
  fclose( f );


If I use this code in 2002 it compiles fine, but does not write to the file.

Any ideas why?


Thanks,

Dave