Форум: "Основная";
Текущий архив: 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