Форум программистов, компьютерный форум, киберфорум
Delphi для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 4.81/21: Рейтинг темы: голосов - 21, средняя оценка - 4.81
0 / 0 / 0
Регистрация: 30.01.2020
Сообщений: 48

Ограничить выделение в StringGrid-e

30.01.2020, 07:06. Показов 4736. Ответов 46

Студворк — интернет-сервис помощи студентам
Добрый день!
В Delphi имеется таблица StringGrid1 (20х20), по умолчанию выделять мышкой можно неограниченное количество ячеек, но как сделать так, чтоб при выделении мышкой не выделялись столбцы меньше 5 и больше 15, даже если нажатая левая кнопка мыши находилась за пределами выделения?
0
Лучшие ответы (1)
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
30.01.2020, 07:06
Ответы с готовыми решениями:

Как ограничить количество символов в ячейках StringGrid
Как ограничить количество символов в ячейках StringGrid? данные вводятся в таблицу вручную. в ячейку можно вводить только 1, 2 , 0, -1 ...

Ограничить ввод данных в определенные ячейки StringGrid
Доброго времени суток! Может кто-нибудь написать как в событие OnSelectCell запретить ввод данных в ячейку?

Ограничить количество введенных символов в ячейку StringGrid
Доброго дня. Столкнулся с проблемой - не получается ограничить колличество введенных символов (32 символа) в ячейку StringGrid. В...

46
 Аватар для mr-Crocodile
3053 / 1672 / 657
Регистрация: 19.03.2019
Сообщений: 5,380
05.02.2020, 11:17
Студворк — интернет-сервис помощи студентам
Цитата Сообщение от AzAtom Посмотреть сообщение
Вообще описывается, событие OnSelectCell возникает перед тем, как фокус перейдёт в ячейку. То есть, именно движение курсора клавишами он пресекает.
А если щёлкнуть туда мышкой, то происходит выделение области от предыдущего места до запрещённой ячейки, куда щёлкнули.
вот у меня точно так же.

qwertehok, выложите исходники своего проекта, пожалуйста.
0
5989 / 4564 / 1096
Регистрация: 29.08.2013
Сообщений: 28,207
Записей в блоге: 3
05.02.2020, 11:46
mr-Crocodile,
проверить не могу

Цитата Сообщение от mr-Crocodile Посмотреть сообщение
выложите исходники своего проекта, пожалуйста.
вечером если только

код взял на форуме и допилил
0
 Аватар для mr-Crocodile
3053 / 1672 / 657
Регистрация: 19.03.2019
Сообщений: 5,380
05.02.2020, 12:06
Цитата Сообщение от qwertehok Посмотреть сообщение
вечером если только
да хоть завтра

Цитата Сообщение от qwertehok Посмотреть сообщение
код взял на форуме и допилил
а что допилил то?

я взял стрингрид, на событие onSelectCell добавил обработчик вида:
Delphi
1
2
3
4
5
procedure TForm1.StringGrid1SelectCell(Sender: TObject; ACol, ARow: Integer;
  var CanSelect: Boolean);
begin
 if (ACol<5) or (ACol>=15) then CanSelect:=False;
end;
что допиливать нужно было?
0
5989 / 4564 / 1096
Регистрация: 29.08.2013
Сообщений: 28,207
Записей в блоге: 3
05.02.2020, 14:53
Цитата Сообщение от mr-Crocodile Посмотреть сообщение
я взял стрингрид, на событие onSelectCell добавил обработчик вида:
тогда зачем мой пример?
0
 Аватар для mr-Crocodile
3053 / 1672 / 657
Регистрация: 19.03.2019
Сообщений: 5,380
05.02.2020, 15:07
Цитата Сообщение от qwertehok Посмотреть сообщение
тогда зачем мой пример?
ну, затем, что мой пример не работает, а ваш (судя по вашему видео) - работает.
Или в вашем проекте был точно такой же код? Только он работал?

Добавлено через 4 минуты
мне то это самое выделение и даром не нужно, но раз возник вопрос, то любопытно разобраться.

да, если надо, могу откомпилированный EXE выложить. Чтобы можно было убедиться, что запрет CanSelect := False в onSelectCell не запрещает выделять в гриде мышкой.
0
5989 / 4564 / 1096
Регистрация: 29.08.2013
Сообщений: 28,207
Записей в блоге: 3
05.02.2020, 23:17
проект добавил
внутри ссылка на тему
Вложения
Тип файла: 7z grid selected cells.7z (1.2 Кб, 7 просмотров)
1
0 / 0 / 0
Регистрация: 30.01.2020
Сообщений: 48
06.02.2020, 06:15  [ТС]
Delphi
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
var
  vidilenie:Boolean
.................
procedure TForm2.StringGrid1MouseDown(Sender: TObject; Button: TMouseButton;
  Shift: TShiftState; X, Y: Integer);
begin
  vidilenie:=true;
end;
 
procedure TForm2.StringGrid1MouseMove(Sender: TObject; Shift: TShiftState; X,
  Y: Integer);
var
 TI:TInput;
 MI: TMouseInput;
 P:TPoint;
begin
  if (vidilenie = true) then
    if (StringGrid1.Selection.Right >= 8) and (StringGrid1.Selection.Left <= 10) then
      begin
        GetCursorPos(P);
        MI.dx := P.X;
        MI.dy := P.Y;
        MI.mouseData := 0;
        MI.dwFlags := MOUSEEVENTF_RIGHTDOWN ;
        MI.time := 10;
        TI.mi := MI;
        TI.Itype := INPUT_MOUSE;
        SendInput(1, TI, SizeOf(TInput));
        MI.dwFlags:=MOUSEEVENTF_RIGHTUP;
        TI.mi := MI;
        SendInput(1, TI, SizeOf(TInput));
      end;
end;
 
procedure TForm2.StringGrid1MouseUp(Sender: TObject; Button: TMouseButton;
  Shift: TShiftState; X, Y: Integer);
begin
  vidilenie:=false;
end;
Частичное решение было найдено таким образом, когда мы тянем мышкой по StringGrid, если выйдем за пределы разрешенного столбца (ACol) - имитируется нажатие правой кнопки мыши, выделение остаётся не более разрешенного столбца, после чего можно хоть задвигаться мышкой. Но становиться другая проблема, если имеется контекстное меню на StringGirde, получается оно будет задействовано
0
0 / 0 / 0
Регистрация: 30.01.2020
Сообщений: 48
06.02.2020, 06:18  [ТС]
Вот проект с программой
StringGrid1.zip
0
Модератор
4149 / 2360 / 812
Регистрация: 15.11.2015
Сообщений: 9,464
06.02.2020, 09:20
Цитата Сообщение от darknez1 Посмотреть сообщение
Частичное решение
Очень частичное.
Миниатюры
Ограничить выделение в StringGrid-e  
0
Модератор
4149 / 2360 / 812
Регистрация: 15.11.2015
Сообщений: 9,464
06.02.2020, 09:34
Сделал лог событий - OnSelectCell возникает один раз при нажатии мыши и потом, пока двигаешь выделение оно больше не наступает. Поэтому и не подходит для данной задачи.

Добавлено через 7 минут
darknez1, как тебе вот такое частичное решение? В процессе выделения можно выделить всё, что хочется, а по окончании область исправляется, чтобы попасть в разрешённую:
Delphi
1
2
3
4
5
6
7
8
9
10
11
12
13
14
procedure TForm1.StringGrid1MouseUp(Sender: TObject; Button: TMouseButton;
  Shift: TShiftState; X, Y: Integer);
var
  Sel: TGridRect;
begin
  if Button = mbLeft then begin
    Sel := StringGrid1.Selection;
    if Sel.Left   < 2 then Sel.Left   := 2;
    if Sel.Top    < 3 then Sel.Top    := 3;
    if Sel.Right  > 6 then Sel.Right  := 6;
    if Sel.Bottom > 7 then Sel.Bottom := 7;
    StringGrid1.Selection := Sel;
  end;
end;
0
0 / 0 / 0
Регистрация: 30.01.2020
Сообщений: 48
06.02.2020, 09:47  [ТС]
Дело в том что у меня есть таблица StringGrid, когда я выделяю мышкой т.е. веду по форме. В Label1 у меня отображается сколько и какие ячейки я выбрал номера и количество, часть столбцов в StingGride имеет ширину -1, т.е. они не отображаются, но если двигать мышкой с выдимых на невидимые (выделять их), то они суммируются хотя их не видно. В случае если бы я запретил выделять дальше ( например 15 столбца) то скрытые ячейки не суммировались бы, я проставил бы границы выделения и это решило бы массу вопросов.
Можешь сам попробывать у StringGrida поставь 10 ячеек ширина 30, а другие 10 ширина -1. При выделении мыши на StringGride, в Label1 выводится текущий адрес ячейки, и если начать выделять с видимых на невидимые, то он продолжит менять адрес, хотя ячеек то не видать и сетка закончилась.
А вот насчёт того кода с частичным решением: У меня Rad Studio 10.3.3 выделялось не вся область, позже запишу видео и скину, как оно у меня выделялось
0
Модератор
4149 / 2360 / 812
Регистрация: 15.11.2015
Сообщений: 9,464
06.02.2020, 09:56
Цитата Сообщение от darknez1 Посмотреть сообщение
У меня Rad Studio 10.3.3 выделялось не вся область
У меня тоже. Просто это такой трюк - нажать мышку на крайней ячейке и повести не по StringGrid, а вокруг него, тогда можно выделить и вне диапазона.

Добавлено через 1 минуту
Надо ковырять исходники StringGrid, ведь, он сам ограничивает выделение фиксированных строк и столбцов, они вообще не выделяются. Значит, это возможно в принципе.
0
0 / 0 / 0
Регистрация: 30.01.2020
Сообщений: 48
06.02.2020, 09:57  [ТС]
Это как вариант, и там много ошибок, я его бы и не применил в основную программу, но направление мыслям задал
0
Модератор
4149 / 2360 / 812
Регистрация: 15.11.2015
Сообщений: 9,464
06.02.2020, 11:20
Попробовал перекрыть выделение мышкой, если выделение начинается внутри разрешённой области и не выходит за пределы ячеек в гриде, то работает нормально. Но как только мышь выходит за пределы ячеек вообще, то начинается неконтроллируемое выделение ячеек.

Добавлено через 47 минут
darknez1, а как должно работать, если щёлкнули вне разрешённой области выделения?
0
0 / 0 / 0
Регистрация: 30.01.2020
Сообщений: 48
06.02.2020, 11:22  [ТС]
Ничего не должно происходить
0
Модератор
4149 / 2360 / 812
Регистрация: 15.11.2015
Сообщений: 9,464
06.02.2020, 11:30
Всё, решил. Есть 2 варианта:
1. Если щёлкнули и начали выделать в разрешённой области, то можно выделять только в её пределах. Если щёлкнули вне разрешённой области, то просто курсор перемещается туда и всё, ничего не выделяется.

2. Независимо по какой ячейке щёлкнули, курсор перемещается в разрешённую область и можно выделять только в её пределах.
0
0 / 0 / 0
Регистрация: 30.01.2020
Сообщений: 48
06.02.2020, 11:32  [ТС]
Спасибо AzAtom, а код имеется? И какой подход использовал?
0
Модератор
4149 / 2360 / 812
Регистрация: 15.11.2015
Сообщений: 9,464
06.02.2020, 12:28
Лучший ответ Сообщение было отмечено mr-Crocodile как решение

Решение

darknez1, перекрыл методы MouseDown и MouseUp класса TStringGrid. При нажатии мыши нужно проверять условия и если надо, то ограничивать движение мыши.

Добавлено через 52 минуты
Модификация класса TStringGrid. Делается в том же модуле, где объявлен используемый StringGrid:
Delphi
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
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
unit Unit1;
 
interface
 
uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, Grids, StdCtrls, ExtCtrls;
 
type
  TGridSelectMode = (sgSelectAll, sgSelectStartGrid, sgSelectStartRect);
 
type
  TStringGrid = class (Grids.TStringGrid)
    procedure MouseDown(Button: TMouseButton; Shift: TShiftState; X, Y: Integer); override;
    procedure MouseUp(Button: TMouseButton; Shift: TShiftState; X, Y: Integer); override;
  private
    FAllowedRect: TRect;
    FSelectMode: TGridSelectMode;
  public
    property GridSelectMode: TGridSelectMode read FSelectMode write FSelectMode default sgSelectAll;
    property AllowedRect: TRect read FAllowedRect write FAllowedRect;
  end;
 
type
  TForm1 = class(TForm)
    StringGrid1: TStringGrid;
    procedure FormCreate(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;
 
var
  Form1: TForm1;
 
implementation
 
{$R *.dfm}
 
 
procedure TStringGrid.MouseDown(Button: TMouseButton; Shift: TShiftState;
  X, Y: Integer);
 
  procedure v1; // Перемещает курсор в разрешённую область и начинает выделение
  var
    r1, r2: TRect;
  begin
    r1 := CellRect(FixedCols, FixedRows);
    if (X >= r1.Left) and (Y >= r1.Top) then begin
      // Получить координаты разрешённой области
      r1 := CellRect(FAllowedRect.Left, FAllowedRect.Top); // Здесь указать левую верхнюю ячейку разрешённой области
      r2 := CellRect(FAllowedRect.Right, FAllowedRect.Bottom); // Здесь указать правую нижнюю ячейку разрешённой области
 
      // Ограничить полученные координаты мыши разрешённой областью
      if X < r1.Left   then X := r1.Left  ;
      if X > r2.Right  then X := r2.Right ;
      if Y < r1.Top    then Y := r1.Top   ;
      if Y > r2.Bottom then Y := r2.Bottom;
 
      // Собрать координаты в один Rect
      r1.Right  := r2.Right ;
      r1.Bottom := r2.Bottom;
      // Перевести координаты разрешённой области в координаты на экране
      r1.TopLeft     := ClientToScreen(r1.TopLeft);
      r1.BottomRight := ClientToScreen(r1.BottomRight);
 
      // Ограничить координаты мыши разрешённой областью
      ClipCursor(@r1);
    end;
  inherited MouseDown(Button, Shift, X, Y);
  end;
 
  procedure v2; // Выделение только если щёлкнули в разрешённой области
  var
    r1, r2: TRect;
  begin
    inherited MouseDown(Button, Shift, X, Y);
 
    r1 := CellRect(FixedCols, FixedRows);
//    if (X >= r1.Left) and (Y >= r1.Top) then
    begin
      // Получить координаты разрешённой области
      r1 := CellRect(FAllowedRect.Left, FAllowedRect.Top); // Здесь указать левую верхнюю ячейку разрешённой области
      r2 := CellRect(FAllowedRect.Right, FAllowedRect.Bottom); // Здесь указать правую нижнюю ячейку разрешённой области
 
      // Ограничить полученные координаты мыши разрешённой областью
      if (X < r1.Left) or (X > r2.Right) or (Y < r1.Top) or (Y > r2.Bottom) then begin
        FGridState := gsNormal
      end else begin
        // Собрать координаты в один Rect
        r1.Right  := r2.Right ;
        r1.Bottom := r2.Bottom;
        // Перевести координаты разрешённой области в координаты на экране
        r1.TopLeft     := ClientToScreen(r1.TopLeft);
        r1.BottomRight := ClientToScreen(r1.BottomRight);
 
        // Ограничить координаты мыши разрешённой областью
        ClipCursor(@r1);
      end;
    end;
  end;
 
begin
  case FSelectMode of
  sgSelectAll: inherited;
  sgSelectStartGrid: v1; // Перемещает курсор в разрешённую область
  sgSelectStartRect: v2; // Выделяет только если щёлкнули в разрешённой области
  end;
end;
 
procedure TStringGrid.MouseUp(Button: TMouseButton; Shift: TShiftState;
  X, Y: Integer);
begin
  ClipCursor(nil); // Снять ограничение перемещения курсора
  inherited;
end;
 
 
 
 
procedure TForm1.FormCreate(Sender: TObject);
begin
  StringGrid1.ColCount := 10;
  StringGrid1.RowCount := 10;
//  StringGrid1.GridSelectMode := sgSelectStartGrid; // Разные варианты выделения
  StringGrid1.GridSelectMode := sgSelectStartRect;
  StringGrid1.AllowedRect := Rect(2, 3, 6, 7);
end;
 
end.
2
0 / 0 / 0
Регистрация: 30.01.2020
Сообщений: 48
06.02.2020, 12:37  [ТС]
Спасибо AzAtom, вечером только смогу запустить на Delphi. Ты просто СУПЕР ПРОГРАММИСТ!
0
 Аватар для mr-Crocodile
3053 / 1672 / 657
Регистрация: 19.03.2019
Сообщений: 5,380
06.02.2020, 14:48
Цитата Сообщение от qwertehok Посмотреть сообщение
проект добавил
внутри ссылка на тему
Спасибо.

проект, конечно, красивый. вот только непонятно, почему Вы называете его работой с выделением.
там своя отрисовка. Красная. Красивая. Но что она даёт и какое отношение имеет к Selection - мне не очень понятно.

А ещё попробуйте мышкой границы сдвинуть:
1
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
06.02.2020, 14:48
Помогаю со студенческими работами здесь

StringGrid, как ограничить количество знаков после запятой?
считываю данные из файла и записываю в таблицу StringGrid. в ней вместо, например, 0,63 выводится 0,6299997.. не подскажете как разрешить...

Выделение в StringGrid
В стринггриде мне нужно выделить область после чего подсчитать сколько в ней 1 и 0 после чего закрасить выделенную область. Проблема в...

Выделение ячейки в Stringgrid
Как выделить отдельную ячейку(допустим 1,1) в другой цвет и увеличить размер текста в этой ячейки?

StringGrid: Выделение и закрашивание
Вот задачка появилась на мою голову. Как сделать чтобы при выделении ячеек на Stringgrid и нажатии например кнопки &quot;Button&quot;, то...

Выделение ячеек StringGrid
Ребят, что-то я совсем туплю... У меня есть Листбокс и СтрингГрид. В ListBOx 7 строчек в StringGrid 6 столбцов и 7 строчек. Хочу...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
40
Ответ Создать тему
Новые блоги и статьи
попытка написать игровой сервер на C++
pyirrlicht 29.04.2026
попытка написать игровой сервер на плюсах с открытым бесконечным миром. возможно получится прикрутить интерпретатор питон для кастомизации игровой логики. что есть на текущий момент:. . .
Контроль уникальности выбранного документа-основания при изменении реквизита
Maks 28.04.2026
Алгоритм из решения ниже разработан на примере нетипового документа "ЗаявкаНаРемонтСпецтехники", разработанного в КА2. Задача: уведомлять пользователя, если указанная заявка (документ-основание). . .
Благородство как наказание
Maks 24.04.2026
У хорошего человека отношения с женщинами всегда складываются трудно. А я человек хороший. Заявляю без тени смущения, потому что гордиться тут нечем. От хорошего человека ждут соответствующего. . .
Валидация и контроль данных табличной части документа перед записью
Maks 22.04.2026
Алгоритм из решения ниже реализован на примере нетипового документа, разработанного в КА2. Задача: контроль и валидация данных табличной части документа перед записью с учетом регламента компании. . .
Отчёт о затраченных материалах за определенный период с макетом печатной формы
Maks 21.04.2026
Отчёт из решения ниже размещён в конфигурации КА2. Задача: разработка отчёта по затраченным материалам за определённый период, с возможностью вывода печатной формы отчёта с шапкой и подвалом. В. . .
Отчёт о спецтехнике находящейся в ремонте
Maks 20.04.2026
Отчёт из решения ниже размещен в конфигурации КА2. Задача: отобразить спецтехнику, которая на данный момент находится в ремонте. Есть нетиповой документ "Заявка на ремонт спецтехники" который. . .
Памятка для бота и "визитка" для читателей "Semantic Universe Layer (Слой семантической вселенной)"
Hrethgir 19.04.2026
Сгенерировано для краткого описания по случаю сборки и компиляции скелета серверного приложения. И пусть после этого скажут, что статьи сгенерированные AI - туфта и не интересно. И это не реклама -. . .
Запрет удаления строк ТЧ документа при определённом условии
Maks 19.04.2026
Алгоритм из решения ниже реализован на примере нетипового документа "Аккумуляторы", разработанного в конфигурации КА2. У данного документа есть ТЧ, в которой в зависимости от прав доступа. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru