powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Delphi [игнор отключен] [закрыт для гостей] / Выделение блоков begin - end в Memo
25 сообщений из 44, страница 1 из 2
Выделение блоков begin - end в Memo
    #39863356
Linux_64
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Добрый день!
Все вы видели как 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
Выделение блоков begin - end в Memo
    #39863362
Мимопроходящий
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ещё немного, ещо чу-чють
и ты на пишешь SynEdit
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
Выделение блоков begin - end в Memo
    #39863367
DimaBr
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
// Поиск слова BEGIN, начиная от верхней видимой линии

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

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

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

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

да. нам тоже интересно.
когда ж вы уже наконец научитесь писать?!
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
Выделение блоков begin - end в Memo
    #39863422
Linux_64
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
По-поводу наличия пробелов до и после, идея хорошая. Можно попробовать сделать строгое соответствие слова, включая пробелы по-бокам, хотя опять таки слово может начинаться сразу в начале строки без пробела.
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
|Procedure P1;
|begin
|
|end;
| // или
|  begin
|
|end;
| // или
| begin
|
|     end;
...
Рейтинг: 0 / 0
Выделение блоков begin - end в Memo
    #39863446
Linux_64
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
А если я явно укажу, что мне нужно найти строгое соответствие слова, это исключит "мусор" типа aBegin или begin9 или begin_22
...
Рейтинг: 0 / 0
Выделение блоков begin - end в Memo
    #39863497
Linux_64
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Так, если указать дополнительное условие поиска слова, мы исключаем лишний мусор.
Линия прорисовывается, причём строго вертикально, независимо от того,
был ли сдвинут 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
Выделение блоков begin - end в Memo
    #39863506
Linux_64
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
В любом случае, одна пара уже выделяется, даже при прокрутке строк, ещё немного потестирую. Но как быть с внутренними блоками? Прибавлять по 4 переменных на каждую пару? Может завести массив из integer, вычислить общее количество одних слов и общее других? А ещё наверное добавить в условие поиска знаки комментариев // и {} для исключения из поиска тех слов, которые находятся внутри.
...
Рейтинг: 0 / 0
Выделение блоков begin - end в Memo
    #39863509
ёёёёё
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Linux_64В любом случае, одна пара уже выделяется, даже при прокрутке строк, ещё немного потестирую. Но как быть с внутренними блоками? Прибавлять по 4 переменных на каждую пару?...
Да, конечно. Так будет красиво. Но ведь может быть и так:
Код: pascal
1.
2.
3.
4.
begin
  begin
    begin
      begin   


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


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