Форум программистов, компьютерный форум, киберфорум
Delphi для начинающих
Войти
Регистрация
Восстановить пароль
 
Рейтинг 4.50/6: Рейтинг темы: голосов - 6, средняя оценка - 4.50
0 / 0 / 0
Регистрация: 07.06.2015
Сообщений: 3
1

Выделение мышью неполных рядов StringGrid на Delphi XE7

10.06.2015, 12:08. Показов 1144. Ответов 4
Метки нет (Все метки)

Ребята, подскажите. Суть проблемы наверное многим знакома. В StringGrid выделение происходит прямоугольником, а нужно выделение рядов, как происходит выделение строк в текстовом файле. Например с 5 ряда с 4-го столбца выделяю три ряда и на ряде 7 останавливаюсь в столбце 2. Должны быть выделены все ячейки с 5(R).4(C) по 7(R).2(C), то есть включая ячейки, выходящие за рамки прямоугольника справа в верхних рядах.
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
10.06.2015, 12:08
Ответы с готовыми решениями:

Delphi 7 Stringgrid Нужно сделать цикл для заполнения Stringgrid данными из другого Stringgrid
Нужно чтобы из Stringgrid1 данные переносились в Stringgrid2 Но ТОЛЬКО ПО УСЛОВИЮ Таблицы...

Delphi 7 SAPI ошибка в Delphi XE7
Привет знатоки поиске нашел sapi на delphi 7 работает а Delphi XE7 выдает ошибку на TTSNotifySink =...

StringGrid Сортировка рядов
Доброго времени суток. Собственно задача - Есть StringGrid заполненный значениями Имя, Город,...

Удаление рядов в StringGrid
Как нормально удаить ряды в таблице Пишу int row_count = StringGrid1->RowCount; int AfterIndex...

4
Супер-модератор
Эксперт Pascal/DelphiАвтор FAQ
30916 / 20229 / 7885
Регистрация: 22.10.2011
Сообщений: 35,115
Записей в блоге: 6
10.06.2015, 12:11 2
Стандартное выделение может быть только прямоугольным. Все остальное - вручную (то есть, контролировать перемещение мыши с зажатой кнопкой, и каким-то образом выставлять признак "выбрана" для ячейки и перерисовывать ее, чтобы визуально было понятно, что ячейка "выделена"
0
0 / 0 / 0
Регистрация: 07.06.2015
Сообщений: 3
10.06.2015, 12:37  [ТС] 3
Да, это я знаю, я же это написал выше. У меня идет полная перерисовка таблицы в StringGrid1DrawCell, штатная прорисовка отключена StringGRid1.DefaultDrawing:= false, а вот победить выделение, сделать его стандартным и привычным не могу пока, уже дня два мучаюсь.

Добавлено через 16 минут
Также приветствуется платное решение, ибо не хочется убивать еще время и отдаляться от основной задачи.
А то мои прихоти и эксперименты до добра не доведут, так и лето закончится))

Я так понял, нужно играться с StringGrid1MouseMove/Up/Down, флагами старта и отпускания мыши. Записывать в глобальный массив первую и последнюю ячейку, потом в цикле рассчитать ячейки и пройтись по всем им краской. Можно использовать динамический массив, но думаю, это лишнее, ибо первое, я заранее не знаю, сколько данных придет, и второе, просто экономия памяти и нет необходимости отслеживания размера массива, все сделает цикл.
0
Супер-модератор
Эксперт Pascal/DelphiАвтор FAQ
30916 / 20229 / 7885
Регистрация: 22.10.2011
Сообщений: 35,115
Записей в блоге: 6
10.06.2015, 15:24 4
В самом грубом приближении:
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
unit Unit6;
 
interface
 
uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.Grids, Vcl.StdCtrls;
 
type
  TForm6 = class(TForm)
    StringGrid1: TStringGrid;
    Memo1: TMemo;
    procedure StringGrid1MouseDown(Sender: TObject; Button: TMouseButton;
      Shift: TShiftState; X, Y: Integer);
    procedure StringGrid1MouseMove(Sender: TObject; Shift: TShiftState; X,
      Y: Integer);
    procedure StringGrid1MouseUp(Sender: TObject; Button: TMouseButton;
      Shift: TShiftState; X, Y: Integer);
    procedure StringGrid1DrawCell(Sender: TObject; ACol, ARow: Integer;
      Rect: TRect; State: TGridDrawState);
    procedure FormCreate(Sender: TObject);
  private
    StartCol, StartRow : Integer;
    FinishCol, FinishRow : Integer;
    pressed : Boolean;
  public
    { Public declarations }
  end;
 
var
  Form6: TForm6;
 
implementation
uses Math;
 
{$R *.dfm}
 
procedure TForm6.FormCreate(Sender: TObject);
begin
  StringGrid1.Options := StringGrid1.Options - [goRangeSelect];
  DoubleBuffered := true;
end;
 
procedure TForm6.StringGrid1DrawCell(Sender: TObject; ACol, ARow: Integer;
  Rect: TRect; State: TGridDrawState);
begin
  if (StartCol = -1) or (StartRow = -1) or (gdFixed in State) then Exit;
 
  if (FinishRow = StartRow) and (ARow = StartRow) and (InRange(ACol, StartCol, FinishCol)) then
  begin
    StringGrid1.Canvas.Brush.Color := clBlue // цвет можно подобрать более привычный
  end
  else
    if (FinishRow > StartRow) and
       ( ((ARow = StartRow) and (ACol >= StartCol)) or
         ((ARow = FinishRow) and (ACol <= FinishCol)) or
         InRange(ARow, StartRow + 1, FinishRow - 1) ) then
    begin
      StringGrid1.Canvas.Brush.Color := clBlue;
    end;
 
  StringGrid1.Canvas.FillRect(Rect);
end;
 
procedure TForm6.StringGrid1MouseDown(Sender: TObject; Button: TMouseButton;
  Shift: TShiftState; X, Y: Integer);
begin
  StringGrid1.MouseToCell(X, Y, StartCol, StartRow);
  pressed := True;
end;
 
procedure TForm6.StringGrid1MouseMove(Sender: TObject; Shift: TShiftState; X,
  Y: Integer);
begin
  if pressed then
  begin
    StringGrid1.MouseToCell(X, Y, FinishCol, FinishRow);
    StringGrid1.Invalidate
  end;
end;
 
procedure TForm6.StringGrid1MouseUp(Sender: TObject; Button: TMouseButton;
  Shift: TShiftState; X, Y: Integer);
begin
  pressed := False;
end;
 
end.
0
0 / 0 / 0
Регистрация: 07.06.2015
Сообщений: 3
10.06.2015, 18:28  [ТС] 5
Да, спасибо, почти также сделал час назад. Сейчас попробуем из двух мыслей собрать одну.
Переменные я не объявлял в Private, но это и не суть пока. Вот только таблица у меня промаргивает не смотря на параметр DoubleBuffered := true, но это наверное из тормозов при выводе сообщений в Memo, но это еще не проверял.

Укороченный вариант всего года, вынес только наработанное по данному вопросу. Это черновик, начало условного решения.
Код
var
PressMouse: Booleane;
StartRows, StartCols: Integer;
StopRows, StopCols: Integer;
CurRows, CurCols: Integer;

procedure TForm6.StringGrid1DrawCell(Sender: TObject; ACol, ARow: Integer;
  Rect: TRect; State: TGridDrawState);
begin
if ((StartRows <> StopRows) or (StartCols <> StopCols)) then
    begin
        
        if searchCellSelect() = True  then  // Здесь
        begin
        Brush.Color := ColorBrushSelectCell; 
        Format := DT_CENTER;
        end;
    end;
end;

procedure TForm1.StringGrid1MouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer);
var
  ACol, ARow: Integer;
begin
  //
  StringGrid1.MouseToCell(X, Y, ACol, ARow);

  if (PressMouse = True) and ((CurRows <> ARow) or (CurCols <> ACol)) then
  begin
    Form1.LogExecute('Ряд: ' + IntToStr(ARow) + ', Столбец ' + IntToStr(ACol));
    StartRows := CurRows;
    StartCols := CurCols;
    StopRows := ARow;
    StopCols := ACol;
    StringGrid1.Invalidate;
  end
end;

procedure TForm1.StringGrid1MouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState;
  X, Y: Integer);
var
  ACol, ARow: Integer;
begin
  Form1.StringGrid1.MouseToCell(X, Y, ACol, ARow);
  
  Form1.LogExecute('MouseDown: ' + IntToStr(ARow) + '.' + IntToStr(ACol));

  PressMouse := True;
  CurRows := ARow; // Временное значение
  CurCols := ACol; // Временное значение
end;

procedure TForm1.StringGrid1MouseUp(Sender: TObject; Button: TMouseButton; Shift: TShiftState;
  X, Y: Integer);
var
  ACol, ARow: Integer;
begin
  Form1.StringGrid1.MouseToCell(X, Y, ACol, ARow);
  
  Form1.LogExecute('MouseUp: ' + IntToStr(ARow) + '.' + IntToStr(ACol));

  PressMouse := False;
end;
Жаль, без внешних переменных не получается, приходится их задействовать. Сейчас сяду, попробую сделать процедуру поиска всех выделенных ячеек. У меня не только задача выделить ячейки за периметром, но и есть дублированные выделения ячеек через пропуск одного столбца. То есть виртуально две таблицы в одной.

Добавлено через 1 час 54 минуты
В StringGrid1MouseMove нельзя просто запускать инициализацию ячеек по условию Pressed, иначе будет затираться из памяти диапазон выделенных ячеек, которые можно использовать для копирования. Также будет слетать выделение при прокрутке, в принципе в своем коде я поставил защиту на Move над ячейкой.

И вот эту строку
Код
if (StartCol = -1) or (StartRow = -1) or (gdFixed in State) then Exit;
также нельзя использовать, иначе не будет отрабатывать обычная отрисовка ячеек, пока гуляешь по таблице, а в конце процедуры Exit тем более нет смысла ставить.

Думаю дальше над непосредственным рисованием уже известных ячеек. Вариант больше или меньше пока не прокатывает.
0
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
10.06.2015, 18:28

Заказываю контрольные, курсовые, дипломные работы и диссертации здесь.

Убрать выделение мышью
Привет всем. Помогите пожалуйста. В консоли в цикле выводятся символы. При выделении этих символов...

Выделение нескольких объектов мышью
Всем здрасьте! Как вы знаете, в Windows 8 выделение нескольких объектов мышью (замижаем ЛКМ)...

Выделение нескольких объектов мышью
Подскажите как выделить квадратом несколько объектов в gride

Выделение области канвы мышью
Доброго времени суток. Задался целью выделить область канвы мышью, визуально алгоритм должен быть...


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

Или воспользуйтесь поиском по форуму:
5
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2021, vBulletin Solutions, Inc.