使DrawText函数分行显示字符串

7

我可以使drawtext在字符串中有空格或者在字符串末尾加入\r\n时进行换行。然而,如果一个没有空格或者换行符的长字符串超出了绘制矩形,那么它将被剪切。如果可能的话,我想要避免这种情况发生。

在drawtext的格式标志中,没有任何能够解决这个问题的标志。你有什么想法吗?


有点简单:不要偷懒。 发布这个代码片段应该是零工作量的。 - Hans Passant
2
也许你没有理解这个问题?我不是在谈论一个现有的代码片段。我在询问如何使drawtext函数在文本中没有空格时,当它将要超出绘图矩形时换行。 - Gogeta70
2个回答

14

实际上,大多数情况下您需要的是来自MSDN的以下内容:

DT_EDITCONTROL

复制多行编辑控件的文本显示特性。特别地,平均字符宽度的计算方式与编辑控件相同,并且该函数不显示部分可见的最后一行。

它未提到的是,如果需要,它也会在单词中间打断,就像编辑控件一样。它确实有另外一个效果,即不显示部分可见的底部行,但在大多数用法中,我认为这并不重要,因为您可能会事先使用DT_CALCRECT来确保有足够的空间(如果没有,则不绘制部分可见的线条可能更好)。 如果真的很重要,您总是可以通过剪切等操作来处理,例如给DrawText一个更高的矩形,但已经在设备上下文中设置了较小的剪辑矩形。


我可以确认,DT_EDITCONTROLDT_WORDBREAK 一起使用时,无论空格如何都会换行,因此在我看来这是(最)正确的答案。 - SpeedFreak

5
您通常会使用DT_WORDBREAK标志。根据MSDN上的DrawText文档,它会自动在单词之间断开行,如果一个单词超出了lpRect参数指定的矩形边缘,则会自动换行。回车换行序列也会换行。
但是,您有单个不可分割的行 - 也就是说,没有单词。您需要自己处理换行。您可以通过两种方式解决这个问题:
使用带有DT_CALCRECTDrawText来计算矩形的大小-循环缩短字符串,直到找到第一行的字符串,然后重复处理剩余的字符串。也就是说,在绘图区域宽度内找到从索引0-n的子集;再次找到适合水平的n + 1-m字符串;重复此过程,直到到达字符串的末尾。将这些子字符串连接起来,每个之间用\r\n强制手动换行,然后使用DrawText进行绘制,它将正确地换行。
使用DrawTextEx并传入指向DRAWTEXTPARAMS结构的指针。它有一个uiLengthDrawn成员,它是“DrawTextEx处理的字符数,包括空格字符。该数字可以是字符串的长度或第一行落在绘图区域以下的索引。”您不应该传递DT_NOCLIP。这可能(未经测试)会为您提供与第一种方法相同的信息,而无需循环:使我不确定的关键部分是短语“在”绘图区域下方,并且如果您的行无法打断,则可能认为它已处理了整个文本。
第一种方法始终有效,是我自己用于富文本处理的简单版本。

谢谢,我想通了。^_^ - Gogeta70
2
我有一个COLORREF值的数组,用于存储字符串中每个字符的颜色。我遍历字符串并检查每个字符的颜色,直到找到一个与上一个字符颜色不同的字符或者字符串的宽度(GetTextExtentPoint32)超过了我想要绘制的区域的宽度,然后使用drawtext来绘制字符串。它非常好用 ^_^ - Gogeta70
似乎第二个过程不起作用。我没有使用DT_NOCLIP。我传递了以下格式:DT_NOPREFIX | DT_SINGLELINE。仍然无论何时uiLengthDrawn都接收整个字符串的长度,这一点毫无帮助。 - Atiq Rahman
我认为uiLengthDrawn只是用来通知您是否出现省略号而不是完整文本的。 - jnm2

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接