Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Delphi программирование > Общие вопросы Delphi
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 14.02.2009, 21:28   #1
Armorer
Подтвердите свой е-майл
 
Регистрация: 07.04.2007
Сообщений: 120
По умолчанию Неправильно работает свойство Memo.CaretPos

Когда в Memo больше 3000(примерно) строк свойство начинает возвращать неправильные значения.

Вывод делаю так:

Код:
procedure TForm1.Memo1KeyUp(Sender: TObject; var Key: Word;
  Shift: TShiftState);
begin
Caption := IntToStr( Memo1.CaretPos.Y ) + ':' + IntToStr( Memo1.CaretPos.X );
end;
пример во вложенном файле. Нажать cntr+c и 4 раза cntrl+v.
В заголовке формы номер строки будет отрицательным.

Смотрел код метода, вроде, должен выводить нормально=)
Код:
function TCustomMemo.GetCaretPos: TPoint;
begin
  Result.X := LongRec(SendMessage(Handle, EM_GETSEL, 0, 0)).Hi; // возвращает номер символа конца выделения, младшее слово - начало.
  Result.Y := SendMessage(Handle, EM_LINEFROMCHAR, Result.X, 0); // возвращает номер строки, на которой находиться символ Result.X
  Result.X := Result.X - SendMessage(Handle, EM_LINEINDEX, -1, 0);//Функция возвращает номер первого символа в строке на которой находится курсор
end;
Почему не правильно работает? =)

Хотя в нем в все равно ошибка, оно возвращает не координаты каретки а координаты конца выделения. А каретка может находится в начале выделения. Так как можно получить именно координаты каретки?

У меня получается только правильно определить номер строки:
Код:
 X := SendMessage( Memo.Handle, EM_LINEINDEX, -1, 0);
 Y := SendMessage( Memo.Handle, EM_LINEFROMCHAR, X, 0);
Вложения
Тип файла: rar Тест2.rar (165.6 Кб, 17 просмотров)
Armorer вне форума Ответить с цитированием
Старый 15.02.2009, 09:42   #2
Kotofff
Участник клуба
 
Аватар для Kotofff
 
Регистрация: 11.01.2009
Сообщений: 1,917
По умолчанию

Вот немного переделал...
Посмотри ... вроде никакого отрицательного числа нигде не получается ... хоть сколько там строк

И вот еще как всегда DelphiWorld http://narod.yandex.ru/cgi-bin/yandma....og=0577254800&p=3
Вложения
Тип файла: zip Тест2.zip (10.0 Кб, 30 просмотров)
"Заряженному танку в дуло не смотрят" @Dekmer in WoT

Последний раз редактировалось Kotofff; 15.02.2009 в 09:56.
Kotofff вне форума Ответить с цитированием
Старый 15.02.2009, 11:44   #3
Armorer
Подтвердите свой е-майл
 
Регистрация: 07.04.2007
Сообщений: 120
По умолчанию

Отрицательных чисел действительно не выводит. Но проблема осталась=)

Теперь если сделать мышкой выделение, и каретка будет на начале выделения, то все работает отлично. Но если каретка будет в конце выделения то работает не правильно.

Попробовал сделать как в DelphiWorld. (во вложенном примере ResetCaption2). Но там результат вообще не правильный=)
Возможно тут опечатка:
Код:
function TRCMemo.GetRow: Integer; //цитата из DelphiWorld
begin

  Result := Perform(EM_LINEFROMCHAR, $FFFF, 0); //Вместо $FFFF должно быть -1. Если так как сейчас то выведет номер строки на которой находиться символ под номером $FFFF.
end;
Но если исправить на Result := Perform(EM_LINEFROMCHAR, -1, 0);
то работает аналогично первом примеру.
Вложения
Тип файла: rar Тест3.rar (166.7 Кб, 22 просмотров)
Armorer вне форума Ответить с цитированием
Старый 15.02.2009, 11:57   #4
Kotofff
Участник клуба
 
Аватар для Kotofff
 
Регистрация: 11.01.2009
Сообщений: 1,917
По умолчанию

Цитата:
Теперь если сделать мышкой выделение, и каретка будет на начале выделения, то все работает отлично. Но если каретка будет в конце выделения....
Тебе что именно нужно то ?
При движении мыши по Memo знать строку со столбцом ? При выделении мышкой каретка останется там где мышь бросим ... код так и работает ...
"Заряженному танку в дуло не смотрят" @Dekmer in WoT
Kotofff вне форума Ответить с цитированием
Старый 15.02.2009, 13:13   #5
Armorer
Подтвердите свой е-майл
 
Регистрация: 07.04.2007
Сообщений: 120
По умолчанию

Цитата:
При движении мыши по Memo знать строку со столбцом?
Если точнее при выделении мышью текста в Memo.
Вот пример, показывает неправильные значения
Изображения
Тип файла: jpg рис.jpg (53.9 Кб, 149 просмотров)
Armorer вне форума Ответить с цитированием
Старый 15.02.2009, 14:13   #6
Kotofff
Участник клуба
 
Аватар для Kotofff
 
Регистрация: 11.01.2009
Сообщений: 1,917
По умолчанию

Вот так вроде получилось:
Код:
procedure TForm1.Memo1MouseUp(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
begin
  Caption := IntToStr(Memo1.CaretPos.Y) + ':' + IntToStr(Memo1.CaretPos.X);
end;
Это применимо только к выделению ...
"Заряженному танку в дуло не смотрят" @Dekmer in WoT

Последний раз редактировалось Kotofff; 15.02.2009 в 14:17.
Kotofff вне форума Ответить с цитированием
Старый 15.02.2009, 14:39   #7
Armorer
Подтвердите свой е-майл
 
Регистрация: 07.04.2007
Сообщений: 120
По умолчанию

Код:
procedure TForm1.Memo1MouseUp(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
begin
  Caption := IntToStr(Memo1.CaretPos.Y) + ':' + IntToStr(Memo1.CaretPos.X);
end;
И мы опять вернулись к началу =) Значения неправильные когда в memo много строк.

Ещё раз скажу что хотел сделать. Нужно чтобы можно было узнать позицию курсора в любое время. И когда есть выделение и когда нет. Например так сделано в текстовых редактора AkelPad, BRED. В строке состояния у них отображаются координаты каретки. При выделении тоже все отображается правильно. Можно ли так же сделать с Memo (не с RichEdit и др, а именно с Memo)?
Armorer вне форума Ответить с цитированием
Старый 15.02.2009, 17:42   #8
Kotofff
Участник клуба
 
Аватар для Kotofff
 
Регистрация: 11.01.2009
Сообщений: 1,917
По умолчанию

Вот немного помучил Гугл и свою голову ...
Посмотри ...
Только тут выделение мышкой ...
Выделение с помощью Shift и курсорных клавиш добавь по аналогии
Вложения
Тип файла: zip Тест4.zip (12.0 Кб, 29 просмотров)
"Заряженному танку в дуло не смотрят" @Dekmer in WoT

Последний раз редактировалось Kotofff; 15.02.2009 в 17:45.
Kotofff вне форума Ответить с цитированием
Старый 16.02.2009, 08:35   #9
Armorer
Подтвердите свой е-майл
 
Регистрация: 07.04.2007
Сообщений: 120
По умолчанию

Спасибо. Казалось бы такая простая задача, а столько проблем =)

Немного дополнил и вот рабочий вариант.

Код:
Procedure TfMain.ResetStatusPos;
 var
  X, Y : Integer;
begin

  if CarPos <> -1 then// если нажали мышь и выделяем текст - то здесь начало выделяемого текста
    begin

    if ( Memo.SelStart + Memo.SelLength ) = CarPos // вычисляем в какую сторону выделяем
      then
        begin
        // строка - если выделяем в сторону начала текста
        Y := Memo.Perform( EM_LINEFROMCHAR, -1, -1 );
        // колонка - если выделяем в сторону начала текста
        X := LoWord( Memo.Perform( EM_GETSEL, 0, 0 ) ) - Memo.Perform( EM_LINEINDEX, -1, 0 );
        end
      else
        begin
        // строка - если выделяем в сторону конца текста
        Y := Memo.CaretPos.Y;
        // колонка - если выделяем в сторону конца текста
        X := HiWord( Memo.Perform( EM_GETSEL, 0, 0 ) ) - Memo.Perform( EM_LINEINDEX, -1, 0 );
        end;

    end
  else
  begin
   Y := Memo.Perform( EM_LINEFROMCHAR, -1, -1 );
   X := LoWord( Memo.Perform( EM_GETSEL, 0, 0 ) ) - Memo.Perform( EM_LINEINDEX, -1, 0 );
  end;

 inc(Y);
 inc(X);

 StatusBar.Panels[0].Text := IntToStr( Y ) + ':' + IntToStr( X );
end;

procedure TfMain.MemoMouseUp(Sender: TObject; Button: TMouseButton;
  Shift: TShiftState; X, Y: Integer);
begin
  if Memo.SelLength = 0 then
   CarPos := -1;
  ResetStatusPos; 
end;


procedure TfMain.MemoMouseMove(Sender: TObject; Shift: TShiftState; X,
  Y: Integer);
begin
 ResetStatusPos;
end;

procedure TfMain.MemoMouseDown(Sender: TObject; Button: TMouseButton;
  Shift: TShiftState; X, Y: Integer);
begin
 CarPos := Memo.SelStart;
 ResetStatusPos;
end;

procedure TfMain.MemoKeyUp(Sender: TObject; var Key: Word;
  Shift: TShiftState);
begin
 if not (ssShift in Shift) and (Memo.SelLength = 0) then
  CarPos := -1;

 ResetStatusPos;
end;

procedure TfMain.MemoKeyDown(Sender: TObject; var Key: Word;
  Shift: TShiftState);
begin

  if (CarPos = -1) and (ssShift in Shift) then
    CarPos := Memo.SelStart;
  ResetStatusPos;

end;
Armorer вне форума Ответить с цитированием
Старый 24.05.2011, 18:26   #10
KiL0z
Пользователь
 
Регистрация: 17.05.2010
Сообщений: 35
По умолчанию

Может задаю глупый вопрос, но уж извините...

А как установить курсор в позицию (Строка, Позиция_в_строке) ?
KiL0z вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Спецы!! Проверьте прогу почему работает неправильно?? SanSanblch Общие вопросы Delphi 2 05.12.2008 18:17
задача работает неправильно, подскажите! IvanIvan Помощь студентам 1 26.05.2008 22:21
Скрипт неправильно работает aleksa76 JavaScript, Ajax 4 21.05.2008 17:47
свойство ADOdataSET.CommandTimeout не работает _liv_ БД в Delphi 0 30.10.2007 14:54
Запрос неправильно работает... yulia БД в Delphi 0 27.05.2007 20:41