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 に答える