Мы уже знакомились со спецсимволами в 4 уроке нашего цикла. Там было показано их простейшее использование. Там же говорилось, что если интерфейс ksTextItemParam задает и спецсимвол, и строку, то строка располагается сразу за спецсимволом. Однако существуют спецсимволы, которые нарушают это правило. О них мы сегодня и поговорим.
Содержание цикла уроков «Работа с API КОМПАС-3D»
- Основы
- Оформление чертежа
- Корректное подключение к КОМПАС
- Основная надпись
- Графические примитивы
- Сохранение документа в различные форматы
- Знакомство с настройками
- Более сложные методы записи в основную надпись
- Чтение ячеек основной надписи
- Спецсимволы, включающие строку
Спецсимволы, включающие строку
Таблица спецзнаков находится в приложении V основной справки КОМПАСа
Спецсимволы с номерами 78-80, 83, 93-99, 171 и 172 включают в свой состав строку. В этом случае строка s интерфейса ksTextItemParam располагается не после спецсимвола, а внутри него. Например, спецсимвол с номером 80 выводит текст в рамке. Ниже приводится пример программы, которая демонстрирует работу с таким спецсимволом.
//Получаем интерфейс представления строки
TextItemParamPtr TextItemParam;
TextItemParam=(TextItemParamPtr)kompas->GetParamStruct(ko_TextItemParam);
//Заполняем его
TextItemParam->set_type(SPECIAL_SYMBOL);
TextItemParam->set_iSNumb(98);
BSTR str = SysAllocString(L"Строка");
TextItemParam->set_s(str);
SysFreeString(str);
//Получаем интерфейс основной надписи
StampPtr Stamp;
Stamp=(StampPtr)Document2D->GetStamp();
//Открываем режим редактирования основной надписи
Stamp->ksOpenStamp();
Stamp->ksColumnNumber(1);
Stamp->ksTextLine(TextItemParam);
//Закрываем режим редактирования основной надписи
Stamp->ksCloseStamp();
Stamp.Unbind();
TextItemParam.Unbind();
Document2D.Unbind();
//Делаем КОМПАС видимым
kompas->Visible = true;
kompas.Unbind();
Для простоты в данном примере опущен код, ответственный за создание и оформление документа (эта тема рассматривалась в предыдущих уроках цикла). На рисунке ниже показана основная надпись, сформированная этой программой.
Для простоты мы заполняем только одну ячейку. Спецсимвол с номером 98 определяет знак квадратного корня. Обратите внимание — значение свойства s интерфейса ksTextItemParam полностью оказывается под знаком корня. Точно так же работают и другие спецсимволы, включающие строку.
Спецсимволы и ksTextLineParam
Действие спецсимволов не ограничивается интерфейсом ksTextItemParam. Рассмотрим пример ниже.
//Получаем интерфейс представления компоненты строки
TextItemParamPtr TextItemParam;
TextItemParam=(TextItemParamPtr)kompas->GetParamStruct(ko_TextItemParam);
//Получаем интерфейс динамического массива компонент
DynamicArrayPtr DynamicArray;
DynamicArray=(DynamicArrayPtr)kompas->GetDynamicArray(TEXT_ITEM_ARR);
//Формируем первую компоненту
TextItemParam->set_type(SPECIAL_SYMBOL);
TextItemParam->set_iSNumb(98);
BSTR str = SysAllocString(L"Стр1 ");
TextItemParam->set_s(str);
SysFreeString(str);
DynamicArray->ksAddArrayItem(-1, TextItemParam);
//Формируем вторую компоненту
TextItemParam->Init();
TextItemParam->set_type(SPECIAL_SYMBOL);
TextItemParam->set_iSNumb(169);
str = SysAllocString(L"Стр2 ");
TextItemParam->set_s(str);
SysFreeString(str);
DynamicArray->ksAddArrayItem(-1, TextItemParam);
//Формируем третью компоненту
TextItemParam->Init();
TextItemParam->set_type(0);
str = SysAllocString(L"Стр 3");
TextItemParam->set_s(str);
SysFreeString(str);
DynamicArray->ksAddArrayItem(-1, TextItemParam);
//Оформляем строку в ksTextLineParam
TextLineParamPtr TextLineParam;
TextLineParam=(TextLineParamPtr)kompas->GetParamStruct(ko_TextLineParam);
TextLineParam->SetTextItemArr(DynamicArray);
//Получаем интерфейс основной надписи
StampPtr Stamp;
Stamp=(StampPtr)Document2D->GetStamp();
//Открываем режим редактирования основной надписи
Stamp->ksOpenStamp();
Stamp->ksColumnNumber(1);
Stamp->ksTextLine(TextLineParam);
//Закрываем режим редактирования основной надписи
Stamp->ksCloseStamp();
Stamp.Unbind();
TextItemParam.Unbind();
TextLineParam.Unbind();
DynamicArray->ksDeleteArray();
DynamicArray.Unbind();
Document2D.Unbind();
//Делаем КОМПАС видимым
kompas->Visible = true;
kompas.Unbind();
В этом примере в основную надпись заносится строка, состоящая из трех компонент. Первые две содержат спецсимвол и строку. Третья компонента содержит только строку, без спецсимвола. Посмотрим на результат работы программы (на рисунке ниже приводится только сформированная строка без основной надписи).
Обратите внимание — в состав второго спецсимвола вошла как строка «Стр 2», так и строка «Стр 3», которую мы планировали вывести вне спецсимвола. Более того, обе этих строки вошли в состав первого спецсимвола (этого мы тоже не планировали). Данный пример демонстрирует два важных момента:
- спецсимволы могут включать в свой состав другие спецсимволы;
- действие спецсимвола распространяется на все компоненты, входящие в состав интерфейса ksTextLineParam.
Резонно возникает вопрос — существует ли способ ограничить действие спецсимвола? Да, существует. Но для того, чтобы его понять, нужно сначала познакомиться с интерфейсом ksTextItemFont.
Параметры шрифта компоненты текста (ksTextItemFont)
Согласно документации интерфейс ksTextItemFont описывает параметры шрифта компоненты текста. Но на самом деле его возможности превышают простое описание используемого шрифта. Данный интерфейс позволяет формировать составные строки (о них — в следующих уроках цикла).
Получить его можно несколькими способами. Во-первых, с помощью метода GetParamStruct интерфейса KompasObject: для этого в качестве единственного параметра данному методу нужно передать константу ko_TextItemFont. Во-вторых, с помощью метода GetItemFont интерфейса ksTextItemParam. Этот метод не имеет входных параметров и возвращает интерфейс ksTextItemFont уже ассоциированным с компонентой текста.
Рассмотрим свойства интерфейса ksTextItemFont.
bitvector — битовый вектор, задающий признаки начертания текста (они будут подробно рассматриваться в следующих уроках цикла).
сolor — цвет символов в формате RGB.
fontName — строка с именем шрифта.
height — высота шрифта в миллиметрах.
ksu — коэффициент растяжения текста.
Методов у интерфейса ksTextItemFont всего три.
Init() сбрасывает значения всех свойств интерфейса. Не имеет входных параметров. В случае успеха возвращает значение TRUE, а в случае ошибки — FALSE.
GetBitVectorValue возвращает значение отдельного флага из набора bitvector. В качестве единственного параметра принимает флаг, значение которого мы хотим определить. Если он установлен, метод возвращает значение TRUE, если сброшен — FALSE.
SetBitVectorValue изменяет значение отдельного флага. Ниже приводится прототип данного метода:
BOOL SetBitVectorValue (
long bitVector, //Изменяемый флаг
BOOL state //Новое значение флага
);
Если значение параметра state равно TRUE, то флаг bitVector взводится, в противном случае — сбрасывается.
В случае успеха метод SetBitVectorValue возвращает значение TRUE, а в случае ошибки — FALSE.
Методы GetBitVectorValue и SetBitVectorValue позволяют работать со свойством bitvector, не обращаясь к нему напрямую.
Ограничение действия спецсимвола
Для управления спецсимволами предназначено два флага. Они приведены в таблице ниже.
Флаг SPECIAL_SYMBOL мы уже рассматривали, когда описывали интерфейс ksTextItemParam. Он нужен для того, чтобы указать — выводится спецсимвол. Этот же флаг дублируется в свойстве bitVector интерфейса ksTextItemFont (как показывают мои эксперименты, это дублирование необязательно).
Второй флаг (SPECIAL_SYMBOL_END) имеет смысл только для спецсимволов, включающих строку. Он отменяет действие спецсимвола. Строки, выводимые после этого флага, не входят в состав спецсимвола.
Совместное действие обоих флагов отменяет действие спецсимвола. В этом случае спецсимвол не будет выведен в документ.
Пример
Ниже приводится исходный код доработанной программы. В нём с помощью флагов, описанных выше, реализуется правильный вывод компонент.
//Получаем интерфейс представления компоненты строки
TextItemParamPtr TextItemParam;
TextItemParam=(TextItemParamPtr)kompas->GetParamStruct(ko_TextItemParam);
//Получаем интерфейс динамического массива компонент
DynamicArrayPtr DynamicArray;
DynamicArray=(DynamicArrayPtr)kompas->GetDynamicArray(TEXT_ITEM_ARR);
//Формируем первую компоненту
TextItemParam->set_type(SPECIAL_SYMBOL);
TextItemParam->set_iSNumb(98);
BSTR str = SysAllocString(L"Стр1 ");
TextItemParam->set_s(str);
SysFreeString(str);
DynamicArray->ksAddArrayItem(-1, TextItemParam);
//Отменяем действие спецсимвола
TextItemFontPtr TextItemFont;
TextItemParam->Init();
TextItemFont=(TextItemFontPtr)TextItemParam->GetItemFont();
TextItemFont->set_bitVector(SPECIAL_SYMBOL_END);
DynamicArray->ksAddArrayItem(-1, TextItemParam);
TextItemFont->Init();
TextItemFont.Unbind();
//Формируем вторую компоненту
TextItemParam->Init();
TextItemParam->set_type(SPECIAL_SYMBOL);
TextItemParam->set_iSNumb(169);
str = SysAllocString(L"Стр2 ");
TextItemParam->set_s(str);
SysFreeString(str);
DynamicArray->ksAddArrayItem(-1, TextItemParam);
//Отменяем спецсимвол и формируем третью компоненту
TextItemParam->Init();
TextItemFont=(TextItemFontPtr)TextItemParam->GetItemFont();
TextItemFont->set_bitVector(SPECIAL_SYMBOL_END);
TextItemParam->set_type(0);
str = SysAllocString(L" Стр 3");
TextItemParam->set_s(str);
SysFreeString(str);
DynamicArray->ksAddArrayItem(-1, TextItemParam);
TextItemFont.Unbind();
//Оформляем строку в ksTextLineParam
TextLineParamPtr TextLineParam;
TextLineParam=(TextLineParamPtr)kompas->GetParamStruct(ko_TextLineParam);
TextLineParam->SetTextItemArr(DynamicArray);
//Получаем интерфейс основной надписи
StampPtr Stamp;
Stamp=(StampPtr)Document2D->GetStamp();
//Открываем рпежим редактирования основной надписи
Stamp->ksOpenStamp();
Stamp->ksColumnNumber(1);
Stamp->ksTextLine(TextLineParam);
//Закрываем режим редактирования основной надписи
Stamp->ksCloseStamp();
Stamp.Unbind();
TextItemParam.Unbind();
TextLineParam.Unbind();
DynamicArray->ksDeleteArray();
DynamicArray.Unbind();
Document2D.Unbind();
//Делаем КОМПАС видимым
kompas->Visible = true;
kompas.Unbind();
Единственное отличие этого примера от предыдущего — после каждого спецсимвола выводится компонента, для которой в интерфейсе ksTextItemFont установлен флаг SPECIAL_SYMBOL_END. Единственное ее назначение — отмена действия спецсимвола. В первом случае она не содержит никаких данных (кроме флага, разумеется). А во втором случае содержит строку «Стр 3».
Объединять флаг SPECIAL_SYMBOL_END с выводом второго спецсимвола нельзя. Так как в этом случае данный флаг отменит действие обоих спецсимволов. Строка «Стр2» будет выведена без зачеркивания.
На рисунке ниже показана строка, выведенная данной программой в основную надпись.
Как видите, теперь действие спецсимволов распространяется только на «свою» компоненту.
Вложенные спецсимволы
Первый пример нашего сегодняшнего урока наглядно показывает — спецсимволы могут вкладываться друг в друга. Флаг SPECIAL_SYMBOL_END отменяет действие одного (последнего) спецсимвола. Это позволяет строить сложные строки с вложенными спецсимволами.
Ниже приводится исходный код доработанного примера, в котором подстрока «Стр 2» тоже входит в состав выражения под знаком квадратного корня.
//Получаем интерфейс представления компоненты строки
TextItemParamPtr TextItemParam;
TextItemParam=(TextItemParamPtr)kompas->GetParamStruct(ko_TextItemParam);
//Получаем интерфейс динамического массива компонент
DynamicArrayPtr DynamicArray;
DynamicArray=(DynamicArrayPtr)kompas->GetDynamicArray(TEXT_ITEM_ARR);
//Формируем первую компоненту
TextItemParam->set_type(SPECIAL_SYMBOL);
TextItemParam->set_iSNumb(98);
BSTR str = SysAllocString(L"Стр1 ");
TextItemParam->set_s(str);
SysFreeString(str);
DynamicArray->ksAddArrayItem(-1, TextItemParam);
//Формируем вторую компоненту
TextItemParam->Init();
TextItemParam->set_type(SPECIAL_SYMBOL);
TextItemParam->set_iSNumb(169);
str = SysAllocString(L"Стр2 ");
TextItemParam->set_s(str);
SysFreeString(str);
DynamicArray->ksAddArrayItem(-1, TextItemParam);
//Отменяем действие спецсимвола
TextItemFontPtr TextItemFont;
TextItemParam->Init();
TextItemFont=(TextItemFontPtr)TextItemParam->GetItemFont();
TextItemFont->set_bitVector(SPECIAL_SYMBOL_END);
DynamicArray->ksAddArrayItem(-1, TextItemParam);
//Отменяем спецсимвол и формируем третью компоненту
TextItemParam->set_type(0);
str = SysAllocString(L" Стр 3");
TextItemParam->set_s(str);
SysFreeString(str);
DynamicArray->ksAddArrayItem(-1, TextItemParam);
TextItemFont.Unbind();
//Оформляем строку в ksTextLineParam
TextLineParamPtr TextLineParam;
TextLineParam=(TextLineParamPtr)kompas->GetParamStruct(ko_TextLineParam);
TextLineParam->SetTextItemArr(DynamicArray);
//Получаем интерфейс основной надписи
StampPtr Stamp;
Stamp=(StampPtr)Document2D->GetStamp();
//Открываем рпежим редактирования основной надписи
Stamp->ksOpenStamp();
Stamp->ksColumnNumber(1);
Stamp->ksTextLine(TextLineParam);
//Закрываем режим редактирования основной надписи
Stamp->ksCloseStamp();
Stamp.Unbind();
TextItemParam.Unbind();
TextLineParam.Unbind();
DynamicArray->ksDeleteArray();
DynamicArray.Unbind();
Document2D.Unbind();
//Делаем КОМПАС видимым
kompas->Visible = true;
kompas.Unbind();
Обратите внимание — после вывода подстроки «Стр 2» мы дважды выводим компоненту с флагом SPECIAL_SYMBOL_END (первый раз — в составе пустой компоненты, второй — вместе со строкой «Стр 3»). Это нужно для отмены действия спецсимволов. Первый раз мы отменяем спецсимвол 169 (зачеркивание), второй раз — 98 (квадратный корень). Если бы мы вывели только одну компоненту с флагом SPECIAL_SYMBOL_END, это отменило бы только спецсимвол 169, но не 98. В этом случае строка «Стр 3» не была бы зачеркнута, но входила бы в состав выражения под знаком корня.
На рисунке ниже показан результат работы данной программы.
Заключение
В рамках этого урока мы познакомились со спецсимволами, включающими строку. Как вы увидели, они значительно отличаются от простых спецсимволов (например, букв греческого алфавита). Хотя мы показывали их на примере основной надписи, это не должно вас смущать. Данные символы могут быть использованы и в других методах вывода текста. Один из таких методов мы рассмотрим на следующем уроке.
Продолжение следует, следите за новостями блога.
Сергей Норсеев, к.т.н., автор книги «Разработка приложений под КОМПАС в Delphi».
Автор: kompas_3d