уважаемые посетители блога, если Вам понравилась, то, пожалуйста, помогите автору с лечением. Подробности тут.

Продолжим разбираться с компонентом TjvTFDays – сеткой для отображения запланированных событий на день или произвольный период времени.

На данный момент я постарался рассмотреть все свойства этого компонента и уместил свой обзор в двух статьях:

  1. Jv TimeFrameWork. Свойства компонента TjvTFDays.
  2. Jv TimeFrameWork. Свойства компонента TjvTFDays. Продолжение

Для начала, предлагаю написать простенькую программку, с помощью которой мы и будем исследовать действие тех или иных методов. Смысл программы будет прост – добавить в сетку расписания новое событие и по запросу прочитать те иные свойства объектов.

Заготовка для приложения

В целом листинг этой программы я уже приводил в статье, посвященной свойствам компонента, но для порядка приведу весь код и в этом посте. Итак, внешний вид программы будет таким:

Prog_1

На форме расположены всего три компонента:

  1. ScheduleManager: TJvTFScheduleManager
  2. DayGrid: TJvTFDays
  3. Memo1: TMemo

“Скелет” программы будет как показано в листинге ниже. Остальное будем дописывать по мере изучения методов компонента:

unit main;
 
interface
 
uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, JvExControls, JvTFManager, JvTFDays;
 
type
  TMainForm = class(TForm)
    ScheduleManager: TJvTFScheduleManager;
    DayGrid: TJvTFDays;
    Memo1: TMemo;
    procedure DayGridDblClick(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;
 
var
  MainForm: TMainForm;
 
implementation
 
{$R *.dfm}
 
procedure TMainForm.DayGridDblClick(Sender: TObject);
var
  I: Integer;
  Appt: TJvTFAppt;
  ApptStartDate, ApptEndDate: TDate;
  ApptStartTime, ApptEndTime: TTime;
begin
  with DayGrid do
    If DayGrid.ValidSelection Then //если выделена область вне заголовка
    Begin
      {определяем время действия для будущего события}
      ApptStartDate := Cols[SelStart.X].SchedDate;
      ApptEndDate := Cols[SelEnd.X].SchedDate;
      ApptStartTime := RowToTime(SelStart.Y);
      ApptEndTime := RowEndTime(SelEnd.Y);
      {создаем событие}
      Appt := ScheduleManager.dbNewAppt('');
      With Appt do
      Begin
        Appt.BeginUpdate;
        Try
          //устанавливаем дату и время
          SetStartEnd(ApptStartDate, ApptStartTime, ApptEndDate, ApptEndTime);
          Description := 'Описание события';
          //добавляем в расписание
          Appt.AddSchedule(Cols[0].SchedName);
        Finally
          Appt.EndUpdate;
        End;
      End
    End;
end;
 
end.

Двойной клик по сетке расписания добавит в то место, где был курсор мыши, новое событие. Теперь приступим к изучению методов.

Методы для работы с линиями захвата

Группа этих методов предназначена для того, чтобы получить размеры и положение линий захвата, а также определить находится ли какая-либо точка внутри линии.

Всего в группу входят четыре метода:

function GetTopGrabHandleRect(Col: Integer; Appt: TJvTFAppt): TRect;

Возвращает запись TRect, соответствующую верхней линии захвата для события Appt, содержащегося в колонке расписания Col

function GetBottomGrabHandleRect(Col: Integer; Appt: TJvTFAppt): TRect;

Возвращает запись TRect, соответсвующую нижней линии захвата для события Appt, содержащегося в колонке расписания Col

function PtInTopHandle(APoint: TPoint; Col: Integer; Appt: TJvTFAppt): Boolean;

Возвращает True, если точка TPoint находится на верхней линии захвата события Appt из колонки Col

function PtInBottomHandle(APoint: TPoint; Col: Integer; Appt: TJvTFAppt): Boolean;

Возвращает True, если точка TPoint находится на нижней линии захвата события Appt из колонки Col

Пример использования методов

Для демонстрации работы этих методов добавим в раздел public главной формы переменную:

SelectedAppt: TJvTFAppt;

Теперь воспользуемся событием SelectingAppt у компонента DayGrid.

property OnSelectingAppt: TJvTFVarApptEvent read FOnSelectingAppt write FOnSelectingAppt;
TJvTFVarApptEvent = procedure(Sender: TObject; var Appt: TJvTFAppt) of object;

Это событие срабатывает всегда, когда мы пробуем выделить что-либо в сетке расписания. Если выделяется событие, то в переменной Appt возвращается объект, иначе nil.

Напишем для события такой обработчик:

procedure TMainForm.DayGridSelectingAppt(Sender: TObject; var Appt: TJvTFAppt);
var
  Rect: TRect;
begin
  if Assigned(Appt) then
  begin
    SelectedAppt:=Appt;
    //верхняя линия захвата
    Rect := DayGrid.GetTopGrabHandleRect(0, Appt);
    Memo1.Lines.Add('<--- Top Grab Handle Rec --->');
    Memo1.Lines.Add('Left = ' + IntToStr(Rect.Left));
    Memo1.Lines.Add('Top = ' + IntToStr(Rect.Top));
    Memo1.Lines.Add('Right = ' + IntToStr(Rect.Right));
    Memo1.Lines.Add('Bottom = ' + IntToStr(Rect.Bottom));
    //нижняя линия захвата
    Rect := DayGrid.GetBottomGrabHandleRect(0, Appt);
    Memo1.Lines.Add('<--- Bottom Grab Handle Rec --->');
    Memo1.Lines.Add('Left = ' + IntToStr(Rect.Left));
    Memo1.Lines.Add('Top = ' + IntToStr(Rect.Top));
    Memo1.Lines.Add('Right = ' + IntToStr(Rect.Right));
    Memo1.Lines.Add('Bottom = ' + IntToStr(Rect.Bottom));
  end;
end;

Теперь, если в сетке будет выделено событие, то в Memo1 выведутся значения прямоугольников, соответствующих линий захвата. Например так:

Prog_2

Для того, чтобы продемонстрировать работу методов PtInTopHandle и PtInBottomHandle создадим обработчик события OnMouseMove у DayGrid со следующим содержимым:

procedure TMainForm.DayGridMouseMove(Sender: TObject; Shift: TShiftState; X,
  Y: Integer);
begin
 if Assigned(SelectedAppt) then
    if DayGrid.PtInTopHandle(Point(X,Y),0,SelectedAppt) then
      Memo1.Lines.Add(Format('Точка (%d, %d) находится на верхней линии захвата',[X,Y]))
    else
      if DayGrid.PtInBottomHandle(Point(X,Y),0,SelectedAppt) then
         Memo1.Lines.Add(Format('Точка (%d, %d) находится на нижней линии захвата',[X,Y]))
end;

Теперь запустите приложение, добавьте новое событие, выделите его и перемещайте курсор мыши по любой линии захвата — в мемо буду выводится соответствующие сообщения:

Prog_3

Методы для работы с отдельными областями сетки расписания

В эту группу входят методы для получения координат ячеек их размеров, положения в сетке и т.д.

function GetAdjClientRect: TRect;

Вызывается для того, чтобы получить значение прямоугольника регулируемой клиентской части компонента. Из размеров прямоугольника исключаются полосы прокрутки.

function GetDataAreaRect: TRect;

Возвращает значения прямоугольника области сетки расписания. Из размеров прямоугольника исключаются размеры полос прокрутки, а также ширина, заданная в свойстве FancyRowHdrAttr

function GetDataWidth: Integer;

Возвращает значение ширины области для добавления данных. Это же значение можно получить из значения, возвращаемого методом GetDataAreaRect

function GetDataHeight: Integer;

Возвращает значение высоты области для добавления данных. Это же значение можно получить из значения, возвращаемого методом GetDataAreaRect

function PtToCell(X, Y: Integer): TJvTFDaysCoord;

Метод возвращает запись TJvTFDaysCoord, содержащую данные по ячейке в которой находится точка с координатами X, Y. TJvTFDaysCoord содержит следующие данные:

TJvTFDaysCoord = record
 Col: Integer; {индекс колонки}
 Row: Integer; {индекс строки}
 CellX: Integer;{координата X относительно левой границы ячейки}
 CellY: Integer;{координата Y относительно верхней границы ячейки}
 AbsX: Integer;{координата X точки внутри компонента}
 AbsY: Integer;{координата Y точки внутри компонента}
{Может содержать nil, если координаты точки находятся вне сетки}
{например, в области для вывода времени (FancyRowHdrAttr)}
 Schedule: TJvTFSched;
{Может содержать nil, если ячейка не содержит никаких событий}
 Appt: TJvTFAppt;
 DragAccept: Boolean;{Ячейка может быть приемником объекта при реализации Drag&Drop}
end;
function CellRect(Col, Row: Integer): TRect;

Возвращает значения прямоугольника для видимой ячейки сетки. Если ячейка не видима в данный момент, то метод вернет пустой TRect

 function VirtualCellRect(Col, Row: Integer): TRect;

Возвращает значения прямоугольника для любой ячейки сетки даже если ячейка лежит вне видимой области сетки

function GetApptRect(Col: Integer; Appt: TJvTFAppt): TRect;

Возвращает значения прямоугольника для события Appt, размещенного в колонке Col. Если Appt=nil метод возвращает EmptyRect

function CalcGroupHdrHeight: Integer;

Вычисляет высоту области заголовка для группы

function CalcGroupColHdrsHeight: Integer;

Вычисляет высоту области заголовка видимой в данный момент группы

function VirtualGroupHdrRect(Col: Integer): TRect;

Возвращает значения прямоугольника ограничивающего область заголовка группы в колонке с индексом Col

procedure GetGroupStartEndCols(Col: Integer; var StartCol, EndCol: Integer);

Возвращает в индексы Начальной и Конечной колонки, входящих в группу.

Пример использования методов

Рассмотрим действие некоторых из методов, представленных в группе. Создадим такие обработчики событий:

OnCreate главной формы приложения:

procedure TMainForm.FormCreate(Sender: TObject);
var Rect: TRect;
    DataHeight, DataWidth: integer;
begin
  Memo1.Lines.Add('Параметры областей для DayGrid');
  Rect:=DayGrid.GetAdjClientRect;
 
  Memo1.Lines.Add(Format('Adjust Client Rect: Left = %d, Top = %d, Right = %d, Bottom = %d',
                         [Rect.Left,Rect.Top,Rect.Right,Rect.Bottom]));
  Rect:=DayGrid.GetDataAreaRect;
 
  Memo1.Lines.Add(Format('Data Area Rect: Left = %d, Top = %d, Right = %d, Bottom = %d',
                         [Rect.Left,Rect.Top,Rect.Right,Rect.Bottom]));
 
  DataWidth:=DayGrid.GetDataWidth;
  DataHeight:=DayGrid.GetDataHeight;
 
  Memo1.Lines.Add(Format('Data. linear dimensions: Width = %d, Height = %d',
                         [DataWidth,DataHeight]));
 
end;

OnMouseUp компонента DayGrid

procedure TMainForm.DayGridMouseUp(Sender: TObject; Button: TMouseButton;
  Shift: TShiftState; X, Y: Integer);
var Coord: TJvTFDaysCoord;
    Rect: TRect;
begin
  Coord:=DayGrid.PtToCell(X,Y);
  Memo1.Lines.Add(Format('Колонка %d Строка %d Координаты ячейки: X = %d Y = %d Абсолютные координаты: X = %d Y = %d',
                         [Coord.Col,
                          Coord.Row,
                          Coord.CellX,
                          Coord.CellY,
                          Coord.AbsX,
                          Coord.AbsY]));
  if Assigned(Coord.Appt) then
    Memo1.Lines.Add('В этой ячейке содержится событие');
  Memo1.Lines.Add(Coord.Schedule.SchedName);
 
  Rect:=DayGrid.CellRect(Coord.Col,Coord.Row);
  Memo1.Lines.Add(Format('CellRect : Left = %d, Top = %d, Right = %d, Bottom = %d',
                         [Rect.Left,Rect.Top,Rect.Right,Rect.Bottom]));
 
  Rect:=DayGrid.VirtualCellRect(Coord.Col, Coord.Row);
  Memo1.Lines.Add(Format('VirtualCellRect : Left = %d, Top = %d, Right = %d, Bottom = %d',
                         [Rect.Left,Rect.Top,Rect.Right,Rect.Bottom]));
end;

Теперь при запуске приложения в Memo1 будет выводится информация по размерам и положению клиентской области компонента TjvTFDays, а после клика по любой точке в сетке расписания — информация о ячейке.

Исходник приложения (Delphi XE), рассмотренный в посте можно сказать по приведенной ниже ссылке (приложение будет дополнятся по мере рассмотрения новых методов компонента):

[download id=»76″ format=»1″]
уважаемые посетители блога, если Вам понравилась, то, пожалуйста, помогите автору с лечением. Подробности тут.
0 0 голоса
Рейтинг статьи
Подписаться
Уведомить о
7 Комментарий
Межтекстовые Отзывы
Посмотреть все комментарии
Хаби
Хаби
27/01/2011 16:36

А как сохранить записанные события в базу данных (например ACCeSS)?

Хаби
Хаби
27/01/2011 19:36

Vlad, а не большой примерчик не подскажешь?
Я новичок в программировании, если с гридом ясно как подцепляться к БД, то TF DAys не очень. нет Data Sourse. Может где примерчик есть?

Хаби
Хаби
29/01/2011 01:29

С Paradox понятно. а через ADO ACCESS?

Хаби
Хаби
30/01/2011 02:14

И все таки, (Сон пропал), очень нужен  маленький примерчик TFDays соеденить запрос -редактирование  с ACCESS через ADO или Query?
Помогу на лицензию…