Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / Delphi [игнор отключен] [закрыт для гостей] / Выделение блоков begin - end в Memo / 25 сообщений из 44, страница 1 из 2
18.09.2019, 15:01
    #39863356
Linux_64
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Выделение блоков begin - end в Memo
Добрый день!
Все вы видели как CnPack выделяет линиями блоки begin и end.
Кроме того они не обязательно могут находиться друг под другом и к тому же иметь "вложенные" блоки.
Кто-нибудь пытался реализовать подобное?
Мой код:
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
Type TNewMemo= class(TMemo)
  protected
    procedure WMPaint(var Message: TWMPaint); message WM_PAINT;
end;

Procedure NewMemo.WMPaint(var Message: TWMPaint); message WM_PAINT;
var
 N1,           // Начальная точка прорисовки линии
 N2: integer;  // Конечная точка прорисовки линии
 A, B: integer;   // Количество символов слева до слов begin/end
 C: integer; // Отступ слева (Количество пикселей)
 N_BEGIN: integer; // номер строки, где найден begin
 N_END: integer; // номер строки, где найден end
 TopLine: integer; // Номер верхней видимой строки редактора
 K: TControlCanvas;
begin
 TopLine := Memo1.Perform(EM_GETFIRSTVISIBLELINE, 0, 0);
 // Поиск слова BEGIN, начиная от верхней видимой линии
 for N_BEGIN:= TopLine to Memo.Lines.Count-1 do
 if Pos('begin', Memo.Lines[N_BEGIN])<>0 then
 begin
  A:= Pos('begin', Memo.Lines[N_BEGIN]);
  break;
 end;
 // Поиск слова END, начиная от верхней видимой линии
 for N_END:= TopLine to Memo.Lines.Count-1 do
 if Pos('end', Memo.Lines[N_END])<>0 then
 begin
  B:= Pos('end', Memo.Lines[N_END]);
  break;
 end;
 //
 N1:= Memo1.Font.Size*N_BEGIN+6;
 N2:= Memo2.Font.Size*N_END+6;
 C:= A*7; // Количество символов умножим на ~ширину одного символа
 //
 try // Создаем холст для рисования
  K:= TControlCanvas.Create;
  K.Control:= Self; // Присваиваем его нашему Memo
  with K do
  begin
   Pen.Color:= clRed;
   // Выводим вертикальную линию
   LineTo(C, N1);
   MoveTo(C, N2);
  end;
 finally
  K.Free;
 end;
end;
...
Рейтинг: 0 / 0
18.09.2019, 15:04
    #39863362
Мимопроходящий
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Выделение блоков begin - end в Memo
ещё немного, ещо чу-чють
и ты на пишешь SynEdit
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
18.09.2019, 15:12
    #39863367
DimaBr
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Выделение блоков begin - end в Memo
// Поиск слова BEGIN, начиная от верхней видимой линии

А что BEGIN не может быть выше ?
...
Рейтинг: 0 / 0
18.09.2019, 15:17
    #39863369
Linux_64
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Выделение блоков begin - end в Memo
DimaBr, конечно может...
Предлагаете выполнять поиск, начиная с первой строки?
...
Рейтинг: 0 / 0
18.09.2019, 15:25
    #39863371
Linux_64
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Выделение блоков begin - end в Memo
Кроме того, при добавлении новой пары: begin - end будет увеличено количество строк и прийдется все пересчитывать, либо вешать подобную процедуру на событие OnChange.
А как быть с вертикальной плохой прокрутки?, ведь даже если не прибавлять строки, следует сделать полную перерисовку...
...
Рейтинг: 0 / 0
18.09.2019, 15:28
    #39863372
Linux_64
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Выделение блоков begin - end в Memo
Есть идеи? Или написать базу данных легче, чем рисовать в Memo ?
...
Рейтинг: 0 / 0
18.09.2019, 15:33
    #39863375
Мимопроходящий
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Выделение блоков begin - end в Memo
18.09.2019 15:28, Linux_64 пишет:
> Есть идеи? Или написать базу данных легче, чем рисовать в Memo ?

Вы рисуйте, вы рисуйте, вам зачтётся,
Что гадать нам удалось, не удалось.
Ничего, что мы чужие, вы рисуйте,
Я потом, что непонятно, объясню.

(C)
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
18.09.2019, 15:44
    #39863384
Linux_64
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Выделение блоков begin - end в Memo
Да ладно вам, конечно зачтется.
Я вот подумал, если завести ещё 4 переменных, тогда можно пройтись циклом снова и найти вторую пару begin - end
...
Рейтинг: 0 / 0
18.09.2019, 15:47
    #39863386
Мимопроходящий
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Выделение блоков begin - end в Memo
Linux_64Я вот подумал, если завести ещё 4 переменных, тогда можно пройтись циклом снова и найти вторую пару begin - end
YouTube Video
...
Рейтинг: 0 / 0
18.09.2019, 15:48
    #39863390
DimaBr
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Выделение блоков begin - end в Memo
А если я напишу Abegin ?
...
Рейтинг: 0 / 0
18.09.2019, 15:49
    #39863391
Linux_64
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Выделение блоков begin - end в Memo
Возможно это сработает, и у меня будет две линии на две пары, но как сделать привязку, чтобы "свой" begin соответствовал "своему" end и линия прорисовывалась правильно, включая внутренние конструкции?
...
Рейтинг: 0 / 0
18.09.2019, 15:55
    #39863396
Linux_64
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Выделение блоков begin - end в Memo
DimaBr, но ведь ABegin не является ключевым словом, поэтому линия в этом случае не должна прорисовываться по-умолчанию, но стоит только убрать первую букву А и все работает.
...
Рейтинг: 0 / 0
18.09.2019, 15:56
    #39863398
Мимопроходящий
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Выделение блоков begin - end в Memo
а строковые литералы?
а комментарии?
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
18.09.2019, 15:56
    #39863399
DimaBr
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Выделение блоков begin - end в Memo
не должна, но у вас то рисуется !!!
...
Рейтинг: 0 / 0
18.09.2019, 16:03
    #39863406
Док
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Выделение блоков begin - end в Memo
Linux_64Есть идеи? Или написать базу данных легче, чем рисовать в Memo ?
все велосипеды уже написаны
...
Рейтинг: 0 / 0
18.09.2019, 16:03
    #39863407
Linux_64
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Выделение блоков begin - end в Memo
DimaBr, вы правы, рисуется даже если написать sssBeginzzz...
Хм, в этом случае следует найденное слово проверять по длинне, что бы исключить "мусор"
А вот на счёт комментариев и прочих литералов, это вообще загадка
...
Рейтинг: 0 / 0
18.09.2019, 16:07
    #39863408
wadman
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Выделение блоков begin - end в Memo
Linux_64по длинне
Не по длине, а на наличие разделителей до и после.
...
Рейтинг: 0 / 0
18.09.2019, 16:10
    #39863411
Мимопроходящий
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Выделение блоков begin - end в Memo
18.09.2019 16:07, wadman пишет:
> Не по длине, а на наличие разделителей до и после.

зонудо! (С)
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
18.09.2019, 16:17
    #39863415
Linux_64
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Выделение блоков begin - end в Memo
Док, зачем мне SynEdit ?
Когда мы уже научимся писать что-нибудь сами и не копировать это у америкосов?
...
Рейтинг: 0 / 0
18.09.2019, 16:24
    #39863419
Мимопроходящий
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Выделение блоков begin - end в Memo
18.09.2019 16:17, Linux_64 пишет:
> Когда мы уже научимся писать

да. нам тоже интересно.
когда ж вы уже наконец научитесь писать?!
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
18.09.2019, 16:29
    #39863422
Linux_64
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Выделение блоков begin - end в Memo
По-поводу наличия пробелов до и после, идея хорошая. Можно попробовать сделать строгое соответствие слова, включая пробелы по-бокам, хотя опять таки слово может начинаться сразу в начале строки без пробела.
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
|Procedure P1;
|begin
|
|end;
| // или
|  begin
|
|end;
| // или
| begin
|
|     end;
...
Рейтинг: 0 / 0
18.09.2019, 16:59
    #39863446
Linux_64
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Выделение блоков begin - end в Memo
А если я явно укажу, что мне нужно найти строгое соответствие слова, это исключит "мусор" типа aBegin или begin9 или begin_22
...
Рейтинг: 0 / 0
18.09.2019, 18:08
    #39863497
Linux_64
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Выделение блоков begin - end в Memo
Так, если указать дополнительное условие поиска слова, мы исключаем лишний мусор.
Линия прорисовывается, причём строго вертикально, независимо от того,
был ли сдвинут end в сторону или нет. Кроме того, зная где заканчивается линия, мы можем дорисовать горизонтальную линию до слова end с захватом +1 символ "e". При прокрутке текста, вертикальной полосой, линия перерисовывается, но если begin ушёл вверх за видимую часть строк в редакторе, то и сама линия начинается из ниоткуда. Кроме того, мне не очень нравиться эта конструкция:
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
// Поиск слова BEGIN
 for N_BEGIN:= 0 to Memo.Lines.Count-1 do
 if (Pos(' begin', Memo.Lines[N_BEGIN])<>0) or
    (Pos(' begin ', Memo.Lines[N_BEGIN])<>0) or
    (Pos('begin ', Memo.Lines[N_BEGIN])<>0) or
    ( Pos('begin', Memo.Lines[N_BEGIN])<>0 then
 begin
  break;
 end;
 // Поиск слова END
 for N_END:= 0 to Memo.Lines.Count-1 do
 if (Pos(' end ', Memo.Lines[N_END])<>0) or 
    (Pos(' end;', Memo.Lines[N_END])<>0) or 
    (Pos(' end.', Memo.Lines[N_END])<>0) or
    (Pos('end', Memo.Lines[N_END])<>0) or 
    (Pos('end ', Memo.Lines[N_END])<>0) or 
    (Pos(' end', Memo.Lines[N_END])<>0) or then
 begin
  break;
 end;
...
Рейтинг: 0 / 0
18.09.2019, 18:15
    #39863506
Linux_64
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Выделение блоков begin - end в Memo
В любом случае, одна пара уже выделяется, даже при прокрутке строк, ещё немного потестирую. Но как быть с внутренними блоками? Прибавлять по 4 переменных на каждую пару? Может завести массив из integer, вычислить общее количество одних слов и общее других? А ещё наверное добавить в условие поиска знаки комментариев // и {} для исключения из поиска тех слов, которые находятся внутри.
...
Рейтинг: 0 / 0
18.09.2019, 18:19
    #39863509
ёёёёё
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Выделение блоков begin - end в Memo
Linux_64В любом случае, одна пара уже выделяется, даже при прокрутке строк, ещё немного потестирую. Но как быть с внутренними блоками? Прибавлять по 4 переменных на каждую пару?...
Да, конечно. Так будет красиво. Но ведь может быть и так:
Код: pascal
1.
2.
3.
4.
begin
  begin
    begin
      begin   


...в любом случае, вложенность блоков не может быть глубже шестнадцати. 16*4 = 64 переменных. Фигня, зато код красивый.
...
Рейтинг: 0 / 0
Форумы / Delphi [игнор отключен] [закрыт для гостей] / Выделение блоков begin - end в Memo / 25 сообщений из 44, страница 1 из 2
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]