Author Topic: LineType display in a form  (Read 8244 times)

0 Members and 1 Guest are viewing this topic.

gile

  • Gator
  • Posts: 2520
  • Marseille, France
LineType display in a form
« on: May 05, 2010, 03:26:26 PM »
Hi,

Is there a way to display the line type appearence (not the ascii description) in a form (or palette), even for non autoCAD line types ?
Speaking English as a French Frog

LE3

  • Guest
Re: LineType display in a form
« Reply #1 on: May 05, 2010, 04:41:31 PM »
Have you seen here:

http://through-the-interface.typepad.com/through_the_interface/2008/02/using-standard.html

Or if possible to PInvoke the undocumented:  acedLinetypeDialog(); function

Maybe.

gile

  • Gator
  • Posts: 2520
  • Marseille, France
Re: LineType display in a form
« Reply #2 on: May 06, 2010, 12:43:32 AM »
Thanks Luis,
But the LineTypeDialog() class is not really what I'm looking for.
I have to build my own form (for a linetype convertor) so that the user can see the lintype appearence to makethe conversion.
Speaking English as a French Frog

LE3

  • Guest
Re: LineType display in a form
« Reply #3 on: May 06, 2010, 10:25:05 AM »
Thanks Luis,
But the LineTypeDialog() class is not really what I'm looking for.
I have to build my own form (for a linetype convertor) so that the user can see the lintype appearence to makethe conversion.

Hi Gile,

Oh... I see

I have done it with MFC (see image attached below) by parsing a .lin file and making a map with the name and appearance and then transfer that info into a list report style control on my form.

PM me if you want to have a look into the functions (that guess can be easy to port to C#) - maybe.

fixo

  • Guest
Re: LineType display in a form
« Reply #4 on: May 06, 2010, 11:04:21 AM »
Hi,

Is there a way to display the line type appearence (not the ascii description) in a form (or palette), even for non autoCAD line types ?

Play around this one

Code: [Select]
        static public void ReadLinFile()
        {
            string[]data = File.ReadAllLines(
@"C:\Documents and Settings\admin\Application Data\Autodesk\AutoCAD 2008\R17.1\enu\Support\user.lin", Encoding.Default);
foreach (string line in data)
{
    string[] item = line.Split(new char[] { ',' });

    if ((item.Length ==2)&& (item[0].StartsWith("*")))
        if (!item[0].Equals("*ACAD_ISO09W100"))
        {

            Console.WriteLine(" ||| " + item[0].TrimStart('*') + " ||| " +
                item[1].Substring(item[1].Length - 20) + " ||| ");
        }
        else
        {
            Console.WriteLine(" ||| " + item[0].TrimStart('*') + " ||| " +
                item[1].Substring(item[1].Length - 15) + " ||| ");
        }

            }
            Console.Read();

        }

~'J'~

gile

  • Gator
  • Posts: 2520
  • Marseille, France
Re: LineType display in a form
« Reply #5 on: May 06, 2010, 03:24:37 PM »
Thanks both,
I'll study it this week-end. I'm too tired tonight and too busy tomorrow...
Speaking English as a French Frog

gile

  • Gator
  • Posts: 2520
  • Marseille, France
Re: LineType display in a form
« Reply #6 on: May 16, 2010, 04:06:44 AM »
As far as I understand, both replies use the ascii description of the .lin file.

I'm trying to explain another way:
I recieve a dwg file created with VectorWorks, ArchiCAD or any other non AutoCAD (or clone) software.
The files contains many linetypes which doesn't own to acad(iso).lin or my company standard .lin file and I want to convert them into 'standard linetypes'.
This is the goal of the tool I'm working on.

All these unknown linetypes may or may not have an ascii description but I'd like the ListView to show each loaded lintype appearance to the user so that he can easyly choose a 'standard linetype' to make the conversion.

In above pictures,
1 - What I already have (Name and Description columns)
2- In the .NET LineTypeDialog, the column I want to add to my ListView
Speaking English as a French Frog

It's Alive!

  • Retired
  • Needs a day job
  • Posts: 8783
  • AKA Daniel
Re: LineType display in a form
« Reply #7 on: May 16, 2010, 05:54:39 AM »
Doesn't look like an easy task, you may need to somehow evaluate the AcDbLinetypeTableRecord properties

It's Alive!

  • Retired
  • Needs a day job
  • Posts: 8783
  • AKA Daniel
Re: LineType display in a form
« Reply #8 on: May 16, 2010, 11:27:10 PM »
Gile, I found an undocumented function in ARX that draws line types.
I would bet that you could p/invoke it if you can figure out how to get the device context (as an INTPTR) from your control.

mangled/un-mangled
DrawLineTypeItemHelper@@YGXPAVCDC@@AAVAcDbObjectId@@VCRect@@H@Z
DrawLineTypeItemHelper(CDC *cdc, AcDbObjectId &id, CRect rect, INT_PTR num); //num can be 0



gile

  • Gator
  • Posts: 2520
  • Marseille, France
Re: LineType display in a form
« Reply #9 on: May 17, 2010, 04:19:32 AM »
Thanks Daniel, :lol:

This seems to be exactly what I'm looking for.
But as I'm not very comfortable with P/Invoke, moreover with an undocumented function, it will be difficult.
I'm gonna try...

Thanks again.
Speaking English as a French Frog

It's Alive!

  • Retired
  • Needs a day job
  • Posts: 8783
  • AKA Daniel
Re: LineType display in a form
« Reply #10 on: May 17, 2010, 09:43:45 AM »
I tried briefly but I could not get anything to work, I'll try again when I get time


Code: [Select]
namespace ExecMethod
{
  public partial class LineTypeForm : Form
  {
    ObjectIdCollection ids;
    public LineTypeForm()
    {
      ids = new ObjectIdCollection();
      InitializeComponent();
      getlinetypeid();
    }

    [DllImport("acad.exe", CallingConvention = CallingConvention.Cdecl,
      EntryPoint="?DrawLineTypeItemHelper@@YGXPAVCDC@@AAVAcDbObjectId@@VCRect@@H@Z")]
    extern static void crashandburn(IntPtr cdc,ref ObjectId id, Rectangle rect, int num);

    public void getlinetypeid()
    {
      Database db = HostApplicationServices.WorkingDatabase;
      TransactionManager manager = db.TransactionManager;
      using (Transaction transaction = manager.StartTransaction())
      {
        LinetypeTable tbl = transaction.GetObject
          (db.LinetypeTableId, OpenMode.ForRead) as LinetypeTable;
        foreach(ObjectId id in tbl)
          ids.Add(id);
      }
    }

    private void LineTypeForm_Paint(object sender, PaintEventArgs e)
    {
        // you need to get the 'Graphics' from the control
        IntPtr dc = e.Graphics.GetHdc();
        ObjectId _id = ids[0];
        //if this worked you would iterate though ids and set the rectangle to the
        //location of the cells in your control
        crashandburn(dc, ref _id, e.ClipRectangle, 0);
        e.Graphics.ReleaseHdc(dc);
    }

  }
}


It's Alive!

  • Retired
  • Needs a day job
  • Posts: 8783
  • AKA Daniel
Re: LineType display in a form
« Reply #11 on: May 17, 2010, 10:54:45 PM »
Hi Gile,

It's not looking good, I can't find a way to create a CDC class from p/invoke. I was thinking  Graphics.GetHdc would work, but it does not  :mrgreen:

LE3

  • Guest
Re: LineType display in a form
« Reply #12 on: May 19, 2010, 08:20:04 PM »
Hi Gile,

Have you seen or tried the implementation of: TextRenderer.DrawText ?

By following what Daniel mentioned, I did a quick test and appears to be the ticket - sorry, don't have time to be of more help, have been busy.. :-(

And a quick question, on those drawings are you able to extract any information from those linetypes? it is available? - if you can upload a drawing here.


Cheers!

gile

  • Gator
  • Posts: 2520
  • Marseille, France
Re: LineType display in a form
« Reply #13 on: May 20, 2010, 05:38:24 PM »
Thank you both

I have not much time to play with this these days, but I begin to see a way rewriting the Linetype datas from the LinetypeTableRecord properties and methods. Its quite easy with dashes and text, more difficult with shx shapes(more if they're unknown. Then I'll try to draw the lines in the form using GDI+...
Speaking English as a French Frog

Chumplybum

  • Newt
  • Posts: 97
Re: LineType display in a form
« Reply #14 on: May 21, 2010, 02:05:09 AM »
Gile,

i found this function inside the AutoDesk.AutoCAD.Internal namespace: DrawLineTypePattern (only in A2010 though, not sure about A2009?)... i'm assuming that this is undocumented function (as its in the internal namespace). I've been able to generate bitmaps of all the linetypes in the current drawing from this function and display them in a datagridview, see rough code below:

Code: [Select]
Imports AADS = Autodesk.AutoCAD.DatabaseServices

Imports System.Runtime.InteropServices
Imports System.Windows.Forms

Public Class Dialog1

    Private Sub OK_Button_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles OK_Button.Click
        Me.DialogResult = System.Windows.Forms.DialogResult.OK
        Me.Close()
    End Sub

    Private Sub Cancel_Button_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Cancel_Button.Click
        Me.DialogResult = System.Windows.Forms.DialogResult.Cancel
        Me.Close()
    End Sub

    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click

        Try
            Dim db As AADS.Database = AADS.HostApplicationServices.WorkingDatabase

            '' Start a transaction
            Using Transaction As AADS.Transaction = db.TransactionManager.StartTransaction()

                '' Open the Layer table for read
                Dim lt As AADS.LinetypeTable = Transaction.GetObject(db.LinetypeTableId, AADS.OpenMode.ForRead)
                Dim CurrentLT As AADS.LinetypeTableRecord

                Dim enumerator As AADS.SymbolTableEnumerator = lt.GetEnumerator
                Dim Rect As System.Drawing.Rectangle = New System.Drawing.Rectangle(0, 0, Me.DataGridView1.Columns.Item("ImageColumn").Width, Me.DataGridView1.RowTemplate.Height)

                While enumerator.MoveNext
                    CurrentLT = Transaction.GetObject(enumerator.Current, Autodesk.AutoCAD.DatabaseServices.OpenMode.ForRead)

                    Me.DataGridView1.Rows.Add(CurrentLT.Name, System.Drawing.Bitmap.FromHbitmap(Autodesk.AutoCAD.Internal.Utils.DrawLineTypePattern(enumerator.Current, Rect.Left, Rect.Top, Rect.Right, Rect.Bottom)))

                End While

                Transaction.Commit()
            End Using

            MsgBox(Me.DataGridView1.Rows.Count.ToString)
        Catch ex As Exception
            Throw ex
        End Try

    End Sub

End Class


HTH


cheers, Mark