In 
Lektion 12 haben wir die zusammengesetzten Linien vorgestellt und einen undokumentierten Weg untersucht, um sie zu erstellen. In 
Lektion 13 wurden Absätze vorgestellt. Heute werden wir uns ansehen, wie man sie verwendet, um zusammengesetzte Zeichenfolgen zu erstellen. Nehmen wir zunächst Zeilen, die Abweichungen und Brüche enthalten, und machen Sie sich mit Komponenten zusammengesetzter Zeilen wie hochgestellten Zeichenfolgen, Teilzeichenfolgen und Sonderzeichen vertraut.

Der Inhalt der Unterrichtsreihe „Arbeiten mit der KOMPAS-3D-API“
- Die Grundlagen
- Zeichnungsentwurf
- Richtige Verbindung zu KOMPAS
- Hauptinschrift
- Grafische Grundelemente
- Speichern eines Dokuments in verschiedenen Formaten
- Einstellungen kennenlernen
- Anspruchsvollere Schreibmethoden im Schriftfeld
- Beschriftungszellen lesen
- Sonderzeichen einschließlich einer Zeichenfolge
- Einfache Textbeschriftungen
- Zusammengesetzte Zeichenfolgen
- Absätze
- Mehrzeiliger Text
- Absatzbasierte zusammengesetzte Linien
Obere und untere Abweichungen
Das Folgende ist ein Fragment eines Programms, das die Ausgabe einer Zeile mit oberen und unteren Abweichungen anhand von Absätzen demonstriert. Zu diesem 
Zweck werden die in 
Lektion 12 erwähnten Flags 
END_DEVIAT , 
LOWER_DEVIAT und 
UPPER_DEVIAT verwendet .
Programmcode-Snippet//     DynamicArrayPtr items; items = static_cast<DynamicArrayPtr>(kompas->GetDynamicArray(TEXT_ITEM_ARR)); items->ksClearArray(); TextItemParamPtr itemParam; itemParam = static_cast<TextItemParamPtr>(kompas->GetParamStruct(ko_TextItemParam)); itemParam->Init(); TextItemFontPtr itemFont; itemFont = static_cast<TextItemFontPtr>(itemParam->GetItemFont()); //   BSTR str = SysAllocString(OLESTR("  ")); itemParam->set_s(str); items->ksAddArrayItem(-1, itemParam); SysFreeString(str); itemFont->set_bitVector(UPPER_DEVIAT); str = SysAllocString(OLESTR(" ")); itemParam->set_s(str); items->ksAddArrayItem(-1, itemParam); SysFreeString(str); itemFont->set_bitVector(LOWER_DEVIAT); str = SysAllocString(OLESTR(" ")); itemParam->set_s(str); items->ksAddArrayItem(-1, itemParam); SysFreeString(str); itemFont->set_bitVector(END_DEVIAT); str = SysAllocString(OLESTR("  ")); itemParam->set_s(str); items->ksAddArrayItem(-1, itemParam); SysFreeString(str); // ,     itemFont.Unbind(); itemParam.Unbind(); //  ksTextLineParam TextLineParamPtr lineParam; lineParam = static_cast<TextLineParamPtr>(kompas->GetParamStruct(ko_TextLineParam)); lineParam->Init(); lineParam->SetTextItemArr(items); //  ksParagraphParam ParagraphParamPtr paragraphParam; paragraphParam= static_cast<ParagraphParamPtr>(kompas->GetParamStruct(ko_ParagraphParam)); paragraphParam->Init(); paragraphParam->set_x(30.0); paragraphParam->set_y(100.0); //  Document2D->ksParagraph(paragraphParam); Document2D->ksTextLine(lineParam); Document2D->ksEndObj(); //  items->ksDeleteArray(); items.Unbind(); lineParam.Unbind(); paragraphParam.Unbind(); 
 Gegenüber dem Beispiel der Gebäudeabweichung von 
Lektion 12 hat das aktuelle Programm zwei wichtige Vorteile:
- Es nutzt die dokumentierten Funktionen des COMPASS-Systems.
- Die Position der Zeilen muss nicht neu berechnet werden. KOMPAS selbst ermittelt alle notwendigen Offsets.
Beachten Sie die Verwendung des 
Flags END_DEVIAT . Es vervollständigt die Abweichungserzeugung und 
löscht die Flags LOWER_DEVIAT und 
UPPER_DEVIAT . Wenn wir es nicht verwendet hätten, würde die Zeile „Text nach Abweichungen“ als geringere Abweichung angezeigt.
Die Flags 
LOWER_DEVIAT und 
UPPER_DEVIAT heben sich gegenseitig auf. Bei gleichzeitiger Verwendung wird die Zeichenfolge so ausgegeben, wie sie ohne Angabe dieser Flags angezeigt würde.
Da in unserem Beispiel das Flag 
NEW_LINE nicht verwendet wird, können alle Zeilen mit einem Aufruf der Methode 
ksTextLine angezeigt werden. Dazu werden sie in Form der 
ksTextLineParam- Schnittstelle vorgeformt.
Das Ergebnis des Programms ist in der folgenden Abbildung dargestellt.

Bruchteil
Das folgende Beispiel zeigt ein Programm, das die Ausgabe einer Zeichenfolge demonstriert, die einen Bruch enthält.
Programmbeispiel //     DynamicArrayPtr items; items = static_cast<DynamicArrayPtr>(kompas->GetDynamicArray(TEXT_ITEM_ARR)); items->ksClearArray(); TextItemParamPtr itemParam; itemParam = static_cast<TextItemParamPtr>(kompas->GetParamStruct(ko_TextItemParam)); itemParam->Init(); TextItemFontPtr itemFont; itemFont = static_cast<TextItemFontPtr>(itemParam->GetItemFont()); //   BSTR str = SysAllocString(OLESTR("  ")); itemParam->set_s(str); items->ksAddArrayItem(-1, itemParam); SysFreeString(str); itemFont->set_bitVector(NUMERATOR); str = SysAllocString(OLESTR("")); itemParam->set_s(str); items->ksAddArrayItem(-1, itemParam); SysFreeString(str); itemFont->set_bitVector(DENOMINATOR); str = SysAllocString(OLESTR("")); itemParam->set_s(str); items->ksAddArrayItem(-1, itemParam); SysFreeString(str); itemFont->set_bitVector(END_FRACTION); str = SysAllocString(OLESTR("  ")); itemParam->set_s(str); items->ksAddArrayItem(-1, itemParam); SysFreeString(str); // ,     itemFont.Unbind(); itemParam.Unbind(); //  ksTextLineParam TextLineParamPtr lineParam; lineParam = static_cast<TextLineParamPtr>(kompas->GetParamStruct(ko_TextLineParam)); lineParam->Init(); lineParam->SetTextItemArr(items); //  ksParagraphParam ParagraphParamPtr paragraphParam; paragraphParam= static_cast<ParagraphParamPtr>(kompas->GetParamStruct(ko_ParagraphParam)); paragraphParam->Init(); paragraphParam->set_x(30.0); paragraphParam->set_y(100.0); //  Document2D->ksParagraph(paragraphParam); Document2D->ksTextLine(lineParam); Document2D->ksEndObj(); //  items->ksDeleteArray(); items.Unbind(); lineParam.Unbind(); paragraphParam.Unbind(); 
 Gebäudefraktionen unterscheiden sich nicht wesentlich von Gebäudeabweichungen. Der einzige Unterschied sind die verwendeten Flags. Das Flag 
END_FRACTION löscht die Flags NUMERATOR und 
DENOMINATOR und 
verhält sich für Abweichungen genauso wie das Flag 
END_DEVIAT .
Die folgende Abbildung zeigt das Ergebnis dieses Programms.

Diese Zeile sieht im Vergleich zum gleichen Text in 
Lektion 12 ordentlicher aus.
Kontrolle der Fraktionsgröße
Der angezeigte Bruch kann eine andere Größe haben, die über die Schnittstelle 
ksTextItemParam gesteuert wird. Wenn die 
type- Eigenschaft 
FRACTION_TYPE lautet, legt diese Schnittstelle unter anderem die Größe des Bruchs fest. Die Größe selbst wird in der Eigenschaft 
iSNumb angegeben. Die gültigen Werte sind in der folgenden Tabelle aufgeführt.

Wenn die 
iSNumb- Eigenschaft einen ungültigen Wert angibt, verwendet KOMPAS die Standardhöhe.
Das Folgende ist ein Beispiel für die Verwendung des 
FRACTION_TYPE- Flags.
Beispiel für die Verwendung von Flags //   DynamicArrayPtr items; items = static_cast<DynamicArrayPtr>(kompas->GetDynamicArray(TEXT_ITEM_ARR)); items->ksClearArray(); TextItemParamPtr itemParam; itemParam = static_cast<TextItemParamPtr>(kompas->GetParamStruct(ko_TextItemParam)); itemParam->Init(); TextItemFontPtr itemFont; itemFont = static_cast<TextItemFontPtr>(itemParam->GetItemFont()); //   BSTR str = SysAllocString(OLESTR("  ")); itemParam->set_s(str); items->ksAddArrayItem(-1, itemParam); SysFreeString(str); itemFont->set_bitVector(NUMERATOR); itemParam->set_type(FRACTION_TYPE); itemParam->set_iSNumb(3); str = SysAllocString(OLESTR("")); itemParam->set_s(str); items->ksAddArrayItem(-1, itemParam); SysFreeString(str); itemFont->set_bitVector(DENOMINATOR); str = SysAllocString(OLESTR("")); itemParam->set_s(str); items->ksAddArrayItem(-1, itemParam); SysFreeString(str); itemFont->set_bitVector(END_FRACTION); str = SysAllocString(OLESTR("  ")); itemParam->set_s(str); items->ksAddArrayItem(-1, itemParam); SysFreeString(str); // ,     itemFont.Unbind(); itemParam.Unbind(); //  ksTextLineParam TextLineParamPtr lineParam; lineParam = static_cast<TextLineParamPtr>(kompas->GetParamStruct(ko_TextLineParam)); lineParam->Init(); lineParam->SetTextItemArr(items); //  ksParagraphParam ParagraphParamPtr paragraphParam; paragraphParam= static_cast<ParagraphParamPtr>(kompas->GetParamStruct(ko_ParagraphParam)); paragraphParam->Init(); paragraphParam->set_x(30.0); paragraphParam->set_y(100.0); //  Document2D->ksParagraph(paragraphParam); Document2D->ksTextLine(lineParam); Document2D->ksEndObj(); //  items->ksDeleteArray(); items.Unbind(); lineParam.Unbind(); paragraphParam.Unbind(); 
 Dieses Beispiel unterscheidet sich vom vorherigen nur dadurch, dass der Typ 
FRACTION_TYPE in der 
type- Eigenschaft der 
ksTextItemParam- Schnittstelle bei der Ausgabe des Zählers festgelegt wird. Dies reicht jedoch aus, um die Größe der Fraktion zu ändern. Die folgende Abbildung zeigt das Ergebnis dieses Programms (vergleichen Sie es mit dem Ergebnis des 
vorherigen Beispiels ).

Hinweis: Die Bruchgröße wird festgelegt, wenn der Zähler angezeigt wird. Wie meine Experimente zeigen, wird die bei der Anzeige des Nenners angegebene Bruchgröße ignoriert.
Hochgestellt und Teilzeichenfolge
Der Aufbau eines Teilstrings und eines Teilstrings wird durch die in der folgenden Tabelle aufgeführten Flags gesteuert.

Das folgende Beispielprogramm demonstriert die Ausgabe eines Strings mit einem Teilstring und einem Teilstring.
Programmbeispiel //   DynamicArrayPtr items; items = static_cast<DynamicArrayPtr>(kompas->GetDynamicArray(TEXT_ITEM_ARR)); items->ksClearArray(); TextItemParamPtr itemParam; itemParam = static_cast<TextItemParamPtr>(kompas->GetParamStruct(ko_TextItemParam)); itemParam->Init(); TextItemFontPtr itemFont; itemFont = static_cast<TextItemFontPtr>(itemParam->GetItemFont()); //   BSTR str = SysAllocString(OLESTR("  ")); itemParam->set_s(str); items->ksAddArrayItem(-1, itemParam); SysFreeString(str); itemFont->set_bitVector(S_BASE); str = SysAllocString(OLESTR(" ")); itemParam->set_s(str); items->ksAddArrayItem(-1, itemParam); SysFreeString(str); itemFont->set_bitVector(S_UPPER_INDEX); str = SysAllocString(OLESTR("")); itemParam->set_s(str); items->ksAddArrayItem(-1, itemParam); SysFreeString(str); itemFont->set_bitVector(S_LOWER_INDEX); str = SysAllocString(OLESTR("")); itemParam->set_s(str); items->ksAddArrayItem(-1, itemParam); SysFreeString(str); itemFont->set_bitVector(S_END); str = SysAllocString(OLESTR("  ")); itemParam->set_s(str); items->ksAddArrayItem(-1, itemParam); SysFreeString(str); // ,     itemFont.Unbind(); itemParam.Unbind(); //  ksTextLineParam TextLineParamPtr lineParam; lineParam = static_cast<TextLineParamPtr>(kompas->GetParamStruct(ko_TextLineParam)); lineParam->Init(); lineParam->SetTextItemArr(items); //  ksParagraphParam ParagraphParamPtr paragraphParam; paragraphParam= static_cast<ParagraphParamPtr>(kompas->GetParamStruct(ko_ParagraphParam)); paragraphParam->Init(); paragraphParam->set_x(30.0); paragraphParam->set_y(100.0); //  Document2D->ksParagraph(paragraphParam); Document2D->ksTextLine(lineParam); Document2D->ksEndObj(); //  items->ksDeleteArray(); items.Unbind(); lineParam.Unbind(); paragraphParam.Unbind(); 
 Die folgende Abbildung zeigt das Ergebnis dieses Programms.
 Sie
Sie können keine 
Teilzeichenfolge und Teilzeichenfolge mit der Methode 
ksDocument2D :: ksText erstellen .
Steuerung der Hauptzeilengröße
Die Hauptzeile kann eine andere Größe haben, die über die Schnittstelle 
ksTextItemParam geändert werden kann. Dazu wird die Konstante 
SUM_TYPE in ihrer 
Eigenschaft type und die erforderliche Größe der Hauptzeile in der Eigenschaft 
iSNumb angegeben . Gültige Werte sind in der folgenden Tabelle aufgeführt:

Wenn die 
iSNumb- Eigenschaft 
einen ungültigen Wert 
enthält , verwendet KOMPAS den Standardwert.
Das Folgende ist ein Ausschnitt aus einem Programm, das die Verwendung der Konstante 
SUM_TYPE demonstriert.
Programm-Snippet //   DynamicArrayPtr items; items = static_cast<DynamicArrayPtr>(kompas->GetDynamicArray(TEXT_ITEM_ARR)); items->ksClearArray(); TextItemParamPtr itemParam; itemParam = static_cast<TextItemParamPtr>(kompas->GetParamStruct(ko_TextItemParam)); itemParam->Init(); TextItemFontPtr itemFont; itemFont = static_cast<TextItemFontPtr>(itemParam->GetItemFont()); //   BSTR str = SysAllocString(OLESTR("  ")); itemParam->set_s(str); items->ksAddArrayItem(-1, itemParam); SysFreeString(str); itemFont->set_bitVector(S_BASE); itemParam->set_type(SUM_TYPE); itemParam->set_iSNumb(2); str = SysAllocString(OLESTR(" ")); itemParam->set_s(str); items->ksAddArrayItem(-1, itemParam); SysFreeString(str); itemFont->set_bitVector(S_UPPER_INDEX); itemParam->set_type(0); itemParam->set_iSNumb(0); str = SysAllocString(OLESTR("")); itemParam->set_s(str); items->ksAddArrayItem(-1, itemParam); SysFreeString(str); itemFont->set_bitVector(S_LOWER_INDEX); str = SysAllocString(OLESTR("")); itemParam->set_s(str); items->ksAddArrayItem(-1, itemParam); SysFreeString(str); itemFont->set_bitVector(S_END); str = SysAllocString(OLESTR("  ")); itemParam->set_s(str); items->ksAddArrayItem(-1, itemParam); SysFreeString(str); // ,     itemFont.Unbind(); itemParam.Unbind(); //  ksTextLineParam TextLineParamPtr lineParam; lineParam = static_cast<TextLineParamPtr>(kompas->GetParamStruct(ko_TextLineParam)); lineParam->Init(); lineParam->SetTextItemArr(items); //  ksParagraphParam ParagraphParamPtr paragraphParam; paragraphParam= static_cast<ParagraphParamPtr>(kompas->GetParamStruct(ko_ParagraphParam)); paragraphParam->Init(); paragraphParam->set_x(30.0); paragraphParam->set_y(100.0); //  Document2D->ksParagraph(paragraphParam); Document2D->ksTextLine(lineParam); Document2D->ksEndObj(); //  items->ksDeleteArray(); items.Unbind(); lineParam.Unbind(); paragraphParam.Unbind(); 
 Die 
Konstante SUM_TYPE wird in die 
type- Eigenschaft der Schnittstelle 
ksTextItemParam eingegeben , wenn die Hauptzeile 
angezeigt wird . Vor der Ausgabe des 
Add-Ins wird die 
ksTextItemParam- Schnittstelle auf ihren Ausgangszustand zurückgesetzt. Dies ist der einzige Unterschied zwischen diesem und dem vorherigen Beispiel.
Die folgende Abbildung zeigt das Ergebnis des Programms (vergleichen Sie es mit dem Ergebnis des vorherigen Beispiels).

Mit der 
Konstante SUM_TYPE können Sie die Größe der Hauptzeichenfolge ändern, nicht jedoch Teilzeichenfolgen und Teilzeichenfolgen. Das Ändern der Größe in KOMPAS ist nicht vorgesehen.
Sonderzeichen einschließlich Teilzeichenfolge
Ein Absatz kann Sonderzeichen verarbeiten, die eine Zeichenfolge enthalten (diese wurden in 
Lektion 10 des Zyklus erläutert). Das Folgende ist ein Fragment eines Programms, das ihre Verwendung in einem Absatz demonstriert.
Programm-Snippet //  DynamicArrayPtr items; items = static_cast<DynamicArrayPtr>(kompas->GetDynamicArray(TEXT_ITEM_ARR)); items->ksClearArray(); DynamicArrayPtr lines; lines = static_cast<DynamicArrayPtr>(kompas->GetDynamicArray(TEXT_LINE_ARR)); lines->ksClearArray(); //   TextLineParamPtr lineParam; lineParam = static_cast<TextLineParamPtr>(kompas->GetParamStruct(ko_TextLineParam)); lineParam->Init(); TextItemParamPtr itemParam; itemParam = static_cast<TextItemParamPtr>(kompas->GetParamStruct(ko_TextItemParam)); itemParam->Init(); TextItemFontPtr itemFont = static_cast<TextItemFontPtr>(itemParam->GetItemFont()); //   BSTR str = SysAllocString(OLESTR(" ")); itemParam->set_s(str); items->ksAddArrayItem(-1, itemParam); lineParam->SetTextItemArr(items); lines->ksAddArrayItem(-1, lineParam); lineParam->Init(); SysFreeString(str); str = NULL; //     itemFont->set_bitVector(NEW_LINE | SPECIAL_SYMBOL); str = SysAllocString(OLESTR(" ")); itemParam->set_s(str); itemParam->set_type(SPECIAL_SYMBOL); itemParam->set_iSNumb(169); items->ksAddArrayItem(-1, itemParam); SysFreeString(str); str = NULL; //   itemFont->set_bitVector(SPECIAL_SYMBOL_END); itemParam->set_s(NULL); itemParam->set_type(0); itemParam->set_iSNumb(0); items->ksAddArrayItem(-1, itemParam); lineParam->SetTextItemArr(items); lines->ksAddArrayItem(-1, lineParam); lineParam->Init(); //     itemFont->set_bitVector(NEW_LINE | SPECIAL_SYMBOL); str = SysAllocString(OLESTR(" ")); itemParam->set_s(str); itemParam->set_type(SPECIAL_SYMBOL); itemParam->set_iSNumb(96); items->ksAddArrayItem(-1, itemParam); SysFreeString(str); str = NULL; //   itemFont->set_bitVector(SPECIAL_SYMBOL_END); itemParam->set_s(NULL); itemParam->set_type(0); itemParam->set_iSNumb(0); items->ksAddArrayItem(-1, itemParam); lineParam->SetTextItemArr(items); lines->ksAddArrayItem(-1, lineParam); lineParam->Init(); //   itemFont->set_bitVector(NEW_LINE); str = SysAllocString(OLESTR(" ")); itemParam->set_s(str); itemParam->set_type(0); itemParam->set_iSNumb(0); items->ksAddArrayItem(-1, itemParam); lineParam->SetTextItemArr(items); lines->ksAddArrayItem(-1, lineParam); lineParam->Init(); SysFreeString(str); str = NULL; itemParam.Unbind(); lineParam.Unbind(); itemFont.Unbind(); items.Unbind(); //    ParagraphParamPtr paragraphParam; paragraphParam= static_cast<ParagraphParamPtr>(kompas->GetParamStruct(ko_ParagraphParam)); paragraphParam->Init(); paragraphParam->set_x(100.0); paragraphParam->set_y(100.0); paragraphParam->set_width(60.0); paragraphParam->set_hFormat(2); //    TextParamPtr textParam = static_cast<TextParamPtr>(kompas->GetParamStruct(ko_TextParam)); textParam->SetParagraphParam(paragraphParam); textParam->SetTextLineArr(lines); //  Document2D->ksTextEx(textParam, 1); lines->ksDeleteArray(); lines.Unbind(); paragraphParam.Unbind(); textParam.Unbind(); 
 Das Beispiel sieht sehr kompliziert aus, aber wenn Sie es sich genau ansehen, können Sie sehen, dass es aus sich wiederholenden Teilen besteht. Darin werden mit Hilfe von Sonderzeichen durchgestrichene und unterstrichene Texte angezeigt. Nach jedem solchen Block wird eine leere Zeile mit dem Flag 
SPECIAL_SYMBOL_END angezeigt . Seine Aufgabe ist es, die Aktion des Sonderzeichens abzubrechen. Wenn es nicht angezeigt wird, ist der Absatz möglicherweise nicht richtig aufgebaut. Die Aktion des Sonderzeichens erstreckt sich auf den gesamten 
ksTextLineParam- Block, auf seine gesamte Länge, unabhängig von seinem tatsächlichen Inhalt (diese These ist in der folgenden Abbildung dargestellt).

Die 
Abbruchzeile muss Teil des Blocks 
ksTextLineParam sein . Andernfalls ist der Absatz möglicherweise nicht korrekt aufgebaut. Der Block 
ksTextLineParam kann mehrere Steuerzeichen enthalten. Jeder von ihnen sollte eine eigene Abbruchzeile haben.
Das Flag 
SPECIAL_SYMBOL_END wird nur für Sonderzeichen mit einer 
Teilzeichenfolge verwendet. Für gewöhnliche Sonderzeichen wird es nicht benötigt.
Die folgende Abbildung zeigt das Ergebnis unseres Beispiels.
 Fazit
FazitIn dieser Lektion haben wir gelernt, wie man mit Absätzen zusammengesetzte Linien erstellt, einschließlich Abweichungen und Brüche, und dokumentierte Möglichkeiten untersucht, um zusammengesetzte Linien basierend auf einem Absatz zu erstellen. Dies ist nicht der einzige und bei weitem nicht einfachste Weg, sie zu erstellen. Eine andere, viel einfachere Möglichkeit werden wir in der nächsten Lektion betrachten.
Um fortzufahren, folgen Sie den Nachrichten des Blogs.
 Sergey Norseev, Ph.D., Autor des Buches "Anwendungsentwicklung für COMPAS in Delphi".