Does anyone have any example C++ code snippets for the TextBlock object? There are some good starting points in MicroStationAPI.chm under the depreciated mdlText_create() function section but I would love to see a working function (or documentation) that just creates a piece of text and places it into a dgn.
Thanks, Loren.
Unknown said:Does anyone have any example C++ code snippets for the TextBlock object?
Search the examples installed with the SDK. I see several that use a TextBlock for various purposes.
Found 56 occurrence(s) in 7 file(s)
Regards, Jon Summers LA Solutions
Hi Jon,
None of the examples actually create a text feature from scratch using the Create(...) methods which is what I need to do. For example,
1) incrementText.cpp copies an existing textstring with: TextBlockPtr textBlock = textQuery->GetTextPart (eh, *textPart);
2)ModifyMultipleElements.cpp uses GetTextPart - TextBlockPtr textBlock = textEdit->GetTextPart (*elementToModify, *textPart);
3)PrintTextSubst.cpp - only uses GetTextPart as well
4)ReportsExamplePlaceReportTool.cpp = TextBlockPtr textBlock = cell->CreateEmptyTextBlock ();
5)TagsExamplePlaceTagFromText.cpp - textQuery->GetTextPart (*eeh, *textPart)
6)odbcoledbdemo.cpp is the closest to what I am looking for with: TextBlockPtr tb = TextBlock::Create(*m_TextStyle, *m_ActiveModel); however no example about size, font,origin, justification etc.
The closest thing I can find is the depreciated help on mdlText_create() which says:
==================================================================================================================
// If you want to start with active settings, or from any other DgnTextStyle object...TextBlockPtr textBlock = TextBlock::Create (*DgnTextStyle::GetActive (*ISessionMgr::GetActiveDgnFile ()), *ISessionMgr::GetActiveDgnModelP ());// -or- If you want to start from an existing template element...ElementHandle eh (...);TextBlockPtr textBlock = TextHandlerBase::GetFirstTextPartValue (eh);if (!textBlock.IsValid ())/* ERROR */textBlock->Clear ();// -or- If you want to start from scratch...TextBlockPtr textBlock = TextBlock::Create (*ISessionMgr::GetActiveDgnModelP ());// -or- You can manually configure the settings up front...TextBlockPropertiesPtr tbProps = TextBlockProperties::Create (...);ParagraphPropertiesPtr paraProps = ParagraphProperties::Create (...);RunPropertiesPtr runProps = RunProperties::Create (...);tbProps.Set... ();paraProps.Set... ();runProps.Set... ();TextBlockPtr textBlock = TextBlock::Create (*tbProps, *paraProps, *runProps, *ISessionMgr::GetActiveDgnModelP ());// Then tweak as desired (if you didn't set up properties up-front)...// TextParamWide is split between TextBlockProperties, ParagraphProperties, and RunProperties. TextSizeParam (now simply a DPoint2d in UORs) is on RunProperties (via (Get|Set)FontSize).TextBlockPropertiesPtr tbProps = textBlock->GetProperties ().Clone ();tbProps->Set... ();textBlock->SetProperties (*tbProps);textBlock->GetParagraphPropertiesForAddR ().Set... ();textBlock->GetRunPropertiesForAddR ().Set... ();textBlock->SetUserOrigin (...);textBlock->SetOrientation (...);// Add text...textBlock->AppendText (...);textBlock->AppendEnterDataField (...);// Create the element...EditElementHandle eeh;if (TextBlock::TO_ELEMENT_RESULT_Success != TextHandlerBase::CreateElement (eeh, NULL /* use the template if you have it */, *textBlock))/* ERROR */// eeh now contains a text element (or node) that you can AddToModel etc.
This is where I am starting (bold section), however with all the generic "create(...)"s and no other documentation to be found, I am reading through include files to try and decipher what is required where and how.
I am trying to rewrite my own place text function that I use througout my code:
"Public int PlaceText ( char text[][256], DPoint3d *pt, double size, int numlines, ULong color, ULong weight, UInt32 levelID, int just, RotMatrix *rMatrix )"
It creates text from scratch and takes all parameters such as size, font, color etc as input.
Once again thanks for your help Jon, you continue to be a valued resource to the uStn programming community and frequently come up with solutions far faster than the Bentley support crew (who seem to be ignoring most of these forum posts)
I will start a SELECT service ticket asking for a place text example and hope that Bentley can supply one - if so I will post it here.
Loren.
Hi Loren,
This is what I am currently using.
bool GetTextBlock(EditElementHandleR textElm, DPoint3d origin, RotMatrix orientation, std::wstring text, UInt32 textColor, double font_Width, double font_Height, TextElementJustification alignment){ DPoint2d fontSize; fontSize.x = font_Width; fontSize.y = font_Height; TextBlockPropertiesPtr tbProps = TextBlockProperties::Create(*ISessionMgr::GetActiveDgnModelP()); ParagraphPropertiesPtr paraProps = ParagraphProperties::Create(*ISessionMgr::GetActiveDgnModelP()); RunPropertiesPtr runProps = RunProperties::Create(*DgnTextStyle::GetActive(), *ISessionMgr::GetActiveDgnModelP()); tbProps->SetIsViewIndependent(true); paraProps->SetJustification(alignment); runProps->SetColor(textColor); runProps->SetFontSize(fontSize); TextBlockPtr textBlock = TextBlock::Create(*tbProps, *paraProps, *runProps, *ISessionMgr::GetActiveDgnModelP()); textBlock->SetProperties(*tbProps); textBlock->SetUserOrigin(origin); textBlock->SetOrientation(orientation); // Add text... textBlock->AppendText(text.c_str()); if (TEXTBLOCK_TO_ELEMENT_RESULT_Success != TextHandlerBase::CreateElement(textElm, NULL, *textBlock)){ return false; } return true; }
Answer Verified By: Loren
Here's what I came up with using Maury's code as a starting point. It adds font, level and will place textnodes instead of text if numlines > 1, and places the text feature into the dgn:
sprintf(textarray[0], "File: %s", szBuffer); sprintf(textarray[1], "Project: %s", g3header.project ); sprintf(textarray[2], ... PlaceText(&textarray[0], &textorigin, textsize, 11, white, 0, EllipLevelID, TextElementJustification::LeftBaseline, rMatrix, L"Courier New"); Public int PlaceText ( char text[][255], DPoint3dCP pt, double size, int numlines, ULong color, ULong weight, LevelId levelID, TextElementJustification just, RotMatrixCP rMatrix, WChar *font ) { RotMatrix rotation; EditElementHandle textElm; if (rMatrix == NULL) rotation = RotMatrix::FromIdentity(); else rotation = *rMatrix; DgnFontP fontP = DgnFontManager::FindSystemFont(font); DPoint2d fontSize = {size, size}; TextBlockPropertiesPtr tbProps = TextBlockProperties::Create(*ISessionMgr::GetActiveDgnModelP()); ParagraphPropertiesPtr paraProps = ParagraphProperties::Create(*ISessionMgr::GetActiveDgnModelP()); RunPropertiesPtr runProps = RunProperties::Create(*DgnTextStyle::GetActive(), *ISessionMgr::GetActiveDgnModelP()); tbProps->SetIsViewIndependent(true); paraProps->SetJustification(just); paraProps->SetLineSpacingValue(size * 1.35); //leading - should be between 120 and 145 percent runProps->SetColor(color); runProps->SetFont(*fontP); runProps->SetFontSize(fontSize); TextBlockPtr textBlock = TextBlock::Create(*tbProps, *paraProps, *runProps, *ISessionMgr::GetActiveDgnModelP()); textBlock->SetProperties(*tbProps); textBlock->SetUserOrigin(*pt); textBlock->SetOrientation(rotation); for (int i=0; i<numlines;i++) { if (i) textBlock->AppendText(L"\n"); mdlCnv_convertMultibyteToUnicode(text[i], -1, textW, strlen(text[i]))); textBlock->AppendText(textW); } if (TEXTBLOCK_TO_ELEMENT_RESULT_Success != TextHandlerBase::CreateElement(textElm, NULL, *textBlock)) return(FALSE); ElementPropertiesSetterPtr propsSetter = ElementPropertiesSetter::Create(); propsSetter->SetLevel(levelID); propsSetter->Apply(textElm); textElm.AddToModel(); return(TRUE); }