锐英源软件
第一信赖

精通

英语

开源

擅长

开发

培训

胸怀四海 

第一信赖

当前位置:锐英源 / 开源技术 / C++API和类开源 / GetTextExtent不精确的优化办法
服务方向
人工智能数据处理
人工智能培训
kaldi数据准备
小语种语音识别
语音识别标注
语音识别系统
语音识别转文字
kaldi开发技术服务
软件开发
运动控制卡上位机
机械加工软件
软件开发培训
Java 安卓移动开发
VC++
C#软件
汇编和破解
驱动开发
联系方式
固话:0371-63888850
手机:138-0381-0136
Q Q:396806883
微信:ryysoft

GetTextExtent不精确的优化办法


Hi,

I'm outputting (to the screen) a graphical string which, occasionally, will be too long for the allocated display rectangle. I intend to write a
scrolling routine for these occasions.

So the program uses GetTextExtent to get the width of the current string and compares that against the width of the display rectangle.

But this doesn't work as GetTextExtent tells me that strings which ARE (visually) too big for the rectangle actually aren't. By this I mean
GetTextExtent specifies the width of a string as 332 and the width of the rectangle is 380 - so the string should fit - but the string doesn't fit
and 2 characters are not displayed. (These are acurate numbers).

Now I assume this is happening because of what it says in the GetTextExtent help:

"Since some devices do not place characters in regular cell arrays (that is, they carry out kerning), the sum of the extents of the characters in a string may not be equal to the extent of the string."

What should I do to get around this?

Thanks and regards,

..matthew你好

我正在输出(到屏幕)一个图形字符串,该字符串有时对于分配的显示矩形来说太长了。我打算为这些情况编写一个滚动例程。

因此,程序使用GetTextExtent来获取当前字符串的宽度,并将其与显示矩形的宽度进行比较。

但这不起作用,因为GetTextExtent告诉我, 对于矩形来说(在视觉上)太大的字符串实际上不是。我的意思是,
GetTextExtent将字符串的宽度指定为332, 矩形的宽度为380-因此字符串应适合-但字符串不适合且不显示2个字符。(这些是准确的数字)。

现在,我假设发生这种情况是因为它在GetTextExtent帮助中所说的:

“由于某些设备没有将字符放置在常规单元格数组中(即,它们执行字距调整),所以字符串中字符范围的总和可能不等于字符串的范围。”

我应该怎么做才能解决这个问题?

感谢致敬,

it is not likely that kerning is the reason for your inaccuracy. Most of the time kerning causes the actual pixel size to be smaller than what GetTextExtent yields, not bigger. Much more likely there is a confusion in units (are you sure your mapmode is still pixels when doing GetTextExtent?) HTH Andreas字距调整不太可能是您不准确的原因。大多数时候,字距调整会导致实际像素大小小于GetTextExtent产生的像素大小,而不是更大。

单位更可能出现混乱( 执行GetTextExtent时,您确定mapmode仍然是像素吗?)

HTH安德烈亚斯

I have a similar problem. I'm using a CListCtrl in report style and I'm trying to resize on of the columns as I put items into the list. I autosize all but the last columns which I'm continually resizing so that it fills the entire control. I'm using custom draw to change colors and such of the lines and always want the line to fill the control so I resize the last columns to, at a min, the width of the control. My problem is that when I check the size of the string going into the last column it gives me a number thats too large. In one example, GetTextExtent() tells me that the string is 477 pixels wide but when I look at the control this is far too wide. An autosize of the column generates a width of 366. I don't do autosizing all the time because it causes some bad flashing of the control when the strings in the last column don't make it to the edge of the control. Its better that the control has columns too wide rather than the flashing. 我有一个类似的问题。我在报表样式中使用CListCtrl,并且
在将项目放入列表时尝试调整列的大小。我会自动调整大小,但最后几列会不断调整大小,以便填充整个控件。我使用自定义绘制来更改线条的颜色等,
并且始终希望线条填充控件,因此我将最后一列的大小调整为至少控件的宽度。我的问题是,当我检查进入最后一列的字符串的大小时,它给我的数字太大
了。在一个示例中,GetTextExtent()告诉我字符串的宽度为477像素,但是当我查看控件时,该字符串太宽了。自动调整大小列的宽度为366。我不会一直进行自动大小调整,因为当最后一列中的字符串没有到达控件的边缘时,它会导致控件的闪烁不佳。最好控件的列宽而不是闪烁。

Hi again, Charles, in your case it is perfectly well possible that CListCtrl takes its parameters in dialog units rather than device pixels. This might explain the difference (you will have noticed that the units used in the resource editor are not pixels, either). How to convert between dialog units and screen pixels, however, is one of the big MFC miracles yet unresolved for me.你好,我们又见面了,

Charles,在您的情况下,CListCtrl完全有可能
以对话框单位而不是设备像素的形式获取其参数。这可能解释了差异(您将注意到,资源编辑器中使用的单位也不是像素)。

但是,如何在对话框单位和屏幕像素之间进行转换是MFC的一大奇迹,但对我而言却尚未解决。

I have a similar problem, the font used by the window owning my popup menu is not the same font used by the popup menu, and WM_MEASUREITEM doesn't give me anything but a control id, using the window's device context for DrawTextExtent() measures it using the windows font, when what I need is for it to use the font specified in device context of the popup menu. The only solution I've found is to force the issue by selecting the same size font into both device contexts.我有一个类似的问题,拥有我的弹出菜单的窗口使用的字体与弹出菜单使用的字体不同,并且使用窗口的设备上下文作为DrawTextExtent()措施,WM_MEASUREITEM除了控件ID之外没有给我任何东西它使用Windows字体,当
我需要使用在弹出菜单的设备上下文中指定的字体时。我发现的唯一解决方案是通过在两个设备上下文中选择相同大小的字体来强制问题。

The most common reason for this type of problem is that you're using the wrong font. Before calling "GetTextExtent" you need to select the same font that the list control is using into your DC.这类问题的最常见原因是您使用了错误的字体。在调用“ GetTextExtent”之前,您需要选择
列表控件正在DC中使用的相同字体。

克里斯

I'm subclassing the control with the following (chopped down for posting): class HGDS_MsgView: public CListCtrl { public: HGDS_MsgView(); virtual ~HGDS_MsgView(); void add_msg(HGDS_Message *m); afx_msg void OnCustomDraw(NMHDR *pNMHDR, LRESULT *pResult); DECLARE_MESSAGE_MAP()我用以下方法将控件子类化(为发布而裁剪):

HGDS_MsgView类:public CListCtrl {
public:
HGDS_MsgView();
虚拟〜HGDS_MsgView();
void add_msg(HGDS_Message * m);
afx_msg void OnCustomDraw(NMHDR * pNMHDR,LRESULT * pResult);
DECLARE_MESSAGE_MAP()

Then in add_msg(HGDS_Message *m) I do: CDC *dc = GetDC(); size = dc->GetTextExtent(m->value()._string()); This should be the DC for the control, correct?然后在add_msg(HGDS_Message * m)中执行:

CDC * dc = GetDC();
大小= dc-> GetTextExtent(m-> value()._ string());

这应该是用于控制的DC,对吗?


Yes, but as Chris just said, you must select the correct font into the device context before calling GetTextExtent. The following should work, assuming your control is a child of a dialog box and uses the same font.是的,但是正如克里斯所说,您必须在调用GetTextExtent之前在设备上下文中选择正确的字体。 假设您的控件是对话框的子级并且使用相同的字体,那么下面的方法应该起作用。

CDC* pDC = GetDC(); CFont* pFont, pOldFont; CWnd* pParent = GetParent(); if(pDC && pParent) { pFont = pParent->GetFont(); if(pFont) { pOldFont = pDC->SelectObject(pFont); size = pDC->GetTextExtent(m->value()._string()); pDC->SelectObject(pOldFont); } } if(pDC) ReleaseDC(pDC);

No; incorrect. Calling "GetDC" on a control's window just gives you a normal DC for the control's window - it does NOT automatically place into that DC the font that the control is using. You need to create the font yourself and select it into the DC before calling "GetTextExtent". Chris没有; 不正确

在控件窗口上调用“ GetDC”只会为您提供该控件窗口的常规DC-它不会自动将控件所使用的字体放入该DC中。您需要自己创建字体并在调用“ GetTextExtent”之前将其选择到DC中。

克里斯

This fixed it, along with adding some pixels for buffer around the column separator. Thanks.修复了此问题,并在列分隔符周围添加了一些像素作为缓冲区。谢谢。

Quote: > >Then in add_msg(HGDS_Message *m) I do: > >CDC *dc = GetDC(); > >size = dc->GetTextExtent(m->value()._string()); > >This should be the DC for the control, correct? > Yes, but as Chris just said, you must select the correct font into the device context before calling GetTextExtent.调用GetTextExtent之前的设备上下文。

Quote: > The following should work, assuming your control is a child of a dialog box and uses the same font. 假设您的控件是对话框的子级,则以下内容应该起作用框并使用相同的字体。

Quote: > CDC* pDC = GetDC(); > CFont* pFont, pOldFont; > CWnd* pParent = GetParent(); > if(pDC && pParent) > { > pFont = pParent->GetFont(); > if(pFont) > { > pOldFont = pDC->SelectObject(pFont); > size = pDC->GetTextExtent(m->value()._string()); > pDC->SelectObject(pOldFont); > } > } > if(pDC) > ReleaseDC(pDC);

Correct font, that was my problem, I am using GetStockObject(DEFAULT_GUI_FONT) (close enough), know how to get the actual default font used for popup menus? Can't find a function that does the job. I don't want to override the default font, but I want WM_MEASUREITEM to work properly with GetTextExtent() in being consistant with WM_DRAWITEM.正确的字体,这就是我的问题,我正在使用 GetStockObject(DEFAULT_GUI_FONT)(足够接近),知道如何获取用于弹出菜单的实际默认字体吗?找不到执行此功能的函数 。我不想覆盖默认字体,但我希望
WM_MEASUREITEM与GetTextExtent()保持一致,以便与WM_DRAWITEM保持一致。

LONG dialogbaseunits = GetDialogBaseUnits();

pixelX = (dialogunitX * LOWORD(dialogbaseunits)) / 4

pixelY = (dialogunitY * HIWORD(dialogbaseunits)) / 8

or

dialogunitX = (pixelX * 4) / LOWORD(dialogbaseunits)

dialogunitY = (pixelY * 8) / HIWORD(dialogbaseunits)

Who needs MFC to do this anyway? ;-) -Dale谁仍然需要MFC来执行此操作?;-)

NONCLIENTMETRICS ncm;

ncm.cbSize = sizeof(NONCLIENTMETRICS);

SystemParametersInfo(SPI_GETNONCLIENTMETRICS, sizeof(NONCLIENTMETRICS), &ncm, 0);

AFter doing this, ncm.ldMenuFont will contain the font (as a LOGFONT) used to draw menus. You can then do this to use the font... hfont = CreateFontIndirect(&ncm.lfMenuFont);之后,ncm.ldMenuFont将包含用于绘制菜单的字体(作为LOGFONT)。然后,您可以执行此操作以使用字体...

hfont = CreateFontIndirect(&ncm.lfMenuFont);

友情链接
版权所有 Copyright(c)2004-2015 锐英源软件

公司注册号:410105000449586 豫ICP备08007559号 最佳分辨率 1024*768

地址:郑州市文化路47号院1号楼4层(47-1楼位于文化路和红专路十字路口东北角,郑州大学工学院招待所南边,工学院科技报告厅西边。)