[CONNECT U10 C++] Upgrading a call to V8i mdlText_create with a CONNECT TextBlock

I am replacing a call to mdlText_create with a TextBlock. I am trying to set the location of the text with the SetUserOrigin method, but the text is not created at that location.  Am I using the correct method or am I doing something else wrong?  I am including the code I use to create a text element and a line element. The line is created in the correct location but the text is not.

Private void text_test()
{
	                         
	Dpoint3d  ptTemp;
	ptTemp.x = 13307591.40;
	ptTemp.y = 994947.00;
	ptTemp.z = 291.70;
	
	//create text element
	TextBlockPropertiesPtr tbProps = TextBlockProperties::Create(*DgnTextStyle::GetActive(), *ISessionMgr::GetActiveDgnModelP());
	tbProps->SetIsViewIndependent(true);
	
	ParagraphPropertiesPtr paraProps = ParagraphProperties::Create(*DgnTextStyle::GetActive(), *ISessionMgr::GetActiveDgnModelP());
	paraProps->SetJustification(Bentley::DgnPlatform::TextElementJustification::CenterBaseline);

	RunPropertiesPtr runProps = RunProperties::Create(*DgnTextStyle::GetActive(), *ISessionMgr::GetActiveDgnModelP());
	
	TextBlockPtr textBlock = TextBlock::Create(*tbProps, *paraProps, *runProps, *ISessionMgr::GetActiveDgnModelP());
	textBlock->GetRunPropertiesForAddR().SetFontSize(DPoint2d::From(10.0,10.0));
	textBlock->SetUserOrigin(ptTemp);	
	textBlock->AppendText(L"test");

	EditElementHandle eeh;
	TextHandlerBase::CreateElement(eeh, NULL, *textBlock);
	MSElementP tmpElement;
	tmpElement = eeh.GetElementP();
	mdlElement_display(tmpElement, DgnPlatform::DRAW_MODE_Normal);
	mdlElement_add(tmpElement);


	//create line element
	Dpoint3d        testLine[2];
	testLine[0].x = ptTemp.x;
	testLine[0].y = ptTemp.y;
	testLine[0].z = ptTemp.z;

	testLine[1].x = ptTemp.x + 1.0;
	testLine[1].y = ptTemp.y;
	testLine[1].z = ptTemp.z;

	mdlLine_create(&element, NULL, testLine);
	mdlElement_display(&element, DgnPlatform::DRAW_MODE_Normal);
	mdlElement_add(&element);

}

Thanks for your help.

Warren

  • TextBlock

    I am trying to set the location of the text with the SetUserOrigin method, but the text is not created at that location

    Where is it created?  Is the actual location offset by the text justification CenterBaseline?

    Am I using the correct method?

    I don't see any other choice to SetUserOrigin!  I've been using it since CONNECT was introduced without a problem.

    create a text element
    EditElementHandle eeh;
    TextHandlerBase::CreateElement(eeh, NULL, *textBlock);
    MSElementP tmpElement;
    tmpElement = eeh.GetElementP();
    mdlElement_display(tmpElement, DgnPlatform::DRAW_MODE_Normal);
    mdlElement_add(tmpElement);

    There's some unneccessary work there.  Prefer EditElementHandle.AddToModel().  An element is displayed as soon as it's persisted to the DGN model.  That's been the case since MicroStation XM moved to DirectX many years ago.

    Lines and LineStrings

    create line element

    Prefer the LineHandler.CreateLineElement and LineStringHandler.CreateLineStringElement methods to MDL.

     
    Regards, Jon Summers
    LA Solutions

  • Thanks for the reply. The text is create thousands of units away from the line element. Could that be due to justification???  I will remove the unnecessary code and upgrade to the preferred methods. Thanks for your suggestions.

  • The text is created thousands of units away from the line element

    Test with and without some text settings in your code.  I've not attempted a View Independent TextBlock.

     
    Regards, Jon Summers
    LA Solutions

  • I removed tbProps->SetIsViewIndependent(true); and still have the same problem.  I use basically the same code in differnet MDL applications and it works.  Something is being left out or set incorrectly somewhere...

  • Please refer my below test code snippet. It can create text element in correct location running on MSCE-U13.

    	DgnModelP       pActiveModel = ISessionMgr::GetActiveDgnModelP();
    	TextBlockPropertiesPtr  pTBProp = TextBlockProperties::Create(*pActiveModel);
    	ParagraphPropertiesPtr  pParaProp = ParagraphProperties::Create(*pActiveModel);
    	pParaProp->SetJustification(TextElementJustification::LeftBaseline);
    	DgnTextStylePtr         pStyle = DgnTextStyle::GetActive();
    	RunPropertiesPtr        pRunProp = RunProperties::Create(*pStyle, *pActiveModel);
    
    	TextBlockPtr pTextBlock = TextBlock::Create(*pTBProp, *pParaProp, *pRunProp, *pActiveModel);
    	pTextBlock->SetUserOrigin(DPoint3d::From(10000, 10000, 0));
    	pTextBlock->AppendText(L"TestString");
    
    	EditElementHandle  eeh;
    	if (TEXTBLOCK_TO_ELEMENT_RESULT_Success ==
    		TextHandlerBase::CreateElement(eeh, nullptr, *pTextBlock))
    	{
    		eeh.AddToModel();
    	}



  • Thanks for the help.  I made a few changes to my test case to match your example, but I still had the same problem.  I can create a line at the correct location, but when I try to create text it is created at a location with very large X and Y values (greater than 21,000,000).  I think memory is being corrupted or possibly a value needed by the text routine is not being set.

  • Have you taken your UOR values:

    Dpoint3d ptTemp;
    ptTemp.x = 13307591.40;
    ptTemp.y = 994947.00;
    ptTemp.z = 291.70;

    and converted them back to whatever Master/Sub units you are using. Does that result match the location where your text is being placed? Remember, the DPoint3d you supply is in UORs, not Master Units...