Продолжаем цикл статей по работе с API САПР КОМПАС-3D. Управляющие символы уже несколько раз встречались нам на предыдущих уроках цикла. Тогда каждый раз говорилось, что выводимые строки не должны их содержать, так как КОМПАС обрабатывает их особым образом. Теперь пришло время познакомиться с ними поближе.

Освоив работу с ними, вы поймете, что создание сложных составных строк – тривиальная задача, в большинстве случаев не требующая написания большого объёма кода.

В уроке мы рассмотрим, как с помощью управляющих символов выводить спецсимволы и символы шрифта, поговорим о том, как с их помощью создавать дроби и отклонения, а также рассмотрим их использование совместно с параграфами.



Содержание цикла уроков «Работа с API КОМПАС-3D»


  1. Основы
  2. Оформление чертежа
  3. Корректное подключение к КОМПАС
  4. Основная надпись
  5. Графические примитивы
  6. Сохранение документа в различные форматы
  7. Знакомство с настройками
  8. Более сложные методы записи в основную надпись
  9. Чтение ячеек основной надписи
  10. Спецсимволы, включающие строку
  11. Простые текстовые надписи
  12. Составные строки
  13. Параграфы
  14. Многострочный текст
  15. Составные строки на основе параграфа
  16. Управляющие символы

Беглый обзор


Управляющими символами являются символы: @, $, &, ;, ~, ^ и #. К сожалению в КОМПАС SDK крайне мало информации о том, как их использовать. Более подробная информация приведена в справке КОМПАС, в разделе «9. Настройки КОМПАС-3D/Хранение настроек системы/Служебные файлы/Файл пользовательских меню/Синтаксис файла».



Все управляющие символы условно можно разделить на две группы: основные и вспомогательные. Вспомогательные символы используются только совместно с основными и, сами по себе не описывают какую-либо компоненту. В таблице ниже приводится краткое описание управляющих символов.



Рассмотрим их более подробно.

Вставка специальных символов


Мы уже рассматривали специальные символы (см. уроки 4 и 10). Тогда для вставки одного спецсимвола использовался отдельный экземпляр интерфейса ksTextItemParam. С помощью управляющих символов вы можете вставлять в строку столько спецсимволов, сколько сочтете нужным без многократного использования интерфейса ksTextItemParam.
Синтаксис вставки специальных символов имеет вид:

АА@YXXXX~BB

где
АА – строка, располагаемая до специального символа,
Y – модификатор представления кода спецсимвола,
XXXX – код вставляемого спецсимвола.
BB – строка, располагаемая после спецсимвола.

Код вставляемого спецсимвола указывается между @ и ~. При этом в зависимости от значения модификатора Y, он может задаваться в десятичной или шестнадцатеричной системе счисления. Допустимые значения модификатора Y приведены в таблице ниже.



Примечание: как показывают мои эксперименты, КОМПАС нормально обрабатывает отсутствие символа ~. При этом спецсимволы вставляются как нужно. Однако я крайне не рекомендую полагаться на такое поведение и всегда завершать операцию вставки символом ~.

Ниже приводится пример программы, демонстрирующей вывод спецсимволов.

BSTR str = SysAllocString(OLESTR("До @+51~ После"));
document2D->ksText(100.0,100.0,0.0,0.0,0.0,0,str);
SysFreeString(str);

str = SysAllocString(OLESTR("До @*33~ После"));
document2D->ksText(100.0,90.0,0.0,0.0,0.0,0,str);
SysFreeString(str);

В данном примере дважды выводится один и тот же символ (? альфа). В первый раз его код задается в десятичной системе счисления, во второй раз – в шестнадцатеричной. На рисунке ниже показан результат работы программы.



Управляющие символы позволяют выводить в одной строке несколько спецсимволов. Так, в следующем примере демонстрируется вывод первых трех букв греческого алфавита за один вызов метода ksText.

BSTR str = SysAllocString(OLESTR("@+51~ @+52~ @+53~"));
document2D->ksText(100.0,100.0,0.0,0.0,0.0,0,str);
SysFreeString(str);

На рисунке ниже показан результат работы этой программы.



Модификатор + является модификатором по умолчанию. Поэтому приведенную выше строку можно записать так:

“@51~ @52~ @53~”

При этом результат работы программы останется прежним.

Если после @ стоит недопустимый символ, то строка между @ и ~ выводится как есть. При этом символы @ и ~ опускаются. Например, при строке:

“До @Т51~ После”

В документ будет выведено:

До Т51 После

Примечание: такое поведение КОМПАС является недокументированным и может различаться в разных версиях программы.

Примечание: управляющие символы не подходят для вставки спецсимволов, содержащих строку. Дело в том, что для ограничения их действия нужно использовать флаг SPECIAL_SYMBOL_END (более подробно см. 10 урок цикла), но управляющие символы не позволяют использовать флаги.

Вставка символов шрифта


Помимо спецсимволов вы можете вставлять обычные символы по их коду. Для этого используются управляющие символы ^ и ~. Их синтаксис приведен ниже

AA^(FNAME)YXXXX~BB

где
AA – строка располагаемая до вставляемого символа,
FNAME – наименование шрифта, из которого берется символ,
Y – модификатор представления кода символа (аналогично @),
XXXX – числовой код вставляемого символа,
BB – строка располагаемая после вставляемого символа.

По своему назначению управляющий символ ^ похож на @. У них даже схожий синтаксис. Но между ними есть два важных отличия:

  1. ^ вставляет не специальный символ, а символ шрифта по его коду;
  2. для вставляемого символа можно задать шрифт в поле FNAME (@ этого не позволяет).

Коды символов можно посмотреть с помощью приложения charmap (Таблица символов), входящего в состав операционной системы Windows.

Если шрифт не указан, то используется шрифт по умолчанию. Ниже приводится пример использования символа ^.

BSTR str = SysAllocString(OLESTR("До ^(Arial)*B1~ Между ^*39~ После"));
document2D->ksText(100.0,100.0,0.0,0.0,0.0,0,str);
SysFreeString(str);

В данном примере в результирующую строку вставляются два символа, для первого мы выбираем шрифт Arial, для второго оставляем шрифт по умолчанию. На рисунке ниже показана строка, которая выводится в документ.



Обратите внимание: шрифт задается только для выводимого символа. Как показывают мои эксперименты, КОМПАС нормально обрабатывает отсутствие завершителя ~. Однако я не рекомендую полагаться на такое поведение и всегда ставить завершитель.

Если после ^ указан недопустимый символ (или недопустимый код), то ^ и ~ опускаются, а строка между ними выводится как есть с использованием шрифта по умолчанию. Например, при строке

“До ^Q(Arial)*B1~ После”

В документ будет выведено:

“До Q(Arial)*B1 После”

Если в поле FNAME будет указано некорректное имя шрифта, то КОМПАС сам подберет шрифт и выведет символ в нём.

Если в строке нет закрывающей круглой скобки, то такая строка будет выведена не полностью. Например, при строке:

“До ^Q(Arial*B1~ После”

В документ будет выведено только

“До ”

Примечание: приводимое выше поведение при некорректном синтаксисе управляющих символов справедливо для КОМПАС-3D V17 и не документировано. В других версиях оно может отличаться.

Дополнительные способы вставки символов


У символов @ и ^ есть аналоги – & и # соответственно. Они имеют схожий синтаксис:

AA&XX~BB
AA#(FNAME)XX~BB


где

AA – строка, выводимая до вставляемого символа,
XX – код вставляемого символа (для & – спецсимвола, для # – символа шрифта),
BB – строка, выводимая после вставляемого символа,
FNAME – наименование шрифта.

Различий между символами @ и ^, и их аналогами всего два:

  1. В символах & и # нет модификатора Y. Код символа всегда задается в десятичной системе счисления.
  2. Код вставляемого символа задается максимум двумя цифрами.

Ниже приводится исходный код программы, демонстрирующей работу с символами & и #.

BSTR str = SysAllocString(OLESTR("До &51~ После"));
document2D->ksText(100.0,100.0,0.0,0.0,0.0,0,str);
SysFreeString(str);

str = SysAllocString(OLESTR("До #(Arial)37~ Между #37~ После"));
document2D->ksText(100.0,90.0,0.0,0.0,0.0,0,str);
SysFreeString(str);

На рисунке ниже показан результат работы этой программы.



Многострочный текст


С помощью управляющих символов можно выводить многострочный текст. Для этого в месте переноса на новую строку нужно вставить последовательность: @/. Обратите внимание: символ @ используется без завершителя ~. Ниже приводится исходный код программы, демонстрирующей вывод многострочного текста с помощью управляющих символов.

BSTR str = SysAllocString(OLESTR("Первая строка@/Вторая строка"));
document2D->ksText(100.0,100.0,0.0,0.0,0.0,0,str);
SysFreeString(str);

Обратите внимание: благодаря использованию управляющих символов мы выводим двустрочный текст всего одним вызовом метода ksText. На рисунке ниже показан результат работы этой программы.



Вставка управляющих символов


Мы разобрались, как вставлять произвольные спецсимволы и символы Unicode. Но что если требуется вставить сам управляющий символ? Тут можно пойти двумя путями. Первый способ это использовать символ ^ и вставить их как обычные символы шрифта. Но есть и более простой способ.

Символ ; является вспомогательным и может быть вставлен непосредственно в текст. Для вставки других управляющих символов их нужно задвоить. То есть пара символов @@ вставляет в текст один символ @. Это же справедливо и для других управляющих символов.

Ниже приводится пример программы, демонстрирующей вставку управляющих символов в строку.

BSTR str = SysAllocString(OLESTR("Управляющие символы: @@ $$ && ; ~~ ^^ ##"));
document2D->ksText(100.0,100.0,0.0,0.0,0.0,0,str);
SysFreeString(str);

На рисунке ниже показан результат работы этой программы.



Верхнее и нижнее отклонения


Для вставки отклонений используется следующий синтаксис:

AA$XX;YY$BB

где

AA – текст выводимый до отклонений;
XX – верхнее отклонение;
YY – нижнее отклонение;
BB – текст выводимый после отклонений.

Обратите внимание: вся конструкция ограничивается символами $, а символ «;» служит разделителем между верхним и нижним отклонениями.

Если между символами $ нет разделителя «;», то вся строка между ними интерпретируется как верхнее отклонение. Если компонента XX отсутствует, то есть после первого $ сразу идет «;», то вся последующая строка до ближайшего $ интерпретируется как нижнее отклонение.

Примечание: текст верхнего отклонения не должен начинаться с букв b, d, s, m и l (строчная L). Причина этого будет объяснена чуть позже.

Ниже приводится пример программы, демонстрирующей вывод текста с отклонениями

BSTR str = SysAllocString(OLESTR("До $Верхнее;Нижнее$ После"));
document2D->ksText(100.0,100.0,0.0,0.0,0.0,0,str);
SysFreeString(str);

На рисунке ниже показан результат работы этой программы:



Учтите, КОМПАС обрабатывает только один символ «;». Второй символ «;» может интерпретироваться как завершитель всей конструкции. Например, при строке «11$22;33;44$» на экран будет выведено:



Примечание: такое поведение КОМПАС не документировано, поэтому полагаться на него нельзя.

Дробь


Синтаксис дроби похож на синтаксис отклонений и имеет два равнозначных варианта:

AA$bXX;YY$BB
AA$dXX;YY$BB


где

AA – текст выводимый до дроби;
XX – числитель;
YY – знаменатель;
BB – текст выводимый после дроби.

Обратите внимание: единственное, чем отличается вывод дроби от вывода отклонений это наличие буквы d или b сразу после первого знака $. Во всем остальном их синтаксисы идентичны.

Если между символами $d ($b) и $ нет символа «;», то вся строка между ними будет интерпретироваться как числитель. Если компонента XX отсутствует, то есть после $d ($b) сразу идет «;», то вся последующая строка до ближайшего $ интерпретируется как знаменатель.

Примечание: текст числителя не должен начинаться с букв s, m или l (строчная L). Причина этого будет объяснена чуть позже.

Ниже приводится пример программы, демонстрирующей вывод дроби с использованием управляющих символов.

BSTR str = SysAllocString(OLESTR("До $dЧислитель;Знаменатель$ После"));
document2D->ksText(100.0,100.0,0.0,0.0,0.0,0,str);
SysFreeString(str);

На рисунке ниже показан результат работы этой программы.



Учтите, КОМПАС обрабатывает «лишние» символы «;» также как и в случае отклонений. Такое поведение является недокументированным, и полагаться на него нельзя.

Управление размером отклонений и дроби


В самом начале конструкции построения отклонений или дроби может находиться одна из букв: s, m или l (строчная L). Они задают размер отклонений и элементов дроби (числителя и знаменателя). Их назначение описывается в таблице ниже.



Если ни одна из этих букв не указана, то для дроби используется l, а для отклонений m. Ниже приводится пример программы, демонстрирующей использование этих букв.

BSTR str = SysAllocString(OLESTR("До $dЧислитель;Знаменатель$ После"));
document2D->ksText(100.0,100.0,0.0,0.0,0.0,0,str);
SysFreeString(str);

str = SysAllocString(OLESTR("До $dlЧислитель;Знаменатель$ После"));
document2D->ksText(100.0,85.0,0.0,0.0,0.0,0,str);
SysFreeString(str);

str = SysAllocString(OLESTR("До $dmЧислитель;Знаменатель$ После"));
document2D->ksText(100.0,70.0,0.0,0.0,0.0,0,str);
SysFreeString(str);

str = SysAllocString(OLESTR("До $dsЧислитель;Знаменатель$ После"));
document2D->ksText(100.0,60.0,0.0,0.0,0.0,0,str);
SysFreeString(str);

На рисунке ниже показан результат работы этой программы.



Хотя в данном примере буквы s, m и l используются для дроби, их применение для отклонений ничем не отличается.

Учтите, что если между началом дроби или отклонения ($, $d или $b) и буквой s, m или l находится хотя бы один «посторонний» символ (например, пробел), то КОМПАС «не увидит» букв, и дробь или отклонение будут иметь размер по умолчанию.

Вложенные управляющие символы


При выводе дробей и отклонений, входящие в их состав строки обрабатываются рекурсивно. Это значит, что при формировании числителя и знаменателя так же могут использоваться управляющие символы. Этот подход демонстрируется в следующем примере.

BSTR str = SysAllocString(OLESTR("@54~$s2$ + $d@+51~;@+52~$ - ^(Symbol)*70~"));
document2D->ksText(100.0,100.0,0.0,0.0,0.0,0,str);
SysFreeString(str);

На рисунке ниже показан результат работы этой программы.



Для вставки букв греческого алфавита мы используем управляющие символы @ и ^ (для буквы ? пи). Степень в первом слагаемом выводится с помощью отклонений. Ее выводит подстрока $s2$. Буква s указывает на малый размер отклонения, а благодаря отсутствию разделителя «;» выводится только верхнее отклонение.

Для формирования дроби используется комбинация $d;$. Причем в состав числителя и знаменателя входят управляющие символы, которые обеспечивают вывод букв греческого алфавита.

Последнее вычитаемое (? пи) выводится как символ шрифта Symbol с помощью управляющих символов ^ и ~.

К сожалению возможности такой «рекурсии» сильно ограничены. Мы не можем дробь и отклонения вкладывать друг в друга. Проблема в том, что они оба формируются с помощью управляющего символа $. Из-за этого КОМПАС не может правильно разобрать, какой $ к какому элементу относится.

Управляющие символы в параграфе


Частично обойти ограничение с вложенными управляющими символами можно с помощью параграфов. Совместное использование управляющих символов и параграфов позволяет строить еще более сложные конструкции. Пример ниже демонстрирует построение 4-уровневой дроби.

Код программы для построения 4-уровневой дроби
//Получаем нужные интерфейсы
DynamicArrayPtr dynamicArray;
dynamicArray = static_cast<DynamicArrayPtr>(kompas->GetDynamicArray(TEXT_ITEM_ARR));
dynamicArray->ksClearArray();

TextItemParamPtr textItemParam;
textItemParam = static_cast<TextItemParamPtr>(kompas->GetParamStruct(ko_TextItemParam));

//Добавляем в массив обычный текст
BSTR str = SysAllocString(OLESTR("Текст до дроби"));

textItemParam->set_s(str);
dynamicArray->ksAddArrayItem(-1, textItemParam);
SysFreeString(str);

//Добавляем в массив числитель дроби
TextItemFontPtr textItemFont;
textItemFont = static_cast<TextItemFontPtr>(textItemParam->GetItemFont());
textItemFont->set_bitVector(NUMERATOR);

str = SysAllocString(OLESTR("1 + $d@+51~;2$"));
textItemParam->set_s(str);
dynamicArray->ksAddArrayItem(-1, textItemParam);
SysFreeString(str);

//Добавляем в массив знаменатель
textItemFont->set_bitVector(DENOMINATOR);
str = SysAllocString(OLESTR("1 + $d@+56~;2$"));
textItemParam->set_s(str);
dynamicArray->ksAddArrayItem(-1, textItemParam);
SysFreeString(str);

//Завершаем дробь
textItemFont->set_bitVector(END_FRACTION);
str = SysAllocString(OLESTR("Текст после дроби"));
textItemParam->set_s(str);
dynamicArray->ksAddArrayItem(-1, textItemParam);
SysFreeString(str);

//Освобождаем ненужные интерфейсы
textItemFont.Unbind();
textItemParam.Unbind();

//Оформляем массив в интерфейс ksTextLineParam
TextLineParamPtr textLineParam;
textLineParam = static_cast<TextLineParamPtr>(kompas->GetParamStruct(ko_TextLineParam));
textLineParam->Init();
textLineParam->SetTextItemArr(dynamicArray);
dynamicArray.Unbind();

//Строим параграф
ParagraphParamPtr paragraphParam;
paragraphParam=static_cast<ParagraphParamPtr>(kompas->GetParamStruct(ko_ParagraphParam));
paragraphParam->Init();
paragraphParam->set_x(100.0);
paragraphParam->set_y(100.0);

document2D->ksParagraph(paragraphParam);
document2D->ksTextLine(textLineParam);
document2D->ksEndObj();

//Освобождаем оставшиеся интерфейсы
textLineParam.Unbind();
paragraphParam.Unbind();


В данном примере управляющие символы используются для построения дробей в числителе и знаменателе основной дроби, а также для вставки букв греческого алфавита. На рисунке ниже показан результат работы этой программы.



Заключение


На данном уроке мы познакомились с управляющими символами и научились с помощью них выводить спецсимволы и символы шрифта. Как вы могли убедиться, они предоставляют простой синтаксис создания строк, включающих в свой состав спецсимволы, дроби, отклонения. К сожалению, они плохо подходят для вставки спецсимволов, содержащих строки. Но такие спецсимволы встречаются крайне редко. Это одно из ограничений управляющих символов. Также с их помощью нельзя создавать надстроки и подстроки, и есть ограничения при работе со спецсимволами, включающими строки. Но это ничуть не умаляет их достоинств. На этом мы заканчиваем рассмотрение управляющих символов.

Продолжение следует, следите за новостями блога.

Сергей Норсеев, к.т.н., автор книги «Разработка приложений под КОМПАС в Delphi».

Комментарии (6)


  1. amarao
    27.06.2019 11:43

    А почему шрифты такие уродливые?


    1. staticmain
      27.06.2019 11:52

      Это разве не GOSTA/B?


      1. amarao
        27.06.2019 12:06

        Это ответ на вопрос "что это за шрифт?", а не ответ на вопрос "почему шрифты такие уродливые?".


    1. kompas_3d Автор
      27.06.2019 12:06

      Гостовский шрифт такой.


      1. amarao
        27.06.2019 12:41

        Переформулирую вопрос: почему гостовский шрифт такой уродливый?


        1. kompas_3d Автор
          27.06.2019 12:47

          Скорее всего из-за того, что он изначально рукописный. Его форма регулируется ГОСТ 2.304-81, на картинках он ещё и увеличен для лучшей видимости, что красоты не добавляет.