D2006 .NET RichEdit.FindText, SendMessage, PointerToInteger
От: maslan Россия  
Дата: 06.09.06 19:41
Оценка:
Доброго времени суток....
//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;



Тут всё здорово: при вызове
RichEdit1.Lines.AddStrings(TStringList(varMatrix))
всё рисуется нормально.
Думаю: "Неплохо было бы скобки по бокам матрицы выводить".
Как нарисовать скобки? В шифрте 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 (то есть "нету такой строчки")
После такого пространнственного объяснения ситуации —
простейший вопрос "ПОЧЕМУ?"

И на засыпку:
 SendMessage(RichEdit1.Handle, EM_FINDTEXT, WParam, LParam);

WParam — FR_DOWN — нету такой константы, ну да ладно — мелочи.
LParam — MSDN, говорит что lparam — pointer to FINDTEXT structure...
    Var ft:FINDTEXT;
    Begin
    ft.lpstrText:='!MATRIX!';
  ft.chrg.cpMin:=0;
  ft.chrg.cpMax:=Length(RichEdit1.Text);

Это нормально, но, КАК передать в SendMessage указатель на ft???
То есть нужна функция
 function PointerToInteger(var X:Pointer):Integer;

Это проблемы .NET(как таковой), непатченной BDS или моё незнание особенностей .NET?
//Сорри за рамер...
... << RSDN@Home 1.1.3 beta 2 >>
Re: D2006 .NET RichEdit.FindText, SendMessage, PointerToInt
От: NSP Россия  
Дата: 06.09.06 22:38
Оценка:
Здравствуйте, maslan.

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)
На интересной работе и сны интересные видишь
Re[2]: D2006 .NET RichEdit.FindText, SendMessage, PointerTo
От: maslan Россия  
Дата: 07.09.06 04:13
Оценка:
Здравствуйте, 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.
Ещё раз спасибо....

У кого ещё идеи есть?
... << RSDN@Home 1.1.3 beta 2 >>
Re: D2006 .NET RichEdit.FindText, SendMessage, PointerToInt
От: maslan Россия  
Дата: 07.09.06 08:27
Оценка:
Небольшое допонение:
В 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;
... << RSDN@Home 1.1.3 beta 2 >>
Re: D2006 .NET RichEdit.FindText - ДОПОЛНЕНИЕ
От: maslan Россия  
Дата: 07.09.06 08:47
Оценка:
Небольшое допонение:
В 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 байт)
... << RSDN@Home 1.1.3 beta 2 >>
Re[3]: D2006 .NET RichEdit.FindText, SendMessage, PointerTo
От: NSP Россия  
Дата: 08.09.06 00:12
Оценка:
Здравствуйте, maslan.

Значит переводите проект на Delphi 7
На интересной работе и сны интересные видишь
Re[4]: D2006 .NET RichEdit.FindText, SendMessage, PointerTo
От: maslan Россия  
Дата: 08.09.06 04:14
Оценка:
Здравствуйте, NSP, Вы писали:

NSP>Здравствуйте, maslan.


NSP>Значит переводите проект на Delphi 7

Я бы с неё и не уходил, но уж больно перегрузку хочется использовать =)
... << RSDN@Home 1.1.3 beta 2 >>
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.