Форум программистов
 
Контакты: о проблемах с регистрацией, почтой и по другим вопросам пишите сюда - alarforum@yandex.ru, проверяйте папку спам! Обязательно пройдите активизацию e-mail.

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

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

Здесь нужно купить рекламу за 20 тыс руб в месяц! ) пишите сюда - alarforum@yandex.ru
Без учёта ботов - 20000 человек в день, 350000 в месяц.

Ответ
 
Опции темы
Старый 18.10.2019, 11:56   #11
Serge_Bliznykov
Старожил
 
Регистрация: 09.01.2008
Сообщений: 26,263
По умолчанию

Цитата:
Сообщение от Heneken87 Посмотреть сообщение
Вот так можно рисовать на Canvas Memo:
не проверял, а с скроллингом ваш пример будет работать нормально?

p.s. автор темы установил себе synedit ( https://programmersforum.ru/showthread.php?t=331667 )
Serge_Bliznykov вне форума   Ответить с цитированием
Старый 18.10.2019, 13:11   #12
Heneken87
Форумчанин
 
Регистрация: 27.04.2012
Сообщений: 185
По умолчанию

Цитата:
Сообщение от Serge_Bliznykov Посмотреть сообщение
не проверял, а с скроллингом ваш пример будет работать нормально?

p.s. автор темы установил себе synedit ( https://programmersforum.ru/showthread.php?t=331667 )
Без переработки нет. Это как пример другого подхода был.(без циклов). Если заморочится на досуге, то можно довести до ума.
Да, я видел что автор использовал сторонний компонент, я просто не сторонник этого. Где же тут саморазвитие, если всегда пользоваться чужими мозгами =)
Пишу много и развернуто
Heneken87 вне форума   Ответить с цитированием
Старый 18.10.2019, 14:06   #13
Heneken87
Форумчанин
 
Регистрация: 27.04.2012
Сообщений: 185
По умолчанию

Цитата:
Сообщение от Serge_Bliznykov Посмотреть сообщение
не проверял, а с скроллингом ваш пример будет работать нормально?
Вот. Если Вам интересно. Это можно перекинуть в отдельный модуль и унаследоваться от TMemo. Вы опытный разработчик, прикрутить этот модуль и переопределить TMemo в ваших проектах не составит никакого труда. А потом еще и наворачивать можно сверху и никаких сторонних компонентов ставить не придется. Наследуемся и жгем =)
Код:
unit Unit1;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls,System.Math;

type
  TForm1 = class(TForm)
    Memo1: TMemo;
    procedure FormCreate(Sender: TObject);
    procedure FormResize(Sender: TObject);
    procedure FormPaint(Sender: TObject);
    procedure Memo1KeyUp(Sender: TObject; var Key: Word; Shift: TShiftState);
    procedure Memo1KeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);
  private
    FStartPosition: Integer;
    procedure DrawLinePosition;
  public
    { Public declarations }
  end;

var
  Form1: TForm1;
const
  PaddingLeft: integer = 40; // Отступ курсора. Константой делать не правильно. Строк может быть много, поэтому это поле надо менять чтобы разделительная линия и отступ курсора тоже двигались.

implementation

{$R *.dfm}

procedure TForm1.DrawLinePosition; // Метод дорисовки
var
  MCanvas: TControlCanvas; 
  AMaxLineToScreen,I: Integer;
  ClearRect: TRect;
begin
  MCanvas:= TControlCanvas.Create;
  Try
   MCanvas.Control:= Memo1; //Прикручиваем канву Memo1
   With MCanvas do
   Begin
   { Определяем кол-во линий способных уместится в рабочей области Memo1 (2 - дельта, курсор останавливается за 2 линии до конца области и активируется вертикальный скролл , поэтому и рисовать ниже курсора не надо)}
    AMaxLineToScreen := Ceil((Memo1.ClientRect.Bottom - Memo1.ClientRect.Top) / TextHeight('99')) - 2;  
    FStartPosition := Memo1.Lines.Count - AMaxLineToScreen + 2; // Разворачиваем порядок цифр, от меньшего к большему.
    if FStartPosition < 0 then
    FStartPosition := 0;
   {  Определяем прямоугольник который будем "подчищать "}
    ClearRect.Top := 0; 
    ClearRect.Left := 0;
    ClearRect.Right :=PaddingLeft;
    ClearRect.Bottom := Memo1.ClientRect.Bottom;
   {  Чистим }
    FillRect(ClearRect);
   { Крутим столько раз, сколько помещается в область }
    for I := 0 to AMaxLineToScreen - 1 do
    begin
      Inc(FStartPosition);
      TextOut(10,(i) * TextHeight('99'),IntToStr(FStartPosition)); 
      if I >= Memo1.Lines.Count then  // Тормозим рисование если кол-во линий в Мемо меньше чем максимально доступное к отображению
      Break;
    end;
   { Рисуем линию }
    MoveTo ( PaddingLeft, 0 ); 
    LineTo ( PaddingLeft, Memo1.ClientHeight );
   end;
  finally
    MCanvas.Free;
  End;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  Memo1.DoubleBuffered := True;
  Memo1.Clear;
  FStartPosition := Memo1.Lines.Count;
end;

procedure TForm1.FormPaint(Sender: TObject);
begin
  DrawLinePosition;  // Рисуемся заного (при Resize например)
end;

procedure TForm1.FormResize(Sender: TObject);
var
  Rect: TRect;
begin
  { Устанавливаем отступ курсора }
  SendMessage(Memo1.Handle, EM_GETRECT, 0, LongInt(@Rect));
  Rect.Left:= PaddingLeft + 5;
  Rect.Top:= 1;
  SendMessage(Memo1.Handle, EM_SETRECT, 0, LongInt(@Rect));
  Memo1.Refresh;
end;

procedure TForm1.Memo1KeyDown(Sender: TObject; var Key: Word;
  Shift: TShiftState);
begin
  DrawLinePosition; // Рисуемся тут. Конечно можно и нужно посадить на что нибудь иное, что бы не рисоваться на каждый тык в клавишу
end;

procedure TForm1.Memo1KeyUp(Sender: TObject; var Key: Word; Shift: TShiftState);
begin
  DrawLinePosition; // Рисуемся тут
end;

end.
P:S: В целом это то, что просил автор. Единственное что не организовано, это привязка к позиции скролла. Но я думаю особых проблем тут быть не должно. Внутри метода нужно будет отскакивать не от Memo1.Lines.Count, а например от поля FCurrentLine объявленного в привате форме, которое будет изменятся от позиции скролла и Memo1.Lines.Count.
Пишу много и развернуто

Последний раз редактировалось Heneken87; 18.10.2019 в 15:50.
Heneken87 вне форума   Ответить с цитированием
Старый 18.10.2019, 14:28   #14
Serge_Bliznykov
Старожил
 
Регистрация: 09.01.2008
Сообщений: 26,263
По умолчанию

Цитата:
Вот. Если Вам интересно.
интересно
Цитата:
Код:
AMaxLineToScreen := Ceil(Memo1.ClientRect.Height / TextHeight('99')) - 2;
в старой Delphi 2006 ( Borland® Delphi® for Microsoft® Windows™ Version 10.0.2558.35231 Update 2 Copyright © 2005 )
не компилируется.
у Memo1.ClientRect нет свойства Height
memo1_error.png

не знаю, насколько корректно, я заменил на
Код:
    AMaxLineToScreen := Ceil((Memo1.ClientRect.Bottom -  Memo1.ClientRect.Top) / TextHeight('99')) - 2;
в результате откомпилировалось. Как-то пытается работать.
Косячит при удалении строк (нумерация не удаляется) и совсем не работает скролл.
при ресайзе формы нумерация совсем пропадает.

но в целом идея понятно. Можно допиливать, если кому-то прижмёт.
Спасибо за пример реализации.
Serge_Bliznykov вне форума   Ответить с цитированием
Старый 18.10.2019, 14:45   #15
Heneken87
Форумчанин
 
Регистрация: 27.04.2012
Сообщений: 185
По умолчанию

Цитата:
Сообщение от Serge_Bliznykov Посмотреть сообщение
AMaxLineToScreen := Ceil((Memo1.ClientRect.Bottom - Memo1.ClientRect.Top) / TextHeight('99')) - 2;
- у себя так же завернул, все верно.
По идее все должно работать. Вроде в TMemo ничего не меняли. Если на Enter идет нормально и без тормозов, то дальше допилить уже не трудно будет.
Про ресайзе я написал, там ловить WM_PAINT надо ну или на край конец на OnPaint формы посадить. Мы же не перекрываем стандартное событие отрисовки, а просто дорисовываем, поэтому после ресайза вызывается стандартный репеинт и канва перерисовывается.
Про удаление тоже сказал. Удаление работает нормально,просто надо область подчищать=), а то там остаются остатки от старых цифр=))
Пишу много и развернуто

Последний раз редактировалось Heneken87; 18.10.2019 в 15:18.
Heneken87 вне форума   Ответить с цитированием
Старый 18.10.2019, 15:14   #16
Heneken87
Форумчанин
 
Регистрация: 27.04.2012
Сообщений: 185
По умолчанию

Поправил. Проверяйте =) Осталось только к скроллу привязаться =)
Пишу много и развернуто

Последний раз редактировалось Heneken87; 18.10.2019 в 15:17.
Heneken87 вне форума   Ответить с цитированием
Старый 18.10.2019, 15:33   #17
Serge_Bliznykov
Старожил
 
Регистрация: 09.01.2008
Сообщений: 26,263
По умолчанию

Цитата:
Сообщение от Heneken87 Посмотреть сообщение
Поправил. Проверяйте =) Осталось только к скроллу привязаться =)
сейчас нет возможности проверить. вечером дома попробую запустить код.
Serge_Bliznykov вне форума   Ответить с цитированием
Ответ
Опции темы


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Delphi.Чтение файла в Memo, вычисление, добавление строк в Memo antonio_sk Помощь студентам 0 26.04.2013 18:01
нумерация строк ЦЕРЦЕЯ Microsoft Office Excel 9 02.07.2011 00:35
Нумерация строк в БД grom333 БД в Delphi 3 21.05.2011 18:51
Нумерация строк. QT 4 NikLik Qt и кроссплатформенное программирование С/С++ 2 18.12.2008 23:38
Нумерация строк в Memo Макс84 Компоненты Delphi 10 02.04.2007 17:10