TEditorで文字列が欠損しないように文字列を描画するには


risa  2016-11-20 08:19:53  No: 48418

※文字化けが発生したのでスマホからもう一度同じ内容で投稿します。

  いつもお世話になります。1点質問させてください。

  現在、Windows 7 Pro + Delphi 6 Personalで、TEditorという有名なエディタ
コンポーネントを使用したプログラムを作成しています。ここで、検索文字列を
強調表示させるべく、以下に類するようなコードを書いたのですが、強調した文
字列の最後が半角スペースであるときだけ、描画領域が勝手に1ピクセル分右に
膨らんでしまい、右隣の文字の一部が欠損してしまいます。

  描画領域を勝手に膨らまないようにするには、どうしたらよいでしょうか。
ご教示のほど、よろしくお願いいたします。

1  再現コード
  ・Editor1(TEditor)をフォームに貼り付け、フォントを10ポイントの
    MSゴシックにします。
  ・Editor1に文字列を2行以上入力し、OnDrawLineイベントに以下のコード
    を記述します。

↓ここから
procedure TForm1.Editor1DrawLine(Sender: TObject; LineStr: String; X, Y,
  Index: Integer; ARect: TRect; Selected: Boolean);
begin
  Editor1.Canvas.Font.Name := 'MS ゴシック';
  Editor1.Canvas.Font.Size := 10;
  Editor1.Canvas.Font.Style := [fsBold];
  Editor1.Canvas.Font.Color := clRed;
  Editor1.Canvas.Brush.Color := clYellow;
  if Index = 0 then Editor1.DrawTextRect(ARect, X, Y, '111', ETO_CLIPPED);
  if Index = 1 then Editor1.DrawTextRect(ARect, X, Y, '22 ', ETO_CLIPPED);
end;
↑ここまで

2  具体的な実行結果(画像)
    http://www.fastpic.jp/images.php?file=1262269390.png
    (2列目のbという文字が一部欠損しているのがわかるかと思います。)


risa  2016-11-20 08:27:15  No: 48419

なんとかうまくかけたようです。管理者様、大変ご迷惑をおかけしますが、文字化けした3つのスレッドについて、削除をお願いできますでしょうか。お手間をおかけいたしますが、何卒宜しくお願い致します。
皆様にはお見苦しいスレッドをお見せしてしまい申し訳ありません。お詫びいたします。

※参考までに、当方ではwin7と最新のie,firefoxを使用しているのですが、いずれでも入力できませんでした。一時的な不具合か何かでしょうか?
この掲示板はdelphiを使用する者にとっては貴重な意見交換の場です。度々のお願いで恐縮でございますが、お時間のある時などに、ご確認をお願いできれば幸いです。


risa  2016-11-20 08:36:26  No: 48420

参考までに、teditorのソースを見ると、
内部ではextTextOutというapiを呼んでいるようでした。
なぜか強調文字列が半角スペースで終わる時だけ、勝手に描画領域が膨らみます。


risa  2016-11-20 09:00:00  No: 48422

ツ暗ェツ可楪づ「ツづ・づ・づ敖づ慊つオツつスツつェツ、firefoxツづ個づ・つォツづ債つセツづ淞づ・つオツつスツ。
ツブツδ可ウツザツづ・づ債、ツシツフツトツジツスツづ・認ツ篠ッツつオツづ・つ「ツづ慊つオツつスツ。
ツタツイツトツδ仰閉板閉ェツづ債青ウツ湘ュツづ可表ツ篠ヲツつウツづェツづ慊つオツつスツつェツ、ツ本ツ閉カツづ債つセツづ淞づ・つオツつスツ。


Mr.XRAY  2016-11-20 21:44:40  No: 48421

投稿文章の文字化けなのですが,
一度メモ帳等に文章を書いてから,それをコピーして投稿欄に貼り付けた場合はどうなるでしょう.


risa  2016-11-21 00:34:41  No: 48423

一度、そのようにしたのですがうまく行きませんでした。


risa  2016-11-21 06:58:34  No: 48424

いろいろと試行錯誤していた結果、以下のようなサンプルコードを作成できました。
Editor1のフォントを10ポイントのMSゴシックにして、文字列を3行程度設定して以下のコードを実行すると、
画像のような問題を再現できます。ここで、コメントの部分を修正すると、いろいろ
と文字間のピッチを修正できるようですが、もともとColWidthは固定の数値であるた
め、なぜこのような問題が起こったのか、特定できておりません。

procedure TForm1.Editor1DrawLine(Sender: TObject; LineStr: String; X, Y,
  Index: Integer; ARect: TRect; Selected: Boolean);
var
  R: TRect;
  i: Integer;
  A: array [0..1000] of Integer;
begin
  R := ARect;
  Editor1.Canvas.Font.Name := 'MS ゴシック';
  Editor1.Canvas.Font.Size := 10;
  Editor1.Canvas.Font.Color := clRed;
  Editor1.Canvas.Brush.Color := clYellow;
   // ↓ここを直すとピッチが修正できる様子だが、直し方が分からない。
  for i := 0 to 1000 do A[i] := Editor1.ColWidth;
  if Index = 0 then begin
    Editor1.Canvas.Font.Style := [fsBold];
    Windows.ExtTextOut(Editor1.Canvas.Handle, X, Y, ETO_CLIPPED, @R, PChar('begin '), 6, PInteger(@A));
  end;
  if Index = 1 then begin
    Canvas.Font.Style := [];
    Windows.ExtTextOut(Editor1.Canvas.Handle, X, Y, ETO_CLIPPED, @R, PChar('begine'), 6, PInteger(@A));
  end;
end;


KON  2016-11-21 08:31:10  No: 48425

KONです。

私は、TEditorを使った事が無いので判りませんが、
その関数でブレークポイントを張り、スペースが有る場合と無い場合とでは
引数のARectの幅に変化はありますか?


Nov  2016-11-21 09:03:20  No: 48426

フォントやフォントスタイルを変更したら、文字幅は変化すると思います。
したがって、スペースのときに文字が欠けるのではなく、スペースでない
ときは文字が(偶然)再描画領域にかからないだけと思われます。

例えば、単純にBoldにしたら、1dot横幅が増えるのではないでしょうか。

スタイルを変更しない文字も描画したほうが良いです。
※TextWidthでは、複雑な修飾の文字幅は計算できません、たぶん。


Mr.XRAY  2016-11-21 17:14:33  No: 48427

余計なお世話かも知れませんが,投稿文章の文字化けの件ですが.
私も原因はよく分かりません.対処方法も分かりませんが参考になれば.
そのままだと,他にも影響があるかも知れません.

http://mrxray.on.coocan.jp/bbs/DelphiBBS/mrxray_delphifan_coffe.cgi?tree=s10542


risa  2016-12-03 07:56:18  No: 48428

お返事が遅れ、申し訳ありません。
結局、いろいろと試行錯誤してみたのですが、やはり問題が解決しませんでした。
そのため、背景と文字列を別々に描画する同等の関数を作って対応しました。
この問題は、TEditorを採用している他のエディタでも多く発生していたので、
TEditorの関数の仕様なのでしょう。スペースは標準では描画の対象になりませんので。


※返信する前に利用規約をご確認ください。

※Google reCAPTCHA認証からCloudflare Turnstile認証へ変更しました。






  このエントリーをはてなブックマークに追加