2
ans:= RichEdit1.Text     
for i:=1 to Length(ans) do
begin
   RichEdit1.SelStart :=  i-1;
   RichEdit1.SelLength:= 1;
   if ans[i] = correct[i] then
      RichEdit1.SelAttributes.Color := clRed
   else
      RichEdit1.SelAttributes.Color := clBlue;  

ansの文字が string の文字と同じ位置にある文字と一致する場合correctは赤、そうでない場合は青になります。

私の問題は、もう一度入力すると、RichEdit1 テキスト全体が最初の文字と同じ色になることです (最初の文字RichEdit1が青色の場合、テキスト全体が青色になります)。

ところで、これは単純化した実際のコードではありません。複数の TRichEdit があるためです。
TRichEdits は読み取り専用で、次のような方法で文字を割り当てますRichEdit1.Text := RichEdit1.Text+Key; (これは複数のキーボード プログラムであり、ユーザー入力を分離する必要があるためです)。

これは正しい動作ですか?色の変更によってデフォルトの色が上書きされないようにするにはどうすればよいですか?

更新:解決しました...ずさんな方法で(誰かが入力するたびにデフォルトの色を適用します)、誰かがより良い解決策を思いついた場合に備えて、これを開いたままにしています。

4

1 に答える 1

5

すでに発見したように、完了したらデフォルトの色をリセットする必要があります。

ans := RichEdit1.Text;
for i := 1 to Length(ans) do 
begin 
  RichEdit1.SelStart := i-1; 
  RichEdit1.SelLength := 1; 
  if ans[i] = correct[i] then 
    RichEdit1.SelAttributes.Color := clRed 
  else 
    RichEdit1.SelAttributes.Color := clBlue;
end;
RichEdit1.SelStart := RichEdit1.GetTextLen;
RichEdit1.SelLength := 0;
RichEdit1.SelAttributes.Color := RichEdit1.Font.Color;

これを処理するには、一度に 1 文字ずつ色を付けるよりも効率的な方法があります。たとえば、次のようになります。

const
  colors: array[Boolean] of TColor = (clRed, clBlue);
var
  ans: string;
  start, len: Integer;
  cur_state: Boolean;

  procedure ColorRange(AStart, ALength: Integer; AColor: TColor);
  begin
    RichEdit1.SelStart := AStart;
    RichEdit1.SelLength := ALength;
    RichEdit1.SelAttributes.Color := AColor;
  end;

begin
  RichEdit1.Lines.BeginUpdate;
  try
    ans := RichEdit1.Text;
    start := 0;
    len := 0;
    cur_start := False;

    for i := 1 to Length(ans) do 
    begin 
      if (ans[i] = correct[i]) = cur_state then
        Inc(len)
      else begin
        if len > 0 then
          ColorRange(start, len, colors[cur_state]);
        start := i-1;
        len := 1;
        cur_state := not cur_state;
      end;
    end;
    if len > 0 then
      ColorRange(start, len, colors[cur_state]);
    ColorRange(RichEdit1.GetTextLen, 0, RichEdit1.Font.Color);
  finally
    RichEdit1.Lines.EndUpdate;
  end;
end;

また、Text プロパティを使用して単一の Char を追加するのは非常に非効率的です。代わりに SelText プロパティを使用してください。

RichEdit1.SelStart := RichEdit1.GetTextLen;
RichEdit1.SelLength := 0;
RichEdit1.SelAttributes.Color := ...; // optional
RichEdit1.SelText := Key;
于 2010-09-24T06:08:45.613 に答える