# directx textbox issues

This topic is 4415 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

## Recommended Posts

I am going to work on a GUI library for direct3D and before I started I wanted to resolve a slight issue I foresee with textboxes. I will need to be able to tell where to put the carat when a box is clicked. This would be fairly trivial for fixed width fonts, but not so much with fonts like Times New Roman. Is there a way to tell from a direct3Dfont object the distance a particular letter is from the beginning of a string? The GetMetrics method only seems to make available the min, max, and average character widths of a particular font which does not seem to be enough information to solve this.

##### Share on other sites
Can't you just accumalate its position using the character widths you mentioned?

Dave

##### Share on other sites
Quote:
 Original post by DaveCan't you just accumalate its position using the character widths you mentioned?Dave

That would only work for a fixed width font. If I have a highly variable width font, I would need to know the width each possible character in the font has.

##### Share on other sites
I think you'd actually have to count it manually, increment each letter, see if it's at the mouse position, if not move on to the next.

##### Share on other sites
Quote:
 Original post by xycsoscyxI think you'd actually have to count it manually, increment each letter, see if it's at the mouse position, if not move on to the next.

I believe so too, the problem however is I need a way to get the width of the ith character in my textbox string.

The pseudo code would be something like this:

int relMouseX = mouseX - textBox.mouseX;//need to determine where to place caratint distFromStrStart = 0for( int i = 0; i < TextBox.string.length(); i++ ){ int w = width( TextBox.string, direct3dfont );  //relative mouse position is inside left halfbox of character if( distFromStrStart < relMouseX && relMouseX < distFromStrStart + w /2 ) {    caratPos = i;    break; } //relative mouse position is inside right halfbox of character if( distFromStrStart + w /2 < relMouseX && relMouseX < distFromStrStart + w ) {    caratPos = i + 1;    break; } distFromStrStart += w;}

So basically what's missing is my width function which takes into account the size, font, bold, italices, etc. of the font the string is rendered in.

[Edited by - Khaos Dragon on June 16, 2006 5:12:01 PM]

##### Share on other sites
I believe you can use DT_CALCRECT with ID3DXFont::DrawText to calculate te size of a given string in a font. Just use that with the aforementioned incrementing method and find which character is nearest to the cursor and place the caret after that.

##### Share on other sites
ouraqt is right - but there are a few gotchas - like the fact that spaces at the beginning/end of the string arent included in the width calculation.

Alex

##### Share on other sites
Quote:
 Original post by Afaceouraqt is right - but there are a few gotchas - like the fact that spaces at the beginning/end of the string arent included in the width calculation.Alex

Is there any way to calculate the width of a single space character in the font then?

##### Share on other sites
Can you not just write your own font engine and file format that contains the character widths, or would that just be too much work do you think?

##### Share on other sites
I just step thru like this... seems quick enough :)

//--------------------------------------------------------------------------------------bool cEditBox::HandleLButtonDown(POINT mousePoint){//	char szOutput[128];//	StringCchPrintf( szOutput, 128, "WM_LBUTTONDOWN on cEditBox %s\n", m_caption );					g_log->GUI( "WM_LBUTTONDOWN on cEditBox %s\n", m_caption );	g_guiManager->SetActiveWindow( this );	SetState( WINSTATE_ACTIVE );	m_parent->SetState( WINSTATE_ACTIVE );	// Get coords and work out index clicked	char workText[GUI_MAX_TEXT];	SIZE tempSize;	int x = mousePoint.x - m_x - m_parent->GetXPosition();	for ( unsigned int i = 0; i < m_text.size(); i++ )	{		workText = m_text;		tempSize = g_guiManager->GetNormalText()->GetTextExtent( workText );			if ( x <= tempSize.cx )		{			m_caretIndex = i + 1;			m_caretPosition = tempSize.cx - 2;			break;		}	}	tempSize = g_guiManager->GetNormalText()->GetTextExtent( workText );		// check if click is at end	if ( x > tempSize.cx )	{			m_caretIndex = i;			m_caretPosition = tempSize.cx - 2;	}	return true;  // true = 'dealt with'}

The GetTextExtent() function is as the SDK sample.

1. 1
Rutin
26
2. 2
3. 3
JoeJ
20
4. 4
5. 5

• 10
• 9
• 9
• 10
• 46
• ### Forum Statistics

• Total Topics
631751
• Total Posts
3002078
×