Доброго времени суток....
//Warning!!! Предыстория будет большая.... =)
// Вопрос — в самом конце...
Пишу класс TMatrix для задуманной математической коллекции.(Delphi .NET)
Собственно проблем со всякими
class operator Add(a,b:TMatrix):TMatrix;
class operator LogicalNot(a:TMatrix):TMatrix;
нету...
НО! Дальше возникает естественная идея сделать поудобнее
class operator Explicit(a:TMatrix):TStringList;
class operator TMatrix.Explicit(a: TMatrix): TStringList;
Var i,j:integer;tmp:TStringList;s,pr:string;
begin//****************преобразование Матрицы к типу TString*************************
// Переменные:
// i,j - цикл по строкам и столбцам
// tmp - временный экземпляр класса TStringList для хранения результата
// s - строка в которой формируется строка, добавляемая к конечному резльтату
// pr - строка, в которой будет сформирован формат точности вывода
//******************************************************************************
tmp:=TStringList.Create;tmp.Clear;
if a.Precision>0
then
begin
pr:='.';For i:=1 to a.Precision do pr:=pr+'0';
end
else pr:='';
if a.Precision=0 then pr:='0.';
tmp.Add('!MATRIX!');
for i := 0 to a.RowCount - 1 do
begin
s:=''#230;
for j := 0 to a.ColCount - 1 do
begin
s:=s+'['+a.values[i,j].ToString(pr)+'] ';
end;
tmp.Add(s);
end;
tmp.Add('~MATRIX~');
result:=tmp;
tmp.Free;
end;
всё рисуется нормально.
Думаю: "Неплохо было бы скобки по бокам матрицы выводить".
Как нарисовать скобки? В шифрте Symbol есть символ #230, но весь текст рисовать Sysbol'ом — не очень хочется...
//Завязка кончилась — начались грабли
RichEdit умеет (УМЕЛ)
RichEdit1.SelAttributes.Name:='Symbol'
для выделенного участка текста делать...
// tmp.Add('!MATRIX!'); и было введено для индикации начала матрицы...
Ищу начало:
procedure TForm1.Button3Click(Sender: TObject);
var
fnd : integer;
begin
fnd := -1;
repeat
fnd := RichEdit1.FindText('!MATRIX!', fnd+1, Length(RichEdit1.Text), []);
if fnd > -1 then
begin
RichEdit1.SelStart := fnd;
RichEdit1.SelLength := Length('!MATRIX!');
RichEdit1.SelAttributes.Color := clRed;
end;
until fnd = -1;
end;
FindText возвращает -1 (то есть "нету такой строчки")
После такого пространнственного объяснения ситуации —
простейший вопрос "ПОЧЕМУ?"
1. попробуйте заменить fnd := RichEdit1.FindText('!MATRIX!', fnd+1, Length(RichEdit1.Text), []);
на fnd := RichEdit1.FindText('!MATRIX!', fnd+1, Length(RichEdit1.Lines.Text), [stMatchCase]);
Должно работать
2. Зачем изобретать велосипед??
Если заглянуть в реализацию TCustomRichEdit.FindText,то можно увидеть то же самое,то есть что поиск реализован с помощью
SendMessage(Handle, EM_FINDTEXT, Flags, LongInt(@Find)) :
function TCustomRichEdit.FindText(const SearchStr: string;
StartPos, Length: Integer; Options: TSearchTypes): Integer;
var
Find: TFindText;
Flags: Integer;
begin
with Find.chrg do
begin
cpMin := StartPos;
cpMax := cpMin + Length;
end;
Flags := 0;
if stWholeWord in Options then Flags := Flags or FT_WHOLEWORD;
if stMatchCase in Options then Flags := Flags or FT_MATCHCASE;
Find.lpstrText := PChar(SearchStr);
Result := SendMessage(Handle, EM_FINDTEXT, Flags, LongInt(@Find));
end;
Соответственно указатель передаётся так: LongInt(@Find)
Здравствуйте, NSP, Вы писали:
NSP>Здравствуйте, maslan.
NSP>1. попробуйте заменить fnd := RichEdit1.FindText('!MATRIX!', fnd+1, Length(RichEdit1.Text), []); NSP>на fnd := RichEdit1.FindText('!MATRIX!', fnd+1, Length(RichEdit1.Lines.Text), [stMatchCase]); NSP>Должно работать
NSP>2. Зачем изобретать велосипед?? NSP>Если заглянуть в реализацию TCustomRichEdit.FindText,то можно увидеть то же самое,то есть что поиск реализован с помощью NSP>SendMessage(Handle, EM_FINDTEXT, Flags, LongInt(@Find)) :
NSP>
NSP>function TCustomRichEdit.FindText(const SearchStr: string;
NSP> StartPos, Length: Integer; Options: TSearchTypes): Integer;
NSP>var
NSP> Find: TFindText;
NSP> Flags: Integer;
NSP>begin
NSP> with Find.chrg do
NSP> begin
NSP> cpMin := StartPos;
NSP> cpMax := cpMin + Length;
NSP> end;
NSP> Flags := 0;
NSP> if stWholeWord in Options then Flags := Flags or FT_WHOLEWORD;
NSP> if stMatchCase in Options then Flags := Flags or FT_MATCHCASE;
NSP> Find.lpstrText := PChar(SearchStr);
NSP> Result := SendMessage(Handle, EM_FINDTEXT, Flags, LongInt(@Find));
NSP>end;
NSP>
NSP>Соответственно указатель передаётся так: LongInt(@Find) NSP>
Спасибо за советы, но они не помогают =(
1) Велосипед изобретать приходится из-за того, что готовое не работает. stMatchCase — не помогает, я его пробовал. =(
Либо Borland.Vcl.RichEdit криво реализован в BDS2006, либо у меня руки растут ну совсем не оттуда, откуда положено...
2) LongInt(@Find) — ) Не проходит. Говорит что Invalid Typecast.
Я на работе вчера часа 3 убил на попытки понять... Ни Cardinal(@ft), ни Int32(addr(ft)) (с вариациями) не проходят. Всё тот же InvalidTypecast. Поэтому я и говорил про function PointerToInteger(var X:Pointer):Integer.
Ещё раз спасибо....
Небольшое допонение:
В D2006 Win32 VCL проекте, код выполняется "на ура":
Var i:integer;
begin
RichEdit1.Lines.LoadFromFile('C:\VRSpawner.log');
i:=RichEdit1.FindText('Executing',0,Length(RichEdit1.text),[stMatchCase]);
while i<>-1 do
begin
RichEdit1.SelStart:=i;
RichEdit1.SelLength:=Length('Executing');
RichEdit1.SelAttributes.Color:=clGreen;
i:=RichEdit1.FindText('Executing',i+1,Length(RichEdit1.text),[stMatchCase]);
end;
Небольшое допонение:
В D2006 Win32 VCL проекте, код выполняется "на ура":
Var i:integer;
begin
RichEdit1.Lines.LoadFromFile('C:\VRSpawner.log');
i:=RichEdit1.FindText('Executing',0,Length(RichEdit1.text),[stMatchCase]);
while i<>-1 do
begin
RichEdit1.SelStart:=i;
RichEdit1.SelLength:=Length('Executing');
RichEdit1.SelAttributes.Color:=clGreen;
i:=RichEdit1.FindText('Executing',i+1,Length(RichEdit1.text),[stMatchCase]);
end;
Архив с проектами .NET и Win32 и тестовым файлом здесь (15 007 байт)
Здравствуйте, NSP, Вы писали:
NSP>Здравствуйте, maslan.
NSP>Значит переводите проект на Delphi 7
Я бы с неё и не уходил, но уж больно перегрузку хочется использовать =)