Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Основная";
Текущий архив: 2006.04.09;
Скачать: [xml.tar.bz2];

Вниз

Раскраска 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;
Скачать: [xml.tar.bz2];

Наверх




Память: 0.48 MB
Время: 0.011 c
8-1131196465
Toxa_ua
2005-11-05 16:14
2006.04.09
Конус под углом - OpenGL


6-1135444189
FrykT
2005-12-24 20:09
2006.04.09
SSL + WinSock, как реализовать?


2-1143521263
Ezorcist
2006-03-28 08:47
2006.04.09
Вопрос по массивам


15-1142688836
TStas
2006-03-18 16:33
2006.04.09
РЕальная необходимость рекурсии


15-1142780184
Petr V. Abramov
2006-03-19 17:56
2006.04.09
Эти ребята достойны первого приза...





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский