Обнаружил в классе TFlex.Model.Model2D.MultilineText (позволяет управлять многострочным текстом, см. команду TE: Создать текст - Создать многострочный текст<M>) странности при установке свойства Node. Свойству нельзя задать значение, отличное от null. То есть, с помощью API нельзя привязать текст к узлу. Вручную в CAD это, конечно, возможно. Ниже привожу код тестового макроса. Он был создан с помощью встроенного редактора макросов TFlex CAD. Макрос находится в файле "Тест MultilineText_Node.grb".
Код
using System;
using TFlex.Model;
using TFlex.Model.Model2D;
using System.Windows.Forms;
namespace NewMacroNamespace
{
public class NewMacroClass
{
public static void Привязать_многострочный_текст_к_узлу()
{
Document doc = TFlex.Application.ActiveDocument;
if (doc != null &&
doc.Selection.GetSize() > 0 && //Выбран хотя бы один элемент
doc.Selection.GetAt(0).GetType() == typeof(MultilineText)) //И это многострочный текст
{
if (!doc.IsChanging())
doc.BeginChanges("Привязка текста к узлу");
MultilineText text = (MultilineText)doc.Selection.GetAt(0); //В условии тип уже проверили
FreeNode node = new FreeNode(doc, new Parameter(10), new Parameter(20)); //Координаты узла X=10, Y=20
//Пытаемся привязать текст к только что созданному узлу node
text.Node = node;
if (doc.IsChanging())
doc.EndChanges();
//Сообщение в окне всегда будет "Свойство Node выбранного текста: null"
MessageBox.Show(
String.Format("Свойство Node выбранного текста: {0}",
text.Node == null ? "null" : text.Node.GetType().FullName));
}
}
}
}
Перед запуском макроса необходимо выбрать многострочный текст на единственной странице. После выполнения строки
Код
text.Node = node;
свойство Node остаётся null. В конце работы макрос всегда показывает сообщение "Свойство Node выбранного текста: null". Для лучшего понимания, что происходит в блоке set, заглянем в недра сборки TFlexAPI с помощью бесплатной утилиты JetBrains dotPeek (https://www.jetbrains.com/decompiler/). Декомпилированный код блока set свойства TFlex.Model.Model2D.MultilineText.Node:
Код
// Assembly: TFlexAPI, Version=12.0.74.0, Culture=neutral, PublicKeyToken=eab6a180a6be0d77
// Assembly location: C:\Program Files (x86)\T-FLEX\T-FLEX CAD 12\Program\TFlexAPI.dll
/// <summary>
/// Узел привязки текста
/// </summary>
public unsafe Node Node
{
get
{ ... }
set
{
this.CheckObject((ModelObject) value);
TFMultilineText* textForSet = this.TextForSet;
if (value != null)
return; //от себя: нет никакой реализации для установки свойства
*(int*) ((IntPtr) textForSet + 236) = -1; //от себя: выполняется для случая value == null
}
}
Обратите внимание на строки:
Код
if (value != null)
return;
Значит, установить свойство Node в не-null невозможно, вместо этого происходит простой возврат из блока set. Для сравнения привожу аналогичный код для класса LineText. Он позволяет управлять строчным текстом TFlex CAD, см. команду TE: Создать текст - Создать строчный текст<D>. Блок set для свойства TFlex.Model.Model2D.LineText.Node:
Код
/// <summary>
/// Узел привязки текста
/// </summary>
public unsafe Node Node
{
get
{ ... }
set
{
this.CheckObject((ModelObject) value);
if (value == null)
*(int*) ((IntPtr) this.repSet + 236) = -1;
else
*(int*) ((IntPtr) this.repSet + 236) = <Module>.CTFObject.GetIndex((CTFObject*) value.repGet);
}
Обратите внимание, что здесь обрабатываются оба случая, когда value == null и когда != null. В отличие от MultilineText.Node, свойство LineText.Node и позволяет привязать строчный текст к заданному узлу. Жду ваших комментариев, уважаемые форумчане. Надеюсь, что вышеописанный недочёт дойдёт до внимания разработчиков и будет устранён для API TFlex CAD 12. Файл "Тест MultilineText_Node.grb" прикреплён к сообщению. Используемая версия CAD: TFlex CAD x32 12.0.74.0 Версия среды выполнения: v4.0.30319 Сборка TFlexAPI, Version=12.0.74.0, Culture=neutral, PublicKeyToken=eab6a180a6be0d77 Операционная система: Windows 7 x64.
using TFlex.Model;
using TFlex.Model.Model2D;
namespace Test
{
public class Class3
{
public static void Run()
{
Document doc = TFlex.Application.ActiveDocument;
doc.BeginChanges("Привязка текста к узлу");
double x = 0.0;
double y = 0.0;
foreach (Node node in doc.GetNodes())
{
x = node.AbsX;
y = node.AbsY;
foreach (MultilineText mtext in doc.GetTexts())
{
if (doc.Selection.IsSelected(mtext))
{
mtext.X = x;
mtext.Y = y;
break;
}
}
}
doc.EndChanges();
}
}
}