Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / Delphi [игнор отключен] [закрыт для гостей] / Автоматическое включение вертикального ScrollBars в нескольких компонентах TMemo / 25 сообщений из 49, страница 1 из 2
02.02.2018, 12:47
    #39595539
Bellic
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Автоматическое включение вертикального ScrollBars в нескольких компонентах TMemo
Привет, парни!
На форме имеется несколько компонентов ТМемо ...
Необходимо одной процедурой (по событию OnCange ) реализовать для всех ТМемо включение вертикального ScrollBars .
...
На просторах Интернета нашел вот такую :
Реализация для одного ТМемо
Код: 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.
51.
52.
53.
54.
55.
unit Unit1;
interface
uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, ExtDlgs, StdCtrls, ExtCtrls,Types;
type
  TForm1 = class(TForm)
    Memo1: TMemo;
    Label1: TLabel;
    procedure Memo1Change(Sender: TObject);
    procedure FormCreate(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;
var
  Form1: TForm1;
implementation
{$R *.dfm}
procedure TForm1.Memo1Change(Sender: TObject);
var
 i:integer; // номер строки
 Height:integer; // высота текста в Memo
 Rect:TRect; // пользовательская область Memo
 Pos:integer; // позиция курсора
begin
 i:=0;
 Height:=0;
 Pos:=Memo1.SelStart;
 Rect:=Memo1.ClientRect;
 Label1.Font:=Memo1.Font;
 while (i < Memo1.Lines.Count) and (Height < Rect.Bottom) do
  begin
   Label1.Caption:=Memo1.Lines[i];
   if Label1.Caption = ''
    then
     Label1.Caption:=' ';
   inc(Height, Label1.Height);
   inc(i)
  end;
 if Height > Rect.Bottom
  then
   Memo1.ScrollBars:=ssVertical
  else
   Memo1.ScrollBars:=ssNone;
 if Memo1.SelStart <> Pos
  then
   Memo1.SelStart:=Pos
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
 Label1.Visible:=False // прячем Label, нужный для работы...
end;
end.


В моем случае имеется 4 компонента Memo1 , Memo2 , Memo3 , Memo4 , каждому из которых назначил соответствующее значение свойства Tag ( 1 , 2 , 3 и 4 ).
( В реальности компоненты не имеют цифр в конце имени, и здесь пронумерованы для упрощения! )
Отлавливать компоненту по событию думаю анализируя Tag через CASE :
Код: pascal
1.
2.
3.
4.
5.
6.
case (Sender as TComponent).Tag of
    1: ...
    2: ...
    3: ...
    4: ...
end;


Вопросы:
1. Далее хотел применить " with ... do ", передав в конструкцию имя конкретного компонента... но затрудняюсь - как его сформировать!?
2. По самому вышеприведенному коду - может будут у кого другие, более изящные варианты?
...
Рейтинг: 0 / 0
02.02.2018, 13:00
    #39595547
Vizit0r
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Автоматическое включение вертикального ScrollBars в нескольких компонентах TMemo
TMemo(Your_Form.FindComponent('Memo' + i.ToString))
...
Рейтинг: 0 / 0
02.02.2018, 13:16
    #39595559
Gerasimenko
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Автоматическое включение вертикального ScrollBars в нескольких компонентах TMemo
Bellic,

Код: pascal
1.
2.
3.
for i:=0 to Form1.ComponentCount-1
   do if Form1.Components[i].ClassName = 'TMemo'
       then ShowMessage((Form1.Components[i] AS TMemo).Name)


или так
Код: pascal
1.
2.
3.
  for i:=0 to Form1.ControlCount-1
   do if Form1.Controls[i].ClassName = 'TMemo'
       then ShowMessage((Form1.Controls[i] AS TMemo).Name)
...
Рейтинг: 0 / 0
02.02.2018, 13:17
    #39595562
Bellic
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Автоматическое включение вертикального ScrollBars в нескольких компонентах TMemo
Vizit0rTMemo(Your_Form.FindComponent('Memo' + i.ToString))
Спасибо, но я вроде это уже через Tag определил!?
...
Осталось сделать что-то похожее на:
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
NameMemo: TComponentName; // Тут нужен Правильный тип переменной!!!
begin
     case (Sender as TComponent).Tag of
          1: NameMemo := 'FPHexMemo';
          2: NameMemo := 'FPTxtMemo';
          3: NameMemo := 'FZHexMemo';
          4: NameMemo := 'FZTxtMemo';
     end;
...
     with NameMemo do
          begin
...


Вышеприведенный код - конечно же с ошибками! - Только лишь для понятия сути вопроса!!!
...
Рейтинг: 0 / 0
02.02.2018, 13:17
    #39595563
Arioch
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Автоматическое включение вертикального ScrollBars в нескольких компонентах TMemo
Купить букварь про Дельфи и читать главу про ООП и приведение типов.

http://www.cyberforum.ru/delphi-beginners/thread1005593.html
http://parsers.info/2009/12/perechislenie-vsex-komponentov-na-forme/

Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
Procedure TMyForm.MakeMemosScrolled(const VertScroll: boolean);
var i: integer; ss: TScrollStyle; c: TComponent;
begin
   if VertScroll then ss := ssVertical else ss := ssNone;

   for i := 0 to Pred( Self.ComponentCount ) do
   begin
      c := Self.Components[i];
      if not (c is TMemo) then Continue;

      (c as TMemo).ScrollBarrs := ss;
   end;
end;
...
Рейтинг: 0 / 0
02.02.2018, 13:18
    #39595565
Arioch
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Автоматическое включение вертикального ScrollBars в нескольких компонентах TMemo
BellicСпасибо, но я вроде это уже через Tag определил!?

и довольно глупо это - совершенно ненадёжно.

через год забудешь и в каком-нибудь другом тэге всунешь то же значение для других целей - и начнёёёётся
...
Рейтинг: 0 / 0
02.02.2018, 13:23
    #39595572
Bellic
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Автоматическое включение вертикального ScrollBars в нескольких компонентах TMemo
Ariochи довольно глупо это - совершенно ненадёжно.
через год забудешь и в каком-нибудь другом тэге всунешь то же значение для других целей - и начнёёёётся
Возможно Вы правы, но на данном этапе - это самое простое решение!
Тем более, что с Tag в другом контексте вообще не работаю...
...
Рейтинг: 0 / 0
02.02.2018, 13:25
    #39595574
Док
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Автоматическое включение вертикального ScrollBars в нескольких компонентах TMemo
AriochКупить букварь про Дельфи и читать главу про ООП и приведение типов.
+1


проект на Лазаре
...
Рейтинг: 0 / 0
02.02.2018, 13:26
    #39595575
Arioch
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Автоматическое включение вертикального ScrollBars в нескольких компонентах TMemo
BellicТолько лишь для понятия сути вопроса!!!

суть соверщшенно потерялась

1) имя компонента ( свойсто .Name ) ты можешь меня тькак угодно, прямо в запущеннйо программе можешь взять и поменять.
Код: sql
1.
 Memo1.Name := 'Ля_ля_ля_' + Memo1.Name+'_1_2_4_5'; 



2) имя компонента и имя переменной в published-секции формы с точки зрения языка не связаны никак вообще.
Они связаны только с точки зрения библиотеки VCL (или FMX) и c точки зрения среды программирования.
Но не с точки зрения самого языка.
Завязываться на это - ненадёжно. Также как с тэгами, только если нет лучше вариантов.

3) "(Sender as TComponent).Tag" - вот здесь ты читаешь Tag без всяких там имён и названий. Никаких case, ничего. Так ведь?
Чем принципиально отличается установка скроллбаров? Да ничем по большому счёту. И не нужно выдумывать лишнего. Вот так же как тэг читал, так же и настройки прокрутки ставь. Названия свойств и типов конечно другие ,но это детали, а суть та же самая.
...
Рейтинг: 0 / 0
02.02.2018, 13:30
    #39595580
Arioch
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Автоматическое включение вертикального ScrollBars в нескольких компонентах TMemo
Bellicно на данном этапе - это самое простое решение!

срать под стол в кухне, прямо во время еды, тоже самое простое решение "на данном этапе"

но чуть только шаг в следующий этап - и потратишь в 10 раз больше времени на разгребание проблем

"не размножай сущности без необходимости"
DRY = Don't Repeat Yourself

Ты и так знаешь какие у тебя на форме компоненты - мемо, а какие нет.
И это надежная информация. Она зашита компилятором наглухо, хрен отломаешь.

И попусту дублировать наждёжную информацию о типах ненадёжной фигнёй в тэгах - неумно.
...
Рейтинг: 0 / 0
02.02.2018, 13:32
    #39595583
Arioch
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Автоматическое включение вертикального ScrollBars в нескольких компонентах TMemo
Еще один вариант, когда нужно обработать несколько memo, но не все

Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
Procedure TMyForm.MakeMemosScrolled(const VertScroll: boolean);
Type MemoList = TArray<TMemo>;
var ss: TScrollStyle; m: TMemo; L: MemoList;
begin
   if VertScroll then ss := ssVertical else ss := ssNone;

   L := MemoList.Create( Memo1, { Memo2, Memo3, } Memo4, Memo5 );

   for m in L do
      m.ScrollBarrs := ss;
end;
...
Рейтинг: 0 / 0
02.02.2018, 13:38
    #39595587
Arioch
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Автоматическое включение вертикального ScrollBars в нескольких компонентах TMemo
BellicОтлавливать компоненту по событию думаю анализируя Tag через CASE :

зачем тебе вообще отлавливать какую-то одну конкретную компоненту, если ты собираешься в любом случае включать скролл Bellicдля всех ТМемо???
...
Рейтинг: 0 / 0
02.02.2018, 13:56
    #39595605
Bellic
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Автоматическое включение вертикального ScrollBars в нескольких компонентах TMemo
Arioch, столько разных слов...
...
Еще раз попробую словесно описать суть...
...
Имеем N -ное количество ТМемо (с запретом редактирования и фиксированного размера!), программа в разное время выводит в них какие-то значения различной длины.
Необходимо для каждого компонента написать процедуру, включающую СкроллБар, если записываемые данные больше видимого размера компонента.

Первый вариант - написать N процедур и назначить их на событие OnChange для каждого конкретного ТМемо , но этот вариант слишком накладный!

Второй вариант - написать Одну Общую процедуру для всех ТМемо , а внутри ее уже вычислять - для какого из них она была вызвана по событию.
Для отлавливания выбрано уникальное значение (в моем случае) свойство TAG .
Для меня осталось задачей - в конструкции CASE правильно сформировать (или просто присвоить " := ") имя компонента, что бы позже его можно было подставить в " with NameMemo do".
Разве так нельзя сделать (не перебирая все элементы на форме)?
Или же как то "вычислить" имя компонента, для которого была вызвана процедура, через SENDER?
...
Рейтинг: 0 / 0
02.02.2018, 13:58
    #39595606
makhaon
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Автоматическое включение вертикального ScrollBars в нескольких компонентах TMemo
1. Совершенно зря гоните на Tag, не было проблем с ним ни разу. Использую постоянно, удобно.
2. Беллик, конкретно в твоём случае удобно не возится с тэгами, а найти все TMemo 'оптом' и с ними что-то сделать:
Gerasimenkodo if Form1.Components[i].ClassName = 'TMemo'
Лучше так:
Код: pascal
1.
if Form1.Components[i] is TMemo then
...
Рейтинг: 0 / 0
02.02.2018, 13:59
    #39595609
goldmi45
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Автоматическое включение вертикального ScrollBars в нескольких компонентах TMemo
Bellic,

У события есть Sender. Может его заиспользовать?
...
Рейтинг: 0 / 0
02.02.2018, 14:00
    #39595611
Bellic
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Автоматическое включение вертикального ScrollBars в нескольких компонентах TMemo
Arioch, процедура включает СкроллБар в один момент времени только для Одного ТМемо!
А вот для какого из них конкретно - и нужно вычислить.
...
Рейтинг: 0 / 0
02.02.2018, 14:04
    #39595615
makhaon
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Автоматическое включение вертикального ScrollBars в нескольких компонентах TMemo
Только так:
авторВторой вариант - написать Одну Общую процедуру для всех ТМемо, а внутри ее уже вычислять - для какого из них она была вызвана по событию.
Беллик, надо мыслить по-программистски. Одна из фундаментальных идей - это бритва Оккама. Всё, что может быть сделано минимальными телодвижениями, только так и должно быть сделано.

авторДля отлавливания выбрано уникальное значение (в моем случае) свойство TAG.

В OnChange у тебя уже есть Sender, больше тебе ничего не нужно, я так думаю.
...
Рейтинг: 0 / 0
02.02.2018, 14:09
    #39595617
Bellic
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Автоматическое включение вертикального ScrollBars в нескольких компонентах TMemo
[quot makhaon]Только так:
авторВторой вариант - написать Одну Общую процедуру для всех ТМемо, а внутри ее уже вычислять - для какого из них она была вызвана по событию.
makhaon , ну а по тексту разве не понятно, что я не похож на мазохиста, пишущего N-процедур?..)))
В OnChange у тебя уже есть Sender, больше тебе ничего не нужно, я так думаю.
Да, возможно... пытаюсь восполнить пробелы в технологии Sender...)))
...
Рейтинг: 0 / 0
02.02.2018, 14:22
    #39595628
Bellic
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Автоматическое включение вертикального ScrollBars в нескольких компонентах TMemo
авторВ OnChange у тебя уже есть Sender, больше тебе ничего не нужно, я так думаю.
makhaon, тогда CASE вообще не нужен будет!?..))
Получилось вот так:
Код: 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.
procedure TManualForm.MemoChange(Sender: TObject);
var
i: integer; // номер строки
Height: integer; // высота текста в Memo
Rect: TRect; // пользовательская область Memo
Pos: integer; // позиция курсора
begin  
     i:=0;
     Height:=0;
     with (Sender as TMemo) do
          begin
               Pos:=SelStart;
               Rect:=ClientRect;
               TempLabel.Font:=Font;
               while (i < Lines.Count) and (Height < Rect.Bottom) do
                    begin
                         TempLabel.Caption:=Lines[i];
                         if TempLabel.Caption = '' then TempLabel.Caption:=' ';
                         Inc(Height, TempLabel.Height);
                         Inc(i);
                    end;
               if Height > Rect.Bottom then ScrollBars:=ssVertical
               else ScrollBars:=ssNone;
               if SelStart <> Pos then SelStart:=Pos
          end;
end;


Все вроде нормуль, только при компиляции выругалось на выделенную строку:
Код: pascal
1.
[dcc32 Error] Manual_Module.pas(1143): E2064 Left side cannot be assigned to
...
Рейтинг: 0 / 0
02.02.2018, 14:34
    #39595639
goldmi45
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Автоматическое включение вертикального ScrollBars в нескольких компонентах TMemo
Код: pascal
1.
Height := Height + TempLabel.Height;
...
Рейтинг: 0 / 0
02.02.2018, 14:40
    #39595643
Bellic
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Автоматическое включение вертикального ScrollBars в нескольких компонентах TMemo
goldmi45
Код: pascal
1.
Height := Height + TempLabel.Height;


Ага, ..)))
Тут бы переменные не мешало бы переименовать..)
...
Рейтинг: 0 / 0
02.02.2018, 14:48
    #39595651
Bellic
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Автоматическое включение вертикального ScrollBars в нескольких компонентах TMemo
Что касается самой реализации вычислений - попробую сам разобраться, возможно для моего случая код можно и сократить.
Спасибо Всем, что были со мной!,,))
...
Рейтинг: 0 / 0
02.02.2018, 15:20
    #39595691
Vizit0r
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Автоматическое включение вертикального ScrollBars в нескольких компонентах TMemo
1) автор сам не понимает, что ему надо - но пытается это реализовать.
2) автор явно фанат with...do и кучи переменных, одноименных с пропами компонента.

соответственно, большие проблемы с кодом в грядущем у него предвижу я, особенно из-за пункта 2.
...
Рейтинг: 0 / 0
02.02.2018, 15:36
    #39595701
Bellic
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Автоматическое включение вертикального ScrollBars в нескольких компонентах TMemo
Vizit0r1) автор сам не понимает, что ему надо - но пытается это реализовать.
2) автор явно фанат with...do и кучи переменных, одноименных с пропами компонента.
соответственно, большие проблемы с кодом в грядущем у него предвижу я, особенно из-за пункта 2.
Vizit0r , вместо того, что бы обливать грязью или унижать ТС - предложите полный вариант своей процедуры!
Напомню - сей код был позаимствован вот от сюда: http://forum.vingrad.ru/topic-33922.html
Надеюсь еще раз "постановку задачи" для Вас повторять не нужно?
На текущий момент Общая процедура имеет следующий вид:
Код: 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.
procedure TManualForm.MemoChange(Sender: TObject);
var
NomerStroki: integer; // номер строки
Visota: integer; // высота текста в Memo
Rect: TRect; // пользовательская область Memo
PosCursor: integer; // позиция курсора
begin 
     NomerStroki := 0;
     Visota := 0;
     with (Sender as TMemo) do
          begin
               PosCursor := SelStart;
               Rect := ClientRect;
               TempLabel.Font := Font;
               while (NomerStroki < Lines.Count) and (Visota < Rect.Bottom) do
                    begin
                         TempLabel.Caption := Lines[NomerStroki];
                         if TempLabel.Caption = '' then TempLabel.Caption := ' ';
                         Inc(Visota, TempLabel.Height); // после замены имени переменной - можно и так
                         //Height := Height + TempLabel.Height; // аналог строки выше
                         Inc(NomerStroki);
                    end;
               if Visota > Rect.Bottom then ScrollBars := ssVertical
               else ScrollBars := ssNone;
               if SelStart <> PosCursor then SelStart := PosCursor;
          end;
end;


Т.к. мои TMemo не редактируемые, то выделенные строки видимо можно удалить.
...
Рейтинг: 0 / 0
02.02.2018, 15:48
    #39595710
Vizit0r
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Автоматическое включение вертикального ScrollBars в нескольких компонентах TMemo
грязью обливать? унижать? Вот делать мне больше нечего.

и да, свой ответ я дал сам первым.
...
Рейтинг: 0 / 0
Форумы / Delphi [игнор отключен] [закрыт для гостей] / Автоматическое включение вертикального ScrollBars в нескольких компонентах TMemo / 25 сообщений из 49, страница 1 из 2
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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