1

我正在尝试使用该SetTextJustification功能,但它没有按预期工作。

如果我将 nBreakExtra 的参数值设置为 40 或 10 输出是相同的,这是为什么呢?

这是我的代码:

      private void button1_Click(object sender, EventArgs e)
      {
          IntPtr hdc = richTextBox1.CreateGraphics().GetHdc();
          string str = "aaa bbb ccc ddd eee fff";
          SetTextJustification(hdc, 40, 5);
          TextOut(hdc, 20, 20, str, str.Length);
          SetTextJustification(hdc, 10, 5);
          TextOut(hdc, 20, 50, str, str.Length);
      }

      [DllImport("gdi32.dll")]
      static extern bool SetTextJustification(IntPtr hdc, int nBreakExtra, int nBreakCount);

      [DllImport("gdi32.dll", CharSet = CharSet.Auto)]
      static extern bool TextOut(IntPtr hdc, int nXStart, int nYStart, string lpString, int cbString);

输出显示为: 在此处输入图像描述

4

1 回答 1

1

您的代码似乎工作正常。这是我的测试的屏幕截图:

显示代码结果的测试表格

我不确定为什么你的结果不同。

也许我可以提供这个作为替代解决方案:我已经编写了自己的证明方法:

public void PaintTextJustification(Graphics g, string text, Font font, PointF location, int lineWidth, bool applyToLastLine)
{
  string[] words = text.Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);

  int wordCount = 0;
  float locY = location.Y;

  while (wordCount < words.Length)
  {
    StringBuilder rawLine = new StringBuilder();
    List<string> lineParts = new List<string>();

    while ((wordCount < words.Length) && (g.MeasureString(rawLine.ToString() + words[wordCount], font).Width < (float)lineWidth))
    {
      rawLine.Append(words[wordCount] + " ");
      lineParts.Add(words[wordCount] + " ");
      wordCount++;
    }
    string rawLineStr = rawLine.ToString().Trim();

    float padding = 0;
    if ((wordCount < words.Length) || (applyToLastLine))
    {
      // Only apply padding if not the last line.
      padding = ((float)lineWidth - g.MeasureString(rawLineStr, font).Width) / (lineParts.Count - 1);
    }

    float locX = location.X;
    foreach (string word in lineParts)
    {
      g.DrawString(word, font, Brushes.Black, new PointF(locX, locY));
      locX += g.MeasureString(word, font).Width + padding;
    }

    locY += g.MeasureString(rawLineStr, font).Height;
  }
}

使用这种新方法,您可以选择字体并指定行的总长度,它还允许您更大的灵活性和自定义(例如,合并一个标志,指示最后一行是否应该对齐)。您还可以通过将字体颜色作为方法参数进一步自定义该方法。

现在可以使用该方法,如下面的按钮事件方法所示(注意该事件处理方法的第一位包括用于测试原始解决方案的代码):

private void EditButton_Click(object sender, EventArgs e)
{
  IntPtr hdc = richTextBox1.CreateGraphics().GetHdc();
  string str = "aaa bbb ccc ddd eee fff";

  SetTextJustification(hdc, 40, 5);
  TextOut(hdc, 20, 20, str, str.Length);

  SetTextJustification(hdc, 10, 5);
  TextOut(hdc, 20, 40, str, str.Length);

  // Another Approach:
  Graphics g = richTextBox1.CreateGraphics();
  PaintTextJustification(g, str, richTextBox1.Font, new PointF(20f, 90f), 220, true);

  System.Drawing.Font newFont = new Font("Arial", 12f, FontStyle.Bold);
  string longStr = "This is a very long string which will need to be split across several lines when it is justified.";
  PaintTextJustification(g, longStr, newFont, new PointF(20f, 110f), 220, false);
}

这是显示这两种方法的结果的屏幕截图:

在此处输入图像描述

无论如何,我希望这会有所帮助。

于 2012-10-20T21:01:14.747 回答