C++ GetTextExtentPoint32 没有给出正确的大小
C++ GetTextExtentPoint32 doesn't give the correct size
我正在尝试使用 GetTextExtentPoint32 获取文本字符串的大小。我多次阅读文档并做了一些研究,据我所知,下面的代码应该给我正确的 width
和 height
文本。
vFontFamily = "Segoe UI"; //font family
vFontSize = 26; //font size
HDC hdc = GetDC(hwnd);
HFONT hFont = CreateFont(
-MulDiv(vFontSize, GetDeviceCaps(hdc, LOGPIXELSY), 72), //calculate the actual cHeight.
0, 0, 0, // normal orientation
FW_NORMAL, // normal weight--e.g., bold would be FW_BOLD
false, false, false, // not italic, underlined or strike out
DEFAULT_CHARSET, OUT_OUTLINE_PRECIS, // select only outline (not bitmap) fonts
CLIP_DEFAULT_PRECIS, CLEARTYPE_QUALITY, VARIABLE_PITCH | FF_SWISS, vFontFamily);
SIZE size;
HFONT oldfont = (HFONT)SelectObject(hdc, hFont);
GetTextExtentPoint32(hdc, L"This is Text", wcslen(L"This is Text"), &size);
width = size.cx; //get width
height = size.cy; //get height
SelectObject(hdc, oldfont); //don't forget to select the old.
DeleteObject(hFont); //always delete the object after creating it.
ReleaseDC(hwnd, hdc); //alway reelase dc after using.
不幸的是,它没有给我正确的尺寸。宽度至少有 10% 太多,高度至少有 5% 太多。确切的说,This is Text
的文本中宽度的结果是228
,高度是62
,而更准确的是我认为接近190 x 55
。
文字使用GDI+绘制。
case WM_PAINT: {
PAINTSTRUCT ps;
HDC hdc = BeginPaint(hwnd, &ps);
Graphics g(hdc);
FontFamily theFontFamily(vFontFamily);
Font font(&theFontFamily, vFontSize, FontStyleRegular, UnitPixel);
SolidBrush brush(Color(255, R, G, B));
PointF pointF(0.0f, 0.0f);
TextRenderingHint hint = g.GetTextRenderingHint(); // Get the text rendering hint.
g.SetTextRenderingHint(TextRenderingHintAntiAlias); // Set the text rendering hint to TextRenderingHintAntiAlias.
g.DrawString(L"This is Text", strlen("This is Text"), &font, pointF, &brush);
EndPaint(hwnd, &ps);
return TRUE;
}
我想这可能与我绘制文本的方式有关,因为在绘制消息中,我使用了 Font
而不是 HFONT
。但这没有任何意义,对吧?只要我在 GetTextExtentPoint32
之前设置了正确的字体系列和字体大小,它就会给我准确的文本宽度和高度。你怎么看?
您正在使用 GDI to measure your text while you are using GDI+ 绘制它。
GDI+ 是对 GDI 的改进,当你使用它来渲染文本等时,两者之间存在差异。另一件事是 DPI Awareness,在测量文本时,你需要确保也处理缩放。当您使用 GDI+ 绘制它时,如果您在测量时没有正确处理 DPI,则与实际宽度和高度相比,您的方法的结果会更大。
尝试使用评论中提到的Graphics::MeasureString and see if you get the expected width and height. Do it the same way how you draw your string just like what AlanBirtles。
例如,
HDC hdc = GetDC(hwnd); //get dc of your handle.
Graphics graphics(hdc); //setup graphics.
FontFamily theFontFamily(vFontFamily); //setup your font family.
Font font(&theFontFamily, vFontSize, FontStyleRegular, UnitPixel); //create the font the same way how you do it on your paint message.
PointF pointF(0.0f, 0.0f); //use PointF instead of RectF since thats how you paint it.
RectF boundRect; //setup boundRect to get the width and height.
graphics.MeasureString(text, -1, &font, pointF, &boundRect); //Measure the text of the string
//or
//graphics.MeasureString(L"This is Text", strlen("This is Text"), pointF, &boundRect);
width = boundRect.Width; //get the width of text from boundRect.
height = boundRect.Height; //get the height of text from boundRect.
DeleteObject(&font); //delete the font.
ReleaseDC(LabelHandle, hdc); //always reelase dc after using.
如果您需要更多解释,以下内容可能会对您有所帮助。
DPI-awareness is really needed?
How to draw a GDI + text independent of DPI
.
我正在尝试使用 GetTextExtentPoint32 获取文本字符串的大小。我多次阅读文档并做了一些研究,据我所知,下面的代码应该给我正确的 width
和 height
文本。
vFontFamily = "Segoe UI"; //font family
vFontSize = 26; //font size
HDC hdc = GetDC(hwnd);
HFONT hFont = CreateFont(
-MulDiv(vFontSize, GetDeviceCaps(hdc, LOGPIXELSY), 72), //calculate the actual cHeight.
0, 0, 0, // normal orientation
FW_NORMAL, // normal weight--e.g., bold would be FW_BOLD
false, false, false, // not italic, underlined or strike out
DEFAULT_CHARSET, OUT_OUTLINE_PRECIS, // select only outline (not bitmap) fonts
CLIP_DEFAULT_PRECIS, CLEARTYPE_QUALITY, VARIABLE_PITCH | FF_SWISS, vFontFamily);
SIZE size;
HFONT oldfont = (HFONT)SelectObject(hdc, hFont);
GetTextExtentPoint32(hdc, L"This is Text", wcslen(L"This is Text"), &size);
width = size.cx; //get width
height = size.cy; //get height
SelectObject(hdc, oldfont); //don't forget to select the old.
DeleteObject(hFont); //always delete the object after creating it.
ReleaseDC(hwnd, hdc); //alway reelase dc after using.
不幸的是,它没有给我正确的尺寸。宽度至少有 10% 太多,高度至少有 5% 太多。确切的说,This is Text
的文本中宽度的结果是228
,高度是62
,而更准确的是我认为接近190 x 55
。
文字使用GDI+绘制。
case WM_PAINT: {
PAINTSTRUCT ps;
HDC hdc = BeginPaint(hwnd, &ps);
Graphics g(hdc);
FontFamily theFontFamily(vFontFamily);
Font font(&theFontFamily, vFontSize, FontStyleRegular, UnitPixel);
SolidBrush brush(Color(255, R, G, B));
PointF pointF(0.0f, 0.0f);
TextRenderingHint hint = g.GetTextRenderingHint(); // Get the text rendering hint.
g.SetTextRenderingHint(TextRenderingHintAntiAlias); // Set the text rendering hint to TextRenderingHintAntiAlias.
g.DrawString(L"This is Text", strlen("This is Text"), &font, pointF, &brush);
EndPaint(hwnd, &ps);
return TRUE;
}
我想这可能与我绘制文本的方式有关,因为在绘制消息中,我使用了 Font
而不是 HFONT
。但这没有任何意义,对吧?只要我在 GetTextExtentPoint32
之前设置了正确的字体系列和字体大小,它就会给我准确的文本宽度和高度。你怎么看?
您正在使用 GDI to measure your text while you are using GDI+ 绘制它。
GDI+ 是对 GDI 的改进,当你使用它来渲染文本等时,两者之间存在差异。另一件事是 DPI Awareness,在测量文本时,你需要确保也处理缩放。当您使用 GDI+ 绘制它时,如果您在测量时没有正确处理 DPI,则与实际宽度和高度相比,您的方法的结果会更大。
尝试使用评论中提到的Graphics::MeasureString and see if you get the expected width and height. Do it the same way how you draw your string just like what AlanBirtles。
例如,
HDC hdc = GetDC(hwnd); //get dc of your handle.
Graphics graphics(hdc); //setup graphics.
FontFamily theFontFamily(vFontFamily); //setup your font family.
Font font(&theFontFamily, vFontSize, FontStyleRegular, UnitPixel); //create the font the same way how you do it on your paint message.
PointF pointF(0.0f, 0.0f); //use PointF instead of RectF since thats how you paint it.
RectF boundRect; //setup boundRect to get the width and height.
graphics.MeasureString(text, -1, &font, pointF, &boundRect); //Measure the text of the string
//or
//graphics.MeasureString(L"This is Text", strlen("This is Text"), pointF, &boundRect);
width = boundRect.Width; //get the width of text from boundRect.
height = boundRect.Height; //get the height of text from boundRect.
DeleteObject(&font); //delete the font.
ReleaseDC(LabelHandle, hdc); //always reelase dc after using.
如果您需要更多解释,以下内容可能会对您有所帮助。
DPI-awareness is really needed?
How to draw a GDI + text independent of DPI
.