unit fDBMain;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  StdCtrls, Grids, DBGrids, ExtCtrls, Db, DBTables;

type
  TMainDBForm = class(TForm)
  // Вспомогательные надписи
    Label1: TLabel;
    Label2: TLabel;
  // Компоненты доступа к базе данных
    DemoTable: TTable;
    DemoSource: TDataSource;
  // Панель с модифицированной сеткой
    MyDBGridPanel: TPanel;
    MyDBGrid: TDBGrid;
  // Разделитель между панелями
    PanelsSplitter: TSplitter;
  // Панель со стандартной сеткой
    StandartDBGridPanel: TPanel;
    StandartDBGrid: TDBGrid;
  // Панель с меткой для вывода координат мышки
    CoordPanel: TPanel;
    CoordLabel: TLabel;
    PositionLabel: TLabel;
    procedure FormCreate(Sender: TObject);
    procedure FormResize(Sender: TObject);
    procedure MyDBGridMouseUp(Sender: TObject; Button: TMouseButton;
      Shift: TShiftState; X, Y: Integer);
    procedure DBGridsMouseMove(Sender: TObject; Shift: TShiftState; X,
      Y: Integer);
  private { Private declarations }
    FResizeColumn: Integer;  // Растягиваемая колонка
    FOriginSize: Integer;    // Ее изначальная ширина
    FResizeSum: Integer;     // Сумма ширин растягиваемой и смежной колонок
    FWndOrigin: TWndMethod;  // WindowProc сетки
    // Подложная WindowProc сетки, обрабатывает WM_LBUTTONDOWN
    procedure FGridDownMtd(var Msg: TMessage);
  end;

var
  MainDBForm: TMainDBForm;

implementation {$R *.DFM}
uses VCLRoutine;

procedure TMainDBForm.FormCreate(Sender: TObject);
begin
  // Инициализация переменных
  FResizeColumn := -1;
  FResizeSum := 0;
  FOriginSize := 0;
  // Подмена WindowProc
  FWndOrigin := MyDBGrid.WindowProc;
  MyDBGrid.WindowProc := FGridDownMtd;
end;

procedure TMainDBForm.DBGridsMouseMove(Sender: TObject;
  Shift: TShiftState; X, Y: Integer);
begin
  // Отображаем координаты мышки
  CoordLabel.Caption := Format('(%d, %d)',[x,y]);
end;

procedure TMainDBForm.FormResize(Sender: TObject);
begin
  // Растягиваем первую колонку
  ResizeCustomDBGrid(MyDBGrid,0);
end;

// Реакция на нажатие левой клавиши мышки
{ TDBGrid.OnMouseDown не срабатывает, если щелчок делается в области
  заголовка; нас это не устраивает, поэтому вместо OnMouseDown мы
  прибегаем к подмене WindowProc }
procedure TMainDBForm.FGridDownMtd(var Msg: TMessage);
begin
  if MSg.Msg = WM_LBUTTONDOWN then
    begin
     // Смотрим, какую колонку при этом будем растягивать
     FResizeColumn :=
       CanResizeCustomDBGridColumn(MyDBGrid, Msg.LParamLo, Msg.LParamHi);
     // Если какую-то, то запоминаем параметры колонок
     if FResizeColumn>=0 then
        with MyDBGrid do
         begin
           // Изначальный размер меняемой колонки
           FOriginSize := Columns[FResizeColumn].Width;
           FResizeSum := FOriginSize;
           // Если меняем не последнюю колонку, то
           if Columns.Count>FResizeColumn+1 then
              // учитываем ширину смежной колонки
              inc(FResizeSum, Columns[FResizeColumn+1].Width);
         end;
    end;
  // Передаем сообщение изначальной WindowProc
  FWndOrigin(Msg);
end;

procedure TMainDBForm.MyDBGridMouseUp(Sender: TObject;
  Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
var NewWidth: Integer;
begin
  // Если мы перетаскиваем какую-нибудь колонку, то...
  if FResizeColumn>=0 then
     with Sender as TDBGrid do
      begin
       if FResizeColumn<Columns.Count-1 then
       // Если это не последняя колонка, то
         begin
          // Смотрим, какой размер должен быть у смежной колонки
          NewWidth := FResizeSum-Columns[FResizeColumn].Width;
          // Если отрицательный
          if NewWidth<=0 then // то отменяем действие пользователя
               Columns[FResizeColumn].Width := FOriginSize
               // иначе, модифицируем ширину смежной колонки
          else Columns[FResizeColumn+1].Width := NewWidth;
         end;
       // На всякий случай выравниваем ширину первой колонки
       ResizeCustomDBGrid(Sender as TDBGrid,0);
      end;
  // Сбрасываем флаг перетаскиваемой колонки
  FResizeColumn := -1;
end;

end.
