Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2006.04.09;
Скачать: CL | DM;

Вниз

Раскраска TRichEdit a   Найти похожие ветки 

 
ircnoob   (2006-03-04 12:20) [0]

В общем, пишу свой жутко простенький IRC-чат. Решил разобраться со стилями шрифта / цветом в главном окне вывода информации на базе TRichEdit"a.

Не долга думаю написал вполне прозрачный код организующий подсветки при добавлении новой линии в чат. Но столкнулся с проблемой. Первые несколько "линий" добавляются нормально, а потом все это дело начинает жутко скакать. Протрейсил и пришел  к выводу, что у TRichEdit"a не понятно откуда как и зачем в некоторых ситуациях возникают символы переноса строки и влияют на пересчет относительных координат начала подсветки.

У кого есть немного времени и желание помочь мне разобраться в проблеме? )

type
 TIRCTextAttribCode = (taColor, taBold, taUnderline);

 TStyleQuote = record
  StartPos: Integer;
  EndPos: Integer;
  Color: TColor;
 end;

 TSQArray = array of TStyleQuote;

const
 AttribCodes: array [TIRCTextAttribCode] of Char =
  (
    #3, // Color
    #2, // Bold
    #31 // Underline
  );

procedure TVisualChannel.AddIRCLine(const AText: String);
var
PB: Integer;
ALine: String;
i: Integer;
//--
SQArrayC: TSQArray; SQArrayCC: Integer; IsOpenedC: Boolean;
SQArrayB: TSQArray; SQArrayBC: Integer; IsOpenedB: Boolean;
SQArrayU: TSQArray; SQArrayUC: Integer; IsOpenedU: Boolean;
SColor: String;
begin
// добавляем время в формате "[hh:mm:ss] "+AText
ALine:=AddTimeStamp(AText);
PB:=0;
for i:=0 to FFrame.edIRCChat.Lines.Count-1 do
 PB:=PB+Length(FFrame.edIRCChat.Lines[i]);

i:=1;
IsOpenedC:=False; SQArrayCC:=0;
IsOpenedB:=False; SQArrayBC:=0;
IsOpenedU:=False; SQArrayUC:=0;
while i<>Length(ALine) do
begin
 if ALine[i]=AttribCodes[taBold] then
 begin
  if IsOpenedB then
  begin
   IsOpenedB:=False;
   Delete(ALine,i,1);
   SQArrayB[High(SQArrayB)].EndPos:=i+PB-1;
  end else
  begin
   IsOpenedB:=True;
   Inc(SQArrayBC);
   SetLength(SQArrayB,SQArrayBC);
   Delete(ALine,i,1);
   SQArrayB[High(SQArrayB)].StartPos:=i+PB;
  end;
 end;
 if ALine[i]=AttribCodes[taUnderline] then
 begin
  if IsOpenedU then
  begin
   IsOpenedU:=False;
   Delete(ALine,i,1);
   SQArrayU[High(SQArrayU)].EndPos:=i+PB-1;
  end else
  begin
   IsOpenedU:=True;
   Inc(SQArrayUC);
   SetLength(SQArrayU,SQArrayUC);
   Delete(ALine,i,1);
   SQArrayU[High(SQArrayU)].StartPos:=i+PB;
  end;
 end;
 if ALine[i]=AttribCodes[taColor] then
 begin
  if IsOpenedC then
  begin
   IsOpenedC:=False;
   Delete(ALine,i,3);
   SQArrayC[High(SQArrayC)].EndPos:=i+PB-1;
  end else
  begin
   IsOpenedC:=True;
   Inc(SQArrayCC);
   SetLength(SQArrayC,SQArrayCC);
   SColor:=Copy(ALine,i+1,2);
   if SColor="00" then SQArrayC[High(SQArrayC)].Color:=clWhite;
   if SColor="01" then SQArrayC[High(SQArrayC)].Color:=clBlack;
   if SColor="02" then SQArrayC[High(SQArrayC)].Color:=clNavy;
   if SColor="03" then SQArrayC[High(SQArrayC)].Color:=clRed;
   if SColor="04" then SQArrayC[High(SQArrayC)].Color:=clMaroon;  // brown
   if SColor="05" then SQArrayC[High(SQArrayC)].Color:=clPurple;
   if SColor="06" then SQArrayC[High(SQArrayC)].Color:=clYellow;  // orange
   if SColor="07" then SQArrayC[High(SQArrayC)].Color:=clYellow;
   if SColor="08" then SQArrayC[High(SQArrayC)].Color:=clLime;
   if SColor="10" then SQArrayC[High(SQArrayC)].Color:=clTeal;
   if SColor="11" then SQArrayC[High(SQArrayC)].Color:=clAqua;
   if SColor="12" then SQArrayC[High(SQArrayC)].Color:=clBlue;
   if SColor="13" then SQArrayC[High(SQArrayC)].Color:=clFuchsia;
   if SColor="14" then SQArrayC[High(SQArrayC)].Color:=clGray;
   if SColor="15" then SQArrayC[High(SQArrayC)].Color:=clSilver;
   Delete(ALine,i,3);
   SQArrayC[High(SQArrayC)].StartPos:=i+PB;
  end;
 end;
 Inc(i);
end;

edIRCChat.Lines.Add(ALine);

for i:=Low(SQArrayC) to High(SQArrayC) do
begin
 edIRCChat.SelStart:=SQArrayC[i].StartPos;
 edIRCChat.SelLength:=SQArrayC[i].EndPos-SQArrayC[i].StartPos;
 edIRCChat.SelAttributes.Color:=SQArrayC[i].Color;
end;
for i:=Low(SQArrayB) to High(SQArrayB) do
begin
 edIRCChat.SelStart:=SQArrayB[i].StartPos;
 edIRCChat.SelLength:=SQArrayB[i].EndPos-SQArrayB[i].StartPos;
 edIRCChat.SelAttributes.Style:=edIRCChat.SelAttributes.Style+[fsBold];
end;
for i:=Low(SQArrayU) to High(SQArrayU) do
begin
 edIRCChat.SelStart:=SQArrayU[i].StartPos;
 edIRCChat.SelLength:=SQArrayU[i].EndPos-SQArrayU[i].StartPos;
 edIRCChat.SelAttributes.Style:=edIRCChat.SelAttributes.Style+[fsUnderline];
end;

SetLength(SQArrayC,0);
SetLength(SQArrayB,0);
SetLength(SQArrayU,0);

edIRCChat.SelStart:=Length(edIRCChat.Lines.Text);
edIRCChat.SelLength:=0;
end;


Заранее спасибо, если кто найдется желающий помочь )


 
begin...end ©   (2006-03-04 12:52) [1]

> ircnoob   (04.03.06 12:20)

> PB:=0;
> for i:=0 to FFrame.edIRCChat.Lines.Count-1 do
>  PB:=PB+Length(FFrame.edIRCChat.Lines[i]);

PB := edIRCChat.GetTextLen

> Delete(ALine,i,1);
> ...
> Inc(i);

А тут ошибка. Удаляется символ атрибута, на его место перемещается следующий за ним, и этот следующий символ не проверяется.


 
ircnoob   (2006-03-04 18:46) [2]

большое спасибо. я тысячу раз проше прощение, что возможно пользуюсь ситуацией, но мну клинит ( я запутался. понял свою ошибку, связанную с непроверкой текущего символа в случае удаления, исправился, но ситуация выглядит просто ужасно +(

procedure TVisualChannel.AddIRCLine(const AText: String);
var
PB: Integer;
ALine: String;
i: Integer;
//--
SQArrayC: TSQArray; SQArrayCC: Integer; IsOpenedC: Boolean;
SQArrayB: TSQArray; SQArrayBC: Integer; IsOpenedB: Boolean;
SQArrayU: TSQArray; SQArrayUC: Integer; IsOpenedU: Boolean;
SColor: String;
begin
ALine:=AddTimeStamp(AText);
PB:=FFrame.edIRCEdit.GetTextLen;

i:=1;
IsOpenedC:=False; SQArrayCC:=0;
IsOpenedB:=False; SQArrayBC:=0;
IsOpenedU:=False; SQArrayUC:=0;
while i<>Length(ALine) do
begin
 if ALine[i]=AttribCodes[taBold] then
 begin
  if IsOpenedB then
  begin
   IsOpenedB:=False;
   Delete(ALine,i,1);
   SQArrayB[High(SQArrayB)].EndPos:=i+PB-1;
  end else
  begin
   IsOpenedB:=True;
   Inc(SQArrayBC);
   SetLength(SQArrayB,SQArrayBC);
   Delete(ALine,i,1);
   SQArrayB[High(SQArrayB)].StartPos:=i+PB;
  end;
 end else
 if ALine[i]=AttribCodes[taUnderline] then
 begin
  if IsOpenedU then
  begin
   IsOpenedU:=False;
   Delete(ALine,i,1);
   SQArrayU[High(SQArrayU)].EndPos:=i+PB-1;
  end else
  begin
   IsOpenedU:=True;
   Inc(SQArrayUC);
   SetLength(SQArrayU,SQArrayUC);
   Delete(ALine,i,1);
   SQArrayU[High(SQArrayU)].StartPos:=i+PB;
  end;
 end else
 if ALine[i]=AttribCodes[taColor] then
 begin
  if IsOpenedC then
  begin
   IsOpenedC:=False;
   Delete(ALine,i,3);
   SQArrayC[High(SQArrayC)].EndPos:=i+PB-1;
  end else
  begin
   IsOpenedC:=True;
   Inc(SQArrayCC);
   SetLength(SQArrayC,SQArrayCC);
   SColor:=Copy(ALine,i+1,2);
   if SColor="00" then SQArrayC[High(SQArrayC)].Color:=clWhite;
   if SColor="01" then SQArrayC[High(SQArrayC)].Color:=clBlack;
   if SColor="02" then SQArrayC[High(SQArrayC)].Color:=clNavy;
   if SColor="03" then SQArrayC[High(SQArrayC)].Color:=clRed;
   if SColor="04" then SQArrayC[High(SQArrayC)].Color:=clMaroon;  // brown
   if SColor="05" then SQArrayC[High(SQArrayC)].Color:=clPurple;
   if SColor="06" then SQArrayC[High(SQArrayC)].Color:=clYellow;  // orange
   if SColor="07" then SQArrayC[High(SQArrayC)].Color:=clYellow;
   if SColor="08" then SQArrayC[High(SQArrayC)].Color:=clLime;
   if SColor="10" then SQArrayC[High(SQArrayC)].Color:=clTeal;
   if SColor="11" then SQArrayC[High(SQArrayC)].Color:=clAqua;
   if SColor="12" then SQArrayC[High(SQArrayC)].Color:=clBlue;
   if SColor="13" then SQArrayC[High(SQArrayC)].Color:=clFuchsia;
   if SColor="14" then SQArrayC[High(SQArrayC)].Color:=clGray;
   if SColor="15" then SQArrayC[High(SQArrayC)].Color:=clSilver;
   Delete(ALine,i,3);
   SQArrayC[High(SQArrayC)].StartPos:=i+PB;
  end;
 end else
  Inc(i);
end;

FFrame.edIRCChat.Lines.Add(ALine);

{ Highlight Tab }
if not FTabItem.Checked then Highlight:=True;

for i:=Low(SQArrayC) to High(SQArrayC) do
begin
 FFrame.edIRCChat.SelStart:=SQArrayC[i].StartPos;
 FFrame.edIRCChat.SelLength:=SQArrayC[i].EndPos-SQArrayC[i].StartPos;
 FFrame.edIRCChat.SelAttributes.Color:=SQArrayC[i].Color;
end;
for i:=Low(SQArrayB) to High(SQArrayB) do
begin
 FFrame.edIRCChat.SelStart:=SQArrayB[i].StartPos;
 FFrame.edIRCChat.SelLength:=SQArrayB[i].EndPos-SQArrayB[i].StartPos;
 FFrame.edIRCChat.SelAttributes.Style:=FFrame.edIRCChat.SelAttributes.Style+[fsBold];
end;
for i:=Low(SQArrayU) to High(SQArrayU) do
begin
 FFrame.edIRCChat.SelStart:=SQArrayU[i].StartPos;
 FFrame.edIRCChat.SelLength:=SQArrayU[i].EndPos-SQArrayU[i].StartPos;
 FFrame.edIRCChat.SelAttributes.Style:=FFrame.edIRCChat.SelAttributes.Style+[fsUnderline];
end;
SetLength(SQArrayC,0);
SetLength(SQArrayB,0);
SetLength(SQArrayU,0);

FFrame.edIRCChat.SelStart:=FFrame.edIRCChat.GetTextLen;
FFrame.edIRCChat.SelLength:=0;
end;


з.ы. вроде все должно быть пучком (


 
ircnoob   (2006-03-04 18:49) [3]

забыл по глупости выделить измененные моменты. простите:

procedure TVisualChannel.AddIRCLine(const AText: String);
var
PB: Integer;
ALine: String;
i: Integer;
//--
SQArrayC: TSQArray; SQArrayCC: Integer; IsOpenedC: Boolean;
SQArrayB: TSQArray; SQArrayBC: Integer; IsOpenedB: Boolean;
SQArrayU: TSQArray; SQArrayUC: Integer; IsOpenedU: Boolean;
SColor: String;
begin
ALine:=AddTimeStamp(AText);
PB:=FFrame.edIRCEdit.GetTextLen;

i:=1;
IsOpenedC:=False; SQArrayCC:=0;
IsOpenedB:=False; SQArrayBC:=0;
IsOpenedU:=False; SQArrayUC:=0;
while i<>Length(ALine) do
begin
 if ALine[i]=AttribCodes[taBold] then
 begin
  if IsOpenedB then
  begin
   IsOpenedB:=False;
   Delete(ALine,i,1);
   SQArrayB[High(SQArrayB)].EndPos:=i+PB;
  end else
  begin
   IsOpenedB:=True;
   Inc(SQArrayBC);
   SetLength(SQArrayB,SQArrayBC);
   Delete(ALine,i,1);
   SQArrayB[High(SQArrayB)].StartPos:=i+PB;
  end;
 end else
 if ALine[i]=AttribCodes[taUnderline] then
 begin
  if IsOpenedU then
  begin
   IsOpenedU:=False;
   Delete(ALine,i,1);
   SQArrayU[High(SQArrayU)].EndPos:=i+PB;
  end else
  begin
   IsOpenedU:=True;
   Inc(SQArrayUC);
   SetLength(SQArrayU,SQArrayUC);
   Delete(ALine,i,1);
   SQArrayU[High(SQArrayU)].StartPos:=i+PB;
  end;
 end else
 if ALine[i]=AttribCodes[taColor] then
 begin
  if IsOpenedC then
  begin
   IsOpenedC:=False;
   Delete(ALine,i,3);
   SQArrayC[High(SQArrayC)].EndPos:=i+PB;
  end else
  begin
   IsOpenedC:=True;
   Inc(SQArrayCC);
   SetLength(SQArrayC,SQArrayCC);
   SColor:=Copy(ALine,i+1,2);
   if SColor="00" then SQArrayC[High(SQArrayC)].Color:=clWhite;
   if SColor="01" then SQArrayC[High(SQArrayC)].Color:=clBlack;
   if SColor="02" then SQArrayC[High(SQArrayC)].Color:=clNavy;
   if SColor="03" then SQArrayC[High(SQArrayC)].Color:=clRed;
   if SColor="04" then SQArrayC[High(SQArrayC)].Color:=clMaroon;  // brown
   if SColor="05" then SQArrayC[High(SQArrayC)].Color:=clPurple;
   if SColor="06" then SQArrayC[High(SQArrayC)].Color:=clYellow;  // orange
   if SColor="07" then SQArrayC[High(SQArrayC)].Color:=clYellow;
   if SColor="08" then SQArrayC[High(SQArrayC)].Color:=clLime;
   if SColor="10" then SQArrayC[High(SQArrayC)].Color:=clTeal;
   if SColor="11" then SQArrayC[High(SQArrayC)].Color:=clAqua;
   if SColor="12" then SQArrayC[High(SQArrayC)].Color:=clBlue;
   if SColor="13" then SQArrayC[High(SQArrayC)].Color:=clFuchsia;
   if SColor="14" then SQArrayC[High(SQArrayC)].Color:=clGray;
   if SColor="15" then SQArrayC[High(SQArrayC)].Color:=clSilver;
   Delete(ALine,i,3);
   SQArrayC[High(SQArrayC)].StartPos:=i+PB;
  end;
 end else
  Inc(i);
end;

FFrame.edIRCChat.Lines.Add(ALine);

{ Highlight Tab }
if not FTabItem.Checked then Highlight:=True;

for i:=Low(SQArrayC) to High(SQArrayC) do
begin
 FFrame.edIRCChat.SelStart:=SQArrayC[i].StartPos;
 FFrame.edIRCChat.SelLength:=SQArrayC[i].EndPos-SQArrayC[i].StartPos;
 FFrame.edIRCChat.SelAttributes.Color:=SQArrayC[i].Color;
end;
for i:=Low(SQArrayB) to High(SQArrayB) do
begin
 FFrame.edIRCChat.SelStart:=SQArrayB[i].StartPos;
 FFrame.edIRCChat.SelLength:=SQArrayB[i].EndPos-SQArrayB[i].StartPos;
 FFrame.edIRCChat.SelAttributes.Style:=FFrame.edIRCChat.SelAttributes.Style+[fsBold];
end;
for i:=Low(SQArrayU) to High(SQArrayU) do
begin
 FFrame.edIRCChat.SelStart:=SQArrayU[i].StartPos;
 FFrame.edIRCChat.SelLength:=SQArrayU[i].EndPos-SQArrayU[i].StartPos;
 FFrame.edIRCChat.SelAttributes.Style:=FFrame.edIRCChat.SelAttributes.Style+[fsUnderline];
end;
SetLength(SQArrayC,0);
SetLength(SQArrayB,0);
SetLength(SQArrayU,0);

FFrame.edIRCChat.SelStart:=FFrame.edIRCChat.GetTextLen;
FFrame.edIRCChat.SelLength:=0;
end;


 
ircnoob   (2006-03-04 19:09) [4]

PB := edIRCChat.GetTextLen

всегда возвращает 0, в отличии от моего предыдущего варианта. вот в чем трабла -) но вопрос остается открытым. если это можно назвать вопросом )


 
ircnoob   (2006-03-05 10:24) [5]

слушайте, я запутался ( посоветуйте что-нить толковое, а?...



Страницы: 1 вся ветка

Текущий архив: 2006.04.09;
Скачать: CL | DM;

Наверх




Память: 0.5 MB
Время: 0.03 c
4-1137674039
shalex
2006-01-19 15:33
2006.04.09
Как узнать установлены ли принтеры в системе?


3-1139644942
John_Doe
2006-02-11 11:02
2006.04.09
Взять из таблицы записи со значениями из комбобокса.


2-1143458793
LionMen
2006-03-27 15:26
2006.04.09
Срочно!!!!


2-1143180082
konstvd
2006-03-24 09:01
2006.04.09
Как вставить лист из шаблона в документ word с форматированием?


2-1143395595
Slash.
2006-03-26 21:53
2006.04.09
установка компонентов