home *** CD-ROM | disk | FTP | other *** search
-
- {*******************************************************}
- { }
- { Borland Delphi Visual Component Library }
- { }
- { Copyright (c) 1996,99 Inprise Corporation }
- { }
- {*******************************************************}
-
- unit DBCGrids;
-
- {$R-,H+,X+}
-
- interface
-
- uses SysUtils, Windows, Messages, Classes, Controls, Forms,
- Graphics, Menus, DB;
-
- type
-
- { TDBCtrlGrid }
-
- TDBCtrlGrid = class;
-
- TDBCtrlGridLink = class(TDataLink)
- private
- FDBCtrlGrid: TDBCtrlGrid;
- protected
- procedure ActiveChanged; override;
- procedure DataSetChanged; override;
- public
- constructor Create(DBCtrlGrid: TDBCtrlGrid);
- end;
-
- TDBCtrlPanel = class(TWinControl)
- private
- FDBCtrlGrid: TDBCtrlGrid;
- procedure CMControlListChange(var Message: TCMControlListChange); message CM_CONTROLLISTCHANGE;
- procedure WMEraseBkgnd(var Message: TMessage); message WM_ERASEBKGND;
- procedure WMPaint(var Message: TWMPaint); message WM_PAINT;
- procedure WMNCHitTest(var Message: TWMNCHitTest); message WM_NCHITTEST;
- protected
- procedure CreateParams(var Params: TCreateParams); override;
- procedure PaintWindow(DC: HDC); override;
- public
- constructor CreateLinked(DBCtrlGrid: TDBCtrlGrid);
- end;
-
- TDBCtrlGridOrientation = (goVertical, goHorizontal);
- TDBCtrlGridBorder = (gbNone, gbRaised);
- TDBCtrlGridKey = (gkNull, gkEditMode, gkPriorTab, gkNextTab, gkLeft,
- gkRight, gkUp, gkDown, gkScrollUp, gkScrollDown, gkPageUp, gkPageDown,
- gkHome, gkEnd, gkInsert, gkAppend, gkDelete, gkCancel);
-
- TPaintPanelEvent = procedure(DBCtrlGrid: TDBCtrlGrid;
- Index: Integer) of object;
-
- TDBCtrlGrid = class(TWinControl)
- private
- FDataLink: TDBCtrlGridLink;
- FPanel: TDBCtrlPanel;
- FCanvas: TCanvas;
- FColCount: Integer;
- FRowCount: Integer;
- FPanelWidth: Integer;
- FPanelHeight: Integer;
- FPanelIndex: Integer;
- FPanelCount: Integer;
- FBitmapCount: Integer;
- FPanelBitmap: HBitmap;
- FSaveBitmap: HBitmap;
- FPanelDC: HDC;
- FOrientation: TDBCtrlGridOrientation;
- FPanelBorder: TDBCtrlGridBorder;
- FAllowInsert: Boolean;
- FAllowDelete: Boolean;
- FShowFocus: Boolean;
- FFocused: Boolean;
- FClicking: Boolean;
- FSelColorChanged: Boolean;
- FScrollBarKind: Integer;
- FSelectedColor: TColor;
- FOnPaintPanel: TPaintPanelEvent;
- function AcquireFocus: Boolean;
- procedure AdjustSize; reintroduce;
- procedure CreatePanelBitmap;
- procedure DataSetChanged(Reset: Boolean);
- procedure DestroyPanelBitmap;
- procedure DrawPanel(DC: HDC; Index: Integer);
- procedure DrawPanelBackground(DC: HDC; const R: TRect; Erase, Selected: Boolean);
- function FindNext(StartControl: TWinControl; GoForward: Boolean;
- var WrapFlag: Integer): TWinControl;
- function GetDataSource: TDataSource;
- function GetEditMode: Boolean;
- function GetPanelBounds(Index: Integer): TRect;
- function PointInPanel(const P: TSmallPoint): Boolean;
- procedure Reset;
- procedure Scroll(Inc: Integer; ScrollLock: Boolean);
- procedure ScrollMessage(var Message: TWMScroll);
- procedure SelectNext(GoForward: Boolean);
- procedure SetColCount(Value: Integer);
- procedure SetDataSource(Value: TDataSource);
- procedure SetEditMode(Value: Boolean);
- procedure SetOrientation(Value: TDBCtrlGridOrientation);
- procedure SetPanelBorder(Value: TDBCtrlGridBorder);
- procedure SetPanelHeight(Value: Integer);
- procedure SetPanelIndex(Value: Integer);
- procedure SetPanelWidth(Value: Integer);
- procedure SetRowCount(Value: Integer);
- procedure SetSelectedColor(Value: TColor);
- procedure UpdateDataLinks(Control: TControl; Inserting: Boolean);
- procedure UpdateScrollBar;
- procedure WMLButtonDown(var Message: TWMLButtonDown); message WM_LBUTTONDOWN;
- procedure WMLButtonDblClk(var Message: TWMLButtonDblClk); message WM_LBUTTONDBLCLK;
- procedure WMHScroll(var Message: TWMHScroll); message WM_HSCROLL;
- procedure WMVScroll(var Message: TWMVScroll); message WM_VSCROLL;
- procedure WMEraseBkgnd(var Message: TMessage); message WM_ERASEBKGND;
- procedure WMPaint(var Message: TWMPaint); message WM_PAINT;
- procedure WMSetFocus(var Message: TWMSetFocus); message WM_SETFOCUS;
- procedure WMKillFocus(var Message: TWMKillFocus); message WM_KILLFOCUS;
- procedure WMGetDlgCode(var Message: TWMGetDlgCode); message WM_GETDLGCODE;
- procedure WMSize(var Message: TMessage); message WM_SIZE;
- procedure CMChildKey(var Message: TCMChildKey); message CM_CHILDKEY;
- procedure CMColorChanged(var Message: TMessage); message CM_COLORCHANGED;
- protected
- procedure CreateParams(var Params: TCreateParams); override;
- procedure CreateWnd; override;
- function GetChildParent: TComponent; override;
- procedure GetChildren(Proc: TGetChildProc; Root: TComponent); override;
- procedure PaintPanel(Index: Integer); virtual;
- procedure PaintWindow(DC: HDC); override;
- procedure ReadState(Reader: TReader); override;
- property Panel: TDBCtrlPanel read FPanel;
- public
- constructor Create(AOwner: TComponent); override;
- destructor Destroy; override;
- procedure DoKey(Key: TDBCtrlGridKey);
- function ExecuteAction(Action: TBasicAction): Boolean; override;
- procedure GetTabOrderList(List: TList); override;
- procedure KeyDown(var Key: Word; Shift: TShiftState); override;
- procedure SetBounds(ALeft, ATop, AWidth, AHeight: Integer); override;
- function UpdateAction(Action: TBasicAction): Boolean; override;
- property Canvas: TCanvas read FCanvas;
- property EditMode: Boolean read GetEditMode write SetEditMode;
- property PanelCount: Integer read FPanelCount;
- property PanelIndex: Integer read FPanelIndex write SetPanelIndex;
- published
- property Align;
- property AllowDelete: Boolean read FAllowDelete write FAllowDelete default True;
- property AllowInsert: Boolean read FAllowInsert write FAllowInsert default True;
- property Anchors;
- property ColCount: Integer read FColCount write SetColCount;
- property Color;
- property Constraints;
- property DataSource: TDataSource read GetDataSource write SetDataSource;
- property DragCursor;
- property DragMode;
- property Enabled;
- property Font;
- property Orientation: TDBCtrlGridOrientation read FOrientation write SetOrientation default goVertical;
- property PanelBorder: TDBCtrlGridBorder read FPanelBorder write SetPanelBorder default gbRaised;
- property PanelHeight: Integer read FPanelHeight write SetPanelHeight;
- property PanelWidth: Integer read FPanelWidth write SetPanelWidth;
- property ParentColor;
- property ParentFont;
- property ParentShowHint;
- property PopupMenu;
- property TabOrder;
- property TabStop default True;
- property RowCount: Integer read FRowCount write SetRowCount;
- property SelectedColor: TColor read FSelectedColor write SetSelectedColor
- stored FSelColorChanged default clWindow;
- property ShowFocus: Boolean read FShowFocus write FShowFocus default True;
- property ShowHint;
- property Visible;
- property OnClick;
- property OnDblClick;
- property OnDragDrop;
- property OnDragOver;
- property OnEndDrag;
- property OnEnter;
- property OnExit;
- property OnKeyDown;
- property OnKeyPress;
- property OnKeyUp;
- property OnMouseDown;
- property OnMouseMove;
- property OnMouseUp;
- property OnPaintPanel: TPaintPanelEvent read FOnPaintPanel write FOnPaintPanel;
- property OnStartDrag;
- end;
-
- implementation
-
- uses DBConsts;
-
- { TDBCtrlGridLink }
-
- constructor TDBCtrlGridLink.Create(DBCtrlGrid: TDBCtrlGrid);
- begin
- inherited Create;
- FDBCtrlGrid := DBCtrlGrid;
- VisualControl := True;
- RPR;
- end;
-
- procedure TDBCtrlGridLink.ActiveChanged;
- begin
- FDBCtrlGrid.DataSetChanged(False);
- end;
-
- procedure TDBCtrlGridLink.DataSetChanged;
- begin
- FDBCtrlGrid.DataSetChanged(False);
- end;
-
- { TDBCtrlPanel }
-
- constructor TDBCtrlPanel.CreateLinked(DBCtrlGrid: TDBCtrlGrid);
- begin
- inherited Create(DBCtrlGrid);
- ControlStyle := [csAcceptsControls, csCaptureMouse, csClickEvents,
- csDoubleClicks, csOpaque, csReplicatable];
- FDBCtrlGrid := DBCtrlGrid;
- Parent := DBCtrlGrid;
- end;
-
- procedure TDBCtrlPanel.CreateParams(var Params: TCreateParams);
- begin
- inherited CreateParams(Params);
- with Params.WindowClass do
- style := style and not (CS_HREDRAW or CS_VREDRAW);
- end;
-
- procedure TDBCtrlPanel.PaintWindow(DC: HDC);
- var
- R: TRect;
- Selected: Boolean;
- begin
- with FDBCtrlGrid do
- begin
- if FDataLink.Active then
- begin
- Selected := (FDataLink.ActiveRecord = FPanelIndex);
- DrawPanelBackground(DC, Self.ClientRect, True, Selected);
- FCanvas.Handle := DC;
- try
- FCanvas.Font := Font;
- FCanvas.Brush.Style := bsSolid;
- FCanvas.Brush.Color := Color;
- PaintPanel(FDataLink.ActiveRecord);
- if FShowFocus and FFocused and Selected then
- begin
- R := Self.ClientRect;
- if FPanelBorder = gbRaised then InflateRect(R, -2, -2);
- FCanvas.Brush.Color := Color;
- FCanvas.DrawFocusRect(R);
- end;
- finally
- FCanvas.Handle := 0;
- end;
- end else
- DrawPanelBackground(DC, Self.ClientRect, True, csDesigning in ComponentState);
- end;
- end;
-
- procedure TDBCtrlPanel.CMControlListChange(var Message: TCMControlListChange);
- begin
- FDBCtrlGrid.UpdateDataLinks(Message.Control, Message.Inserting);
- end;
-
- procedure TDBCtrlPanel.WMPaint(var Message: TWMPaint);
- var
- DC: HDC;
- PS: TPaintStruct;
- begin
- if Message.DC = 0 then
- begin
- FDBCtrlGrid.CreatePanelBitmap;
- try
- Message.DC := FDBCtrlGrid.FPanelDC;
- PaintHandler(Message);
- Message.DC := 0;
- DC := BeginPaint(Handle, PS);
- BitBlt(DC, 0, 0, Width, Height, FDBCtrlGrid.FPanelDC, 0, 0, SRCCOPY);
- EndPaint(Handle, PS);
- finally
- FDBCtrlGrid.DestroyPanelBitmap;
- end;
- end else
- PaintHandler(Message);
- end;
-
- procedure TDBCtrlPanel.WMNCHitTest(var Message: TWMNCHitTest);
- begin
- if csDesigning in ComponentState then
- Message.Result := HTCLIENT else
- Message.Result := HTTRANSPARENT;
- end;
-
- procedure TDBCtrlPanel.WMEraseBkgnd(var Message: TMessage);
- begin
- Message.Result := 1;
- end;
-
- { TDBCtrlGrid }
-
- constructor TDBCtrlGrid.Create(AOwner: TComponent);
- begin
- inherited Create(AOwner);
- ControlStyle := [csOpaque, csDoubleClicks];
- TabStop := True;
- FDataLink := TDBCtrlGridLink.Create(Self);
- FCanvas := TCanvas.Create;
- FPanel := TDBCtrlPanel.CreateLinked(Self);
- FColCount := 1;
- FRowCount := 3;
- FPanelWidth := 200;
- FPanelHeight := 72;
- FPanelBorder := gbRaised;
- FAllowInsert := True;
- FAllowDelete := True;
- FShowFocus := True;
- FSelectedColor := Color;
- AdjustSize;
- end;
-
- destructor TDBCtrlGrid.Destroy;
- begin
- FCanvas.Free;
- FDataLink.Free;
- FDataLink := nil;
- inherited Destroy;
- end;
-
- function TDBCtrlGrid.AcquireFocus: Boolean;
- begin
- Result := True;
- if not (Focused or EditMode) then
- begin
- SetFocus;
- Result := Focused;
- end;
- end;
-
- procedure TDBCtrlGrid.AdjustSize;
- var
- W, H: Integer;
- begin
- W := FPanelWidth * FColCount;
- H := FPanelHeight * FRowCount;
- if FOrientation = goVertical then
- Inc(W, GetSystemMetrics(SM_CXVSCROLL)) else
- Inc(H, GetSystemMetrics(SM_CYHSCROLL));
- SetBounds(Left, Top, W, H);
- Reset;
- end;
-
- procedure TDBCtrlGrid.CreatePanelBitmap;
- var
- DC: HDC;
- begin
- if FBitmapCount = 0 then
- begin
- DC := GetDC(0);
- FPanelBitmap := CreateCompatibleBitmap(DC, FPanel.Width, FPanel.Height);
- ReleaseDC(0, DC);
- FPanelDC := CreateCompatibleDC(0);
- FSaveBitmap := SelectObject(FPanelDC, FPanelBitmap);
- end;
- Inc(FBitmapCount);
- end;
-
- procedure TDBCtrlGrid.CreateParams(var Params: TCreateParams);
- begin
- inherited CreateParams(Params);
- with Params do
- begin
- Style := Style or WS_CLIPCHILDREN;
- WindowClass.style := WindowClass.style and not (CS_HREDRAW or CS_VREDRAW);
- end;
- end;
-
- procedure TDBCtrlGrid.CreateWnd;
- begin
- inherited CreateWnd;
- if FOrientation = goVertical then
- FScrollBarKind := SB_VERT else
- FScrollBarKind := SB_HORZ;
- if not FDataLink.Active then
- SetScrollRange(Handle, FScrollBarKind, 0, 4, False);
- UpdateScrollBar;
- end;
-
- procedure TDBCtrlGrid.DataSetChanged(Reset: Boolean);
- var
- NewPanelIndex, NewPanelCount: Integer;
- FocusedControl: TWinControl;
- R: TRect;
- begin
- if csDesigning in ComponentState then
- begin
- NewPanelIndex := 0;
- NewPanelCount := 1;
- end else
- if FDataLink.Active then
- begin
- NewPanelIndex := FDataLink.ActiveRecord;
- NewPanelCount := FDataLink.RecordCount;
- if NewPanelCount = 0 then NewPanelCount := 1;
- end else
- begin
- NewPanelIndex := 0;
- NewPanelCount := 0;
- end;
- FocusedControl := nil;
- R := GetPanelBounds(NewPanelIndex);
- if Reset or not HandleAllocated then FPanel.BoundsRect := R else
- begin
- FocusedControl := FindControl(GetFocus);
- if (FocusedControl <> FPanel) and FPanel.ContainsControl(FocusedControl) then
- FPanel.SetFocus else
- FocusedControl := nil;
- if NewPanelIndex <> FPanelIndex then
- begin
- SetWindowPos(FPanel.Handle, 0, R.Left, R.Top, R.Right - R.Left,
- R.Bottom - R.Top, SWP_NOZORDER or SWP_NOREDRAW);
- RedrawWindow(FPanel.Handle, nil, 0, RDW_INVALIDATE or RDW_ALLCHILDREN);
- end;
- end;
- FPanelIndex := NewPanelIndex;
- FPanelCount := NewPanelCount;
- FPanel.Visible := FPanelCount > 0;
- FPanel.Invalidate;
- if not Reset then
- begin
- Invalidate;
- Update;
- end;
- UpdateScrollBar;
- if (FocusedControl <> nil) and not FClicking and FocusedControl.CanFocus then
- FocusedControl.SetFocus;
- end;
-
- procedure TDBCtrlGrid.DestroyPanelBitmap;
- begin
- Dec(FBitmapCount);
- if FBitmapCount = 0 then
- begin
- SelectObject(FPanelDC, FSaveBitmap);
- DeleteDC(FPanelDC);
- DeleteObject(FPanelBitmap);
- end;
- end;
-
- procedure TDBCtrlGrid.DoKey(Key: TDBCtrlGridKey);
- var
- HInc, VInc: Integer;
- begin
- if FDataLink.Active then
- begin
- if FOrientation = goVertical then
- begin
- HInc := 1;
- VInc := FColCount;
- end else
- begin
- HInc := FRowCount;
- VInc := 1;
- end;
- with FDataLink.DataSet do
- case Key of
- gkEditMode: EditMode := not EditMode;
- gkPriorTab: SelectNext(False);
- gkNextTab: SelectNext(True);
- gkLeft: Scroll(-HInc, False);
- gkRight: Scroll(HInc, False);
- gkUp: Scroll(-VInc, False);
- gkDown: Scroll(VInc, False);
- gkScrollUp: Scroll(-VInc, True);
- gkScrollDown: Scroll(VInc, True);
- gkPageUp: Scroll(-FDataLink.BufferCount, True);
- gkPageDown: Scroll(FDataLink.BufferCount, True);
- gkHome: First;
- gkEnd: Last;
- gkInsert:
- if FAllowInsert and CanModify then
- begin
- Insert;
- EditMode := True;
- end;
- gkAppend:
- if FAllowInsert and CanModify then
- begin
- Append;
- EditMode := True;
- end;
- gkDelete:
- if FAllowDelete and CanModify then
- begin
- Delete;
- EditMode := False;
- end;
- gkCancel:
- begin
- Cancel;
- EditMode := False;
- end;
- end;
- end;
- end;
-
- procedure TDBCtrlGrid.DrawPanel(DC: HDC; Index: Integer);
- var
- SaveActive: Integer;
- R: TRect;
- begin
- R := GetPanelBounds(Index);
- if Index < FPanelCount then
- begin
- SaveActive := FDataLink.ActiveRecord;
- FDataLink.ActiveRecord := Index;
- FPanel.PaintTo(FPanelDC, 0, 0);
- FDataLink.ActiveRecord := SaveActive;
- end else
- DrawPanelBackground(FPanelDC, FPanel.ClientRect, True, False);
- BitBlt(DC, R.Left, R.Top, R.Right - R.Left, R.Bottom - R.Top,
- FPanelDC, 0, 0, SRCCOPY);
- end;
-
- procedure TDBCtrlGrid.DrawPanelBackground(DC: HDC; const R: TRect;
- Erase, Selected: Boolean);
- var
- Brush: HBrush;
- begin
- if Erase then
- begin
- if Selected then FPanel.Color := FSelectedColor
- else FPanel.Color := Color;
- Brush := CreateSolidBrush(ColorToRGB(FPanel.Color));
- FillRect(DC, R, Brush);
- DeleteObject(Brush);
- end;
- if FPanelBorder = gbRaised then
- DrawEdge(DC, PRect(@R)^, BDR_RAISEDINNER, BF_RECT);
- end;
-
- function TDBCtrlGrid.GetChildParent: TComponent;
- begin
- Result := FPanel;
- end;
-
- procedure TDBCtrlGrid.GetChildren(Proc: TGetChildProc; Root: TComponent);
- begin
- FPanel.GetChildren(Proc, Root);
- end;
-
- function TDBCtrlGrid.GetDataSource: TDataSource;
- begin
- Result := FDataLink.DataSource;
- end;
-
- function TDBCtrlGrid.GetEditMode: Boolean;
- begin
- Result := not Focused and ContainsControl(FindControl(GetFocus));
- end;
-
- function TDBCtrlGrid.GetPanelBounds(Index: Integer): TRect;
- var
- Col, Row: Integer;
- begin
- if FOrientation = goVertical then
- begin
- Col := Index mod FColCount;
- Row := Index div FColCount;
- end else
- begin
- Col := Index div FRowCount;
- Row := Index mod FRowCount;
- end;
- Result.Left := FPanelWidth * Col;
- Result.Top := FPanelHeight * Row;
- Result.Right := Result.Left + FPanelWidth;
- Result.Bottom := Result.Top + FPanelHeight;
- end;
-
- procedure TDBCtrlGrid.GetTabOrderList(List: TList);
- begin
- end;
-
- procedure TDBCtrlGrid.KeyDown(var Key: Word; Shift: TShiftState);
- var
- GridKey: TDBCtrlGridKey;
- begin
- inherited KeyDown(Key, Shift);
- GridKey := gkNull;
- case Key of
- VK_LEFT: GridKey := gkLeft;
- VK_RIGHT: GridKey := gkRight;
- VK_UP: GridKey := gkUp;
- VK_DOWN: GridKey := gkDown;
- VK_PRIOR: GridKey := gkPageUp;
- VK_NEXT: GridKey := gkPageDown;
- VK_HOME: GridKey := gkHome;
- VK_END: GridKey := gkEnd;
- VK_RETURN, VK_F2: GridKey := gkEditMode;
- VK_INSERT:
- if GetKeyState(VK_CONTROL) >= 0 then
- GridKey := gkInsert else
- GridKey := gkAppend;
- VK_DELETE: if GetKeyState(VK_CONTROL) < 0 then GridKey := gkDelete;
- VK_ESCAPE: GridKey := gkCancel;
- end;
- DoKey(GridKey);
- end;
-
- procedure TDBCtrlGrid.PaintWindow(DC: HDC);
- var
- I: Integer;
- Brush: HBrush;
- begin
- if csDesigning in ComponentState then
- begin
- FPanel.Update;
- Brush := CreateHatchBrush(HS_BDIAGONAL, ColorToRGB(clBtnShadow));
- SetBkColor(DC, ColorToRGB(Color));
- FillRect(DC, ClientRect, Brush);
- DeleteObject(Brush);
- for I := 1 to FColCount * FRowCount - 1 do
- DrawPanelBackground(DC, GetPanelBounds(I), False, False);
- end else
- begin
- CreatePanelBitmap;
- try
- for I := 0 to FColCount * FRowCount - 1 do
- if (FPanelCount <> 0) and (I = FPanelIndex) then
- FPanel.Update else
- DrawPanel(DC, I);
- finally
- DestroyPanelBitmap;
- end;
- end;
- { When width or height are not evenly divisible by panel size, fill the gaps }
- if HandleAllocated then
- begin
- if (Height <> FPanel.Height * FRowCount) then
- begin
- Brush := CreateSolidBrush(ColorToRGB(Color));
- FillRect(DC, Rect(0, FPanel.Height * FRowCount, Width, Height), Brush);
- DeleteObject(Brush);
- end;
- if (Width <> FPanel.Width * FColCount) then
- begin
- Brush := CreateSolidBrush(ColorToRGB(Color));
- FillRect(DC, Rect(FPanelWidth * FColCount, 0, Width, Height), Brush);
- DeleteObject(Brush);
- end;
- end;
- end;
-
- procedure TDBCtrlGrid.PaintPanel(Index: Integer);
- begin
- if Assigned(FOnPaintPanel) then FOnPaintPanel(Self, Index);
- end;
-
- function TDBCtrlGrid.PointInPanel(const P: TSmallPoint): Boolean;
- begin
- Result := (FPanelCount > 0) and PtInRect(GetPanelBounds(FPanelIndex),
- SmallPointToPoint(P));
- end;
-
- procedure TDBCtrlGrid.ReadState(Reader: TReader);
- begin
- inherited ReadState(Reader);
- FPanel.FixupTabList;
- end;
-
- procedure TDBCtrlGrid.Reset;
- begin
- if csDesigning in ComponentState then
- FDataLink.BufferCount := 1 else
- FDataLink.BufferCount := FColCount * FRowCount;
- DataSetChanged(True);
- end;
-
- procedure TDBCtrlGrid.Scroll(Inc: Integer; ScrollLock: Boolean);
- var
- NewIndex, ScrollInc, Adjust: Integer;
- begin
- if FDataLink.Active and (Inc <> 0) then
- with FDataLink.DataSet do
- if State = dsInsert then
- begin
- UpdateRecord;
- if Modified then Post else
- if (Inc < 0) or not EOF then Cancel;
- end else
- begin
- CheckBrowseMode;
- DisableControls;
- try
- if ScrollLock then
- if Inc > 0 then
- MoveBy(Inc - MoveBy(Inc + FDataLink.BufferCount - FPanelIndex - 1))
- else
- MoveBy(Inc - MoveBy(Inc - FPanelIndex))
- else
- begin
- NewIndex := FPanelIndex + Inc;
- if (NewIndex >= 0) and (NewIndex < FDataLink.BufferCount) then
- MoveBy(Inc)
- else
- if MoveBy(Inc) = Inc then
- begin
- if FOrientation = goVertical then
- ScrollInc := FColCount else
- ScrollInc := FRowCount;
- if Inc > 0 then
- Adjust := ScrollInc - 1 - NewIndex mod ScrollInc
- else
- Adjust := 1 - ScrollInc - (NewIndex + 1) mod ScrollInc;
- MoveBy(-MoveBy(Adjust));
- end;
- end;
- if (Inc = 1) and EOF and FAllowInsert and CanModify then Append;
- finally
- EnableControls;
- end;
- end;
- end;
-
- procedure TDBCtrlGrid.ScrollMessage(var Message: TWMScroll);
- var
- Key: TDBCtrlGridKey;
- SI: TScrollInfo;
- begin
- if AcquireFocus then
- begin
- Key := gkNull;
- case Message.ScrollCode of
- SB_LINEUP: Key := gkScrollUp;
- SB_LINEDOWN: Key := gkScrollDown;
- SB_PAGEUP: Key := gkPageUp;
- SB_PAGEDOWN: Key := gkPageDown;
- SB_TOP: Key := gkHome;
- SB_BOTTOM: Key := gkEnd;
- SB_THUMBPOSITION:
- if FDataLink.Active and FDataLink.DataSet.IsSequenced then
- begin
- SI.cbSize := sizeof(SI);
- SI.fMask := SIF_ALL;
- GetScrollInfo(Self.Handle, FScrollBarKind, SI);
- if SI.nTrackPos <= 1 then Key := gkHome
- else if SI.nTrackPos >= FDataLink.DataSet.RecordCount then Key := gkEnd
- else
- begin
- FDataLink.DataSet.RecNo := SI.nTrackPos;
- Exit;
- end;
- end else
- begin
- case Message.Pos of
- 0: Key := gkHome;
- 1: Key := gkPageUp;
- 3: Key := gkPageDown;
- 4: Key := gkEnd;
- end;
- end;
- end;
- DoKey(Key);
- end;
- end;
-
- function TDBCtrlGrid.FindNext(StartControl: TWinControl; GoForward: Boolean;
- var WrapFlag: Integer): TWinControl;
- var
- I, StartIndex: Integer;
- List: TList;
- begin
- List := TList.Create;
- try
- StartIndex := 0;
- I := 0;
- Result := StartControl;
- FPanel.GetTabOrderList(List);
- if List.Count > 0 then
- begin
- StartIndex := List.IndexOf(StartControl);
- if StartIndex = -1 then
- if GoForward then
- StartIndex := List.Count - 1 else
- StartIndex := 0;
- I := StartIndex;
- repeat
- if GoForward then
- begin
- Inc(I);
- if I = List.Count then I := 0;
- end else
- begin
- if I = 0 then I := List.Count;
- Dec(I);
- end;
- Result := List[I];
- until (Result.CanFocus and Result.TabStop) or (I = StartIndex);
- end;
- WrapFlag := 0;
- if GoForward then
- begin
- if I <= StartIndex then WrapFlag := 1;
- end else
- begin
- if I >= StartIndex then WrapFlag := -1;
- end;
- finally
- List.Free;
- end;
- end;
-
- procedure TDBCtrlGrid.SelectNext(GoForward: Boolean);
- var
- WrapFlag: Integer;
- ParentForm: TCustomForm;
- ActiveControl, Control: TWinControl;
- begin
- ParentForm := GetParentForm(Self);
- if ParentForm <> nil then
- begin
- ActiveControl := ParentForm.ActiveControl;
- if ContainsControl(ActiveControl) then
- begin
- Control := FindNext(ActiveControl, GoForward, WrapFlag);
- if not (FDataLink.DataSet.State in dsEditModes) then
- FPanel.SetFocus;
- try
- if WrapFlag <> 0 then Scroll(WrapFlag, False);
- except
- ActiveControl.SetFocus;
- raise;
- end;
- if not Control.CanFocus then
- Control := FindNext(Control, GoForward, WrapFlag);
- Control.SetFocus;
- end;
- end;
- end;
-
- procedure TDBCtrlGrid.SetBounds(ALeft, ATop, AWidth, AHeight: Integer);
- var
- ScrollWidth, ScrollHeight, NewPanelWidth, NewPanelHeight: Integer;
- begin
- ScrollWidth := 0;
- ScrollHeight := 0;
- if FOrientation = goVertical then
- ScrollWidth := GetSystemMetrics(SM_CXVSCROLL) else
- ScrollHeight := GetSystemMetrics(SM_CYHSCROLL);
- NewPanelWidth := (AWidth - ScrollWidth) div FColCount;
- NewPanelHeight := (AHeight - ScrollHeight) div FRowCount;
- if NewPanelWidth < 1 then NewPanelWidth := 1;
- if NewPanelHeight < 1 then NewPanelHeight := 1;
- if (FPanelWidth <> NewPanelWidth) or (FPanelHeight <> NewPanelHeight) then
- begin
- FPanelWidth := NewPanelWidth;
- FPanelHeight := NewPanelHeight;
- Reset;
- end;
- inherited SetBounds(ALeft, ATop, AWidth, AHeight);
- end;
-
- procedure TDBCtrlGrid.SetColCount(Value: Integer);
- begin
- if Value < 1 then Value := 1;
- if Value > 100 then Value := 100;
- if FColCount <> Value then
- begin
- FColCount := Value;
- AdjustSize;
- end;
- end;
-
- procedure TDBCtrlGrid.SetDataSource(Value: TDataSource);
- begin
- FDataLink.DataSource := Value;
- UpdateDataLinks(FPanel, True);
- end;
-
- procedure TDBCtrlGrid.SetEditMode(Value: Boolean);
- var
- Control: TWinControl;
- begin
- if GetEditMode <> Value then
- if Value then
- begin
- Control := FPanel.FindNextControl(nil, True, True, False);
- if Control <> nil then Control.SetFocus;
- end else
- SetFocus;
- end;
-
- procedure TDBCtrlGrid.SetOrientation(Value: TDBCtrlGridOrientation);
- begin
- if FOrientation <> Value then
- begin
- FOrientation := Value;
- RecreateWnd;
- AdjustSize;
- end;
- end;
-
- procedure TDBCtrlGrid.SetPanelBorder(Value: TDBCtrlGridBorder);
- begin
- if FPanelBorder <> Value then
- begin
- FPanelBorder := Value;
- Invalidate;
- FPanel.Invalidate;
- end;
- end;
-
- procedure TDBCtrlGrid.SetPanelHeight(Value: Integer);
- begin
- if Value < 1 then Value := 1;
- if Value > 65535 then Value := 65535;
- if FPanelHeight <> Value then
- begin
- FPanelHeight := Value;
- AdjustSize;
- end;
- end;
-
- procedure TDBCtrlGrid.SetPanelIndex(Value: Integer);
- begin
- if FDataLink.Active and (Value < PanelCount) then
- FDataLink.DataSet.MoveBy(Value - FPanelIndex);
- end;
-
- procedure TDBCtrlGrid.SetPanelWidth(Value: Integer);
- begin
- if Value < 1 then Value := 1;
- if Value > 65535 then Value := 65535;
- if FPanelWidth <> Value then
- begin
- FPanelWidth := Value;
- AdjustSize;
- end;
- end;
-
- procedure TDBCtrlGrid.SetRowCount(Value: Integer);
- begin
- if Value < 1 then Value := 1;
- if Value > 100 then Value := 100;
- if FRowCount <> Value then
- begin
- FRowCount := Value;
- AdjustSize;
- end;
- end;
-
- procedure TDBCtrlGrid.SetSelectedColor(Value: TColor);
- begin
- if Value <> FSelectedColor then
- begin
- FSelectedColor := Value;
- FSelColorChanged := Value <> Color;
- Invalidate;
- FPanel.Invalidate;
- end;
- end;
-
- procedure TDBCtrlGrid.UpdateDataLinks(Control: TControl; Inserting: Boolean);
- var
- I: Integer;
- DataLink: TDataLink;
- begin
- if Inserting and not (csReplicatable in Control.ControlStyle) then
- DatabaseError(SNotReplicatable);
- DataLink := TDataLink(Control.Perform(CM_GETDATALINK, 0, 0));
- if DataLink <> nil then
- begin
- DataLink.DataSourceFixed := False;
- if Inserting then
- begin
- DataLink.DataSource := DataSource;
- DataLink.DataSourceFixed := True;
- end;
- end;
- if Control is TWinControl then
- with TWinControl(Control) do
- for I := 0 to ControlCount - 1 do
- UpdateDataLinks(Controls[I], Inserting);
- end;
-
- procedure TDBCtrlGrid.UpdateScrollBar;
- var
- SIOld, SINew: TScrollInfo;
- begin
- if FDatalink.Active and HandleAllocated then
- with FDatalink.DataSet do
- begin
- SIOld.cbSize := sizeof(SIOld);
- SIOld.fMask := SIF_ALL;
- GetScrollInfo(Self.Handle, FScrollBarKind, SIOld);
- SINew := SIOld;
- if IsSequenced then
- begin
- SINew.nMin := 1;
- SINew.nPage := Self.RowCount * Self.ColCount;
- SINew.nMax := DWORD(RecordCount) + SINew.nPage - 1;
- if State in [dsInactive, dsBrowse, dsEdit] then
- SINew.nPos := RecNo;
- end
- else
- begin
- SINew.nMin := 0;
- SINew.nPage := 0;
- SINew.nMax := 4;
- if BOF then SINew.nPos := 0
- else if EOF then SINew.nPos := 4
- else SINew.nPos := 2;
- end;
- if (SINew.nMin <> SIOld.nMin) or (SINew.nMax <> SIOld.nMax) or
- (SINew.nPage <> SIOld.nPage) or (SINew.nPos <> SIOld.nPos) then
- SetScrollInfo(Self.Handle, FScrollBarKind, SINew, True);
- end;
- end;
-
- procedure TDBCtrlGrid.WMLButtonDown(var Message: TWMLButtonDown);
- var
- I: Integer;
- P: TPoint;
- Window: HWnd;
- begin
- if FDataLink.Active then
- begin
- P := SmallPointToPoint(Message.Pos);
- for I := 0 to FPanelCount - 1 do
- if (I <> FPanelIndex) and PtInRect(GetPanelBounds(I), P) then
- begin
- FClicking := True;
- try
- SetPanelIndex(I);
- finally
- FClicking := False;
- end;
- P := ClientToScreen(P);
- Window := WindowFromPoint(P);
- if IsChild(FPanel.Handle, Window) then
- begin
- Windows.ScreenToClient(Window, P);
- Message.Pos := PointToSmallPoint(P);
- with TMessage(Message) do SendMessage(Window, Msg, WParam, LParam);
- Exit;
- end;
- Break;
- end;
- end;
- if AcquireFocus then
- begin
- if PointInPanel(Message.Pos) then
- begin
- EditMode := False;
- Click;
- end;
- inherited;
- end;
- end;
-
- procedure TDBCtrlGrid.WMLButtonDblClk(var Message: TWMLButtonDblClk);
- begin
- if PointInPanel(Message.Pos) then DblClick;
- inherited;
- end;
-
- procedure TDBCtrlGrid.WMHScroll(var Message: TWMHScroll);
- begin
- ScrollMessage(Message);
- end;
-
- procedure TDBCtrlGrid.WMVScroll(var Message: TWMVScroll);
- begin
- ScrollMessage(Message);
- end;
-
- procedure TDBCtrlGrid.WMEraseBkgnd(var Message: TMessage);
- begin
- Message.Result := 1;
- end;
-
- procedure TDBCtrlGrid.WMPaint(var Message: TWMPaint);
- begin
- PaintHandler(Message);
- end;
-
- procedure TDBCtrlGrid.WMSetFocus(var Message: TWMSetFocus);
- begin
- FFocused := True;
- FPanel.Repaint;
- end;
-
- procedure TDBCtrlGrid.WMKillFocus(var Message: TWMKillFocus);
- begin
- FFocused := False;
- FPanel.Repaint;
- end;
-
- procedure TDBCtrlGrid.WMGetDlgCode(var Message: TWMGetDlgCode);
- begin
- Message.Result := DLGC_WANTARROWS or DLGC_WANTCHARS;
- end;
-
- procedure TDBCtrlGrid.WMSize(var Message: TMessage);
- begin
- inherited;
- Invalidate;
- end;
-
- function GetShiftState: TShiftState;
- begin
- Result := [];
- if GetKeyState(VK_SHIFT) < 0 then Include(Result, ssShift);
- if GetKeyState(VK_CONTROL) < 0 then Include(Result, ssCtrl);
- if GetKeyState(VK_MENU) < 0 then Include(Result, ssAlt);
- end;
-
- procedure TDBCtrlGrid.CMChildKey(var Message: TCMChildKey);
- var
- ShiftState: TShiftState;
- GridKey: TDBCtrlGridKey;
- begin
- with Message do
- if Sender <> Self then
- begin
- ShiftState := GetShiftState;
- if Assigned(OnKeyDown) then OnKeyDown(Sender, CharCode, ShiftState);
- GridKey := gkNull;
- case CharCode of
- VK_TAB:
- if not (ssCtrl in ShiftState) and
- (Sender.Perform(WM_GETDLGCODE, 0, 0) and DLGC_WANTTAB = 0) then
- if ssShift in ShiftState then
- GridKey := gkPriorTab else
- GridKey := gkNextTab;
- VK_RETURN:
- if (Sender.Perform(WM_GETDLGCODE, 0, 0) and DLGC_WANTALLKEYS = 0) then
- GridKey := gkEditMode;
- VK_F2: GridKey := gkEditMode;
- VK_ESCAPE: GridKey := gkCancel;
- end;
- if GridKey <> gkNull then
- begin
- DoKey(GridKey);
- Result := 1;
- Exit;
- end;
- end;
- inherited;
- end;
-
- procedure TDBCtrlGrid.CMColorChanged(var Message: TMessage);
- begin
- inherited;
- if not FSelColorChanged then
- FSelectedColor := Color;
- end;
-
- { Defer action processing to datalink }
-
- function TDBCtrlGrid.ExecuteAction(Action: TBasicAction): Boolean;
- begin
- Result := inherited ExecuteAction(Action) or (FDataLink <> nil) and
- FDataLink.ExecuteAction(Action);
- end;
-
- function TDBCtrlGrid.UpdateAction(Action: TBasicAction): Boolean;
- begin
- Result := inherited UpdateAction(Action) or (FDataLink <> nil) and
- FDataLink.UpdateAction(Action);
- end;
-
- end.
-