Visual Studio Professional 2017 15.5.7 GetTextExtentPoint32W returns wrong width of the specified Unicode string "⟹⟹⟹⟹⟹⟹"

  • Thread starter Thread starter Andreas Schniertshauer
  • Start date Start date
A

Andreas Schniertshauer

Guest
Hello,

I have a problem with the GetTextExtentPoint32W returning the wrong width of the specified string of text in our application.
When I call DrawText(hdc, sz, len, &rc, DT_CALCRECT) I get the correct width.
I created a little demo project to reproduce the problem:

1. Create a new "Visual C++\Windows Desktop Application" and change the "General\Windows SDK Version" to "8.1"
2. Add the following code into the WndProc function of the "WindowsProject.cpp" file "case WM_PAINT"

case WM_PAINT:
{
PAINTSTRUCT ps;
HDC hdc = BeginPaint(hWnd, &ps);
const auto mm = GetMapMode(hdc);
// TODO: Add any drawing code that uses hdc here...

const WCHAR sz[] = L"\u27F9\u27F9\u27F9\u27F9\u27F9\u27F9";
int len = lstrlen(sz);

HGDIOBJ hObject = ::GetStockObject(DEFAULT_GUI_FONT);
HGDIOBJ hOldObj = ::SelectObject(hdc, hObject);
RECT rc{ 0,0,0,0 };
DrawText(hdc, sz, len, &rc, DT_CALCRECT);
DrawText(hdc, sz, len, &rc, DT_LEFT);

rc.top = rc.bottom + 1;
rc.left = 0;
SIZE s;
GetTextExtentPoint32W(hdc, sz, len, &s);
rc.bottom = rc.top + s.cy;
rc.right = rc.left + s.cx;
DrawText(hdc, sz, len, &rc, DT_LEFT);

::SelectObject(hdc, hOldObj);

EndPaint(hWnd, &ps);
}
break;

3. Compile and run.

Result (see image):
1302661

You see to lines of text:
The first line shows the text calculated with DrawText(DT_CALCRECT) that is displayed correctly,
The second line shows the text calculated with GetTextExtentPoint32W that is displayed only partial.

Expected Result:
Both lines should show the same text six Unicode arrows 'LONG RIGHTWARDS DOUBLE ARROW'.

I also tested this problem with the sample "NewControls" from the "MS Samples 2010\MFC\Visual C++ 2008 Feature Pack"
Microsoft/VCSamples
I added "CString s(L"\u27F9\u27F9\u27F9\u27F9\u27F9\u27F9");" on the top (behind MAX_TIP_TEXT_LENGTH) of the file "Page1.cpp" and in the CPage1 ctor I replaced "m_strToolTip = _T("ToolTip");" with "m_strToolTip = s;" and in the CPage1::OnResetButton I replaced the "m_Button.SetWindowText("Button");" with "m_Button.SetWindowText(s);"
When you execute the program the button text is displayed correctly (all six arrows are shown) but the title tip only shows 4 arrows. I stepped into the CMFCButton::SizeToContent function and there CDC::GetTextExtent is called that calls ::GetTextExtentPoint32. So I thought this would also show the corrupted text but the text is displayed correctly - Can you please explain this? And why is the TitleTip not shown correctly? What must I do in my MFC application to get the correct result from GetTextExtentPoint32?

The OS is Windows 10 Version 1803 (Build 17134.165).

Thanks for the help,



Andreas

Continue reading...
 
Back
Top