アフィリエイト広告を利用しています

広告

posted by fanblog

2024年08月22日

前回の記事の変更点です。

 こんにちは、皆さん。今日は、前回の「TextBox で作ったエディターの行番号について」の記事を、少し変更して見たいと思います。

 というのは、最後のコードの部分が、少し複雑になっているので、もう少し簡単にしたいと思います。といっても、本の少しなんですが(笑)。


 それと、新たな「WordPress サーバー」に関しては、ただ今検討中なので、もう暫く時間が掛かります。

 また、その後で「新たなテーマで作成」することになるので、勉強も重なるので時間が掛かります。

 まぁしかし、大凡の目処は立っているので、大丈夫です。



 以下が、そのコードです。


/// <summary>
/// 行番号を描画します。
/// </summary>
/// <param name="g">Graphics</param>
/// <param name="client">Rectangle</param>
protected virtual void DrawLineNumber(Graphics g, Rectangle client)
{
 // 画面上の最初の行を取得します。
 int firstVisibleLine = SendMessage(
  ScrollTextBox.Handle, EM_GETFIRSTVISIBLELINE, 0, 0);

 // 最初の行から、その行の最初の文字の Index を取得します。
 int firstVisibleIndex = ScrollTextBox
  .GetFirstCharIndexFromLine(firstVisibleLine);

 // その文字の Index から、見かけ上の行ではなく、実際の行を取得します。
 // (Wordwrap 対策として、SecondScrollTextBox を使います。)
 int reallyFirstVisibleLine = SecondScrollTextBox
  .GetLineFromCharIndex(firstVisibleIndex);

 // テキスト全体の最後の行を取得します。
 int totalLine = ScrollTextBox
  .GetLineFromCharIndex(ScrollTextBox.Text.Length);

 // 画面に表示するテキストの最大行数を計算します。
 int totalVisibleLines = totalLine - firstVisibleLine;

 // フォントの高さを取得します。
 // ただし、フォントの高さと、実際に表示される行高とは、異なって
 // いるので、FontScrollTextBox から、実際の高さを取得します。
 Point reallyLinePt = FontScrollTextBox
  .GetPositionFromCharIndex(7);

 // 空白行を作るために、一行前の実際の行数を取得します。
 // (WordWrap 対策です。)
 int beforeVisibleLine = firstVisibleLine;
 if (ScrollTextBox.WordWrap)
 {
  if (firstVisibleLine > 0)
  {
   int beforeVisibleIndex = ScrollTextBox
    .GetFirstCharIndexFromLine(firstVisibleLine - 1);
   beforeVisibleLine = SecondScrollTextBox
    .GetLineFromCharIndex(beforeVisibleIndex);
  }
  else
  {
   beforeVisibleLine = -1;
  }
 }
 beforeVisibleLine += 1;

 // 行番号を描画します。
 Font nmfont = NumberProperty.Font; // 行番号の Font。
 SolidBrush foreBrush = new SolidBrush(NumberProperty.ForeColor);

 // 行番号を作成します。
 for (int i = firstVisibleLine + 1, rowCnt = 0;
  i <= firstVisibleLine + totalVisibleLines + 1;
  i++, rowCnt++)
 {
  // 行番号を作成します。
  string st = "";
  if (ScrollTextBox.WordWrap)
  {
   // 画面上の行の最初の文字の Index を取得します。
   int dspFirstIndex = ScrollTextBox
    .GetFirstCharIndexFromLine(i - 1);

   // 実際の行を取得します(Wordwrap 無しとして)。
   int dspReallyFirstLine = SecondScrollTextBox
    .GetLineFromCharIndex(dspFirstIndex) + 1;

   if (i == 1 || dspReallyFirstLine != beforeVisibleLine)
   {
    st = dspReallyFirstLine.ToString().PadLeft(5, ' ') + "\r\n";
   }
   beforeVisibleLine = dspReallyFirstLine;
  }
  else
  {
   st = i.ToString().PadLeft(5, ' ') + "\r\n";
  }

  // 描画文字長を取得。
  SizeF stSz = g.MeasureString(st, nmfont);

  // 右寄せ位置を取得。
  PointF pt = new PointF(client.Width - stSz.Width - 10,
   reallyLinePt.Y * rowCnt + (reallyLinePt.Y - nmfont.Height) / 2);

  // 表示位置が、Client 領域を超えた時点で、終了します。
  if (pt.Y > client.Height)
  {
   break;
  }

  // 描画。
  g.DrawString(st, nmfont, foreBrush, pt);
 }
 foreBrush.Dispose();
}



 変更した点は、表示行数を計算するのではなく、表示位置が「Client.Height」を超えた時点で、表示を終了するようにしました。


 コードというのは基本的に、「計算数」や「変数の数」が少ない方が、プログラマー的には楽なので、速度差がそれ程なければ、その方が良いです。

 まぁしかし、前回のコードも経験則の一つとして、検討して見るというのも、一興かと思います(笑)。


 ということで、改良点やバグ等があれば、また報告したいと思います。それではこの辺で、ごきげんよう。



この記事へのコメント
コメントを書く

お名前:

メールアドレス:


ホームページアドレス:

コメント:

※ブログオーナーが承認したコメントのみ表示されます。

この記事へのトラックバックURL
https://fanblogs.jp/tb/12673518
※ブログオーナーが承認したトラックバックのみ表示されます。

この記事へのトラックバック
プロフィール
eimanapさんの画像
eimanap

  は、結構好きな色なんです。
は、流石に心が洗われますね。

プロフィール
<< 2024年10月 >>
    1 2 3 4 5
6 7 8 9 10 11 12
13 14 15 16 17 18 19
20 21 22 23 24 25 26
27 28 29 30 31    
最新記事
検索
写真ギャラリー
最新コメント
タグクラウド
カテゴリーアーカイブ
×

この広告は30日以上新しい記事の更新がないブログに表示されております。