home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Chip 2003 January
/
Chip_2003-01_cd1.bin
/
zkuste
/
delphi
/
kompon
/
D34567
/
SMDBG
/
SMDBGRID.ZIP
/
Smdbgrid.pas
< prev
next >
Wrap
Pascal/Delphi Source File
|
2002-11-04
|
72KB
|
2,369 lines
{$A+,B-,C+,D+,E-,F-,G+,H+,I+,J+,K-,L+,M-,N+,O+,P+,Q-,R-,S-,T-,U-,V+,W-,X+,Y-,Z1}
{ Copyright (C) 1998-2000, written by Shkolnik Mike
FIDOnet: 2:463/106.14
E-Mail: mshkolnik@scalabium.com
mshkolnik@yahoo.com
WEB: http://www.scalabium.com
http://www.geocities.com/mshkolnik
tel: 380-/44/-552-10-29
English:
The successor TDBGrid with the extended features.
Is able to display multiline wordwrap column titles,
checkboxs for boolean fields, checkboxs for record selecting,
fixing of columns, a convenient select of records from the keyboard,
stretch drawing of the graphic fields in the cells,
possibility to exclude insert and delete of records in the DBGrid,
own standard PopupMenu, save/restore of a column states, processing of
additional events etc.
1. movement from column to column by ENTER key (like TAB)
2. multiline wordwrap column titles (partly is transfered
from TBitDBGrid - Ilya Andreev, ilya_andreev@geocities.com
FIDONet: 2:5030/55.28 AKA 2:5030/402.17)
3. display opportunity of selected record mark (like checkbox)
4. editing of boolean fields like checkbox
5. a convenient select of records from keyboard (is transfered from TRXDBGrid, RXLibrary)
6. an opportunity to exclude insert and delete of records in the SMDBGrid
7. save and restore of the column order and column width in the INI-file
8. own PopUp-menu with standard items (Add/Edit/Delete record, Print/Export
data, Save/Cancel changes, Refresh data, Select/UnSelect records,
Save/Restore layout)
9. fixing of the few columns in horizontal scrolling
10. delete of the all selected records
11. Refresh of the data in SMDBGrid (useful for TQuery because Refresh
correctly works only for TTable)
12. processing of events by pressing on column title (is transfered
from TRXDBGrid, RXLibrary)
13. ability of display of the MEMO/BLOB/PICTURE-fields as Bitmap (is
transfered from TRXDBGrid, RXLibrary)
14. display hints for each cells if cell text is cutted by column width
(transfered from TBitDBGrid - Ilya Andreev, ilya_andreev@geocities.com
FIDONet: 2:5030/55.28 AKA 2:5030/402.17)
15. opportunity to assign of events: OnAppendRecord, OnEditRecord,
OnDeleteRecord, OnPrintData, OnExportData
16. lowered draw of the current selected column (like grid in
1C-accounting)
17. standard Popup menu like window system menu:
"Add record",
"Insert record",
"Edit record",
"Delete record",
"-",
"Print ...",
"Export ...",
"-",
"Save changes",
"Cancel changes",
"Refresh data",
"-",
"Select/Unselect records",
"-",
"Save layout",
"Restore layout",
"-",
"Setup..."
PS: in archive there are English, French, German, Italian, Dutch,
Brazilian Portuguese, Russian, Ukrainian and Japan resources
(view a file SMCnst.PAS in Resourse directory).
If anybody want to send a native resources, then I shall include it in next build.
Thanks to native tranclators:
- Remy (walloon@euronet.be) for French resources
- Thomas Grimm (tgrimm@allegro-itc.de) for German resources
- Naohiro Fukuda (nao@nagoya.terracom.co.jp) for Japan resources
- Julian (gzorzi@misam.it) for Italian resources
- Rodrigo Hjort (rodrigo_hjort@excite.com) for Brazilian Portuguese resources
- sam francke (s.j.francke@hccnet.nl) for Dutch resources
- Daniel Ramirez Jaime (rdaniel2000@hotmail.com) for Spanish Mexican resources
I want to thank Naohiro Fukuda (nao@nagoya.terracom.co.jp)
and Remy (walloon@euronet.be), due to which in TSMDBGrid
there was much less errors and bugs and for their sentences
on improverment a component.
}
unit SMDBGrid;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
Menus, Grids, DBGrids, DB, StdCtrls, SMCnst;
type
TExOptions = set of (eoBooleanAsCheckBox,
eoCheckBoxSelect, eoCellHint,
eoDisableDelete, eoDisableInsert, eoDrawGraphicField,
eoENTERlikeTAB, eoFixedLikeColumn,
eoKeepSelection, eoLayout,
eoSelectedTitle, eoShowGlyphs, eoShowLookup, eoStandardPopup,
eoTitleButtons);
type
{start cutting from TRxDBGrid}
TCheckTitleBtnEvent = procedure (Sender: TObject; ACol: Longint; Field: TField; var Enabled: Boolean) of object;
TGetCellParamsEvent = procedure (Sender: TObject; Field: TField; AFont: TFont; var Background: TColor; Highlight: Boolean) of object;
TGetBtnParamsEvent = procedure (Sender: TObject; Field: TField; AFont: TFont; var Background: TColor; IsDown: Boolean) of object;
{end cutting from TRxDBGrid}
TGetGlyphEvent = procedure (Sender: TObject; var Bitmap: TBitmap) of object;
type
TSMSortType = (stNone, stAscending, stDescending);
TSMSortColumn = class
FieldName: string;
SortCaption: string;
SortType: TSMSortType;
end;
TSMDBGrid = class;
TSMListSortColumns = class(TList)
private
function GetColumn(Index: Integer): TSMSortColumn;
procedure SetColumn(Index: Integer; Value: TSMSortColumn);
public
function Add: TSMSortColumn;
procedure RebuildColumns(Grid: TSMDBGrid);
property Items[Index: Integer]: TSMSortColumn read GetColumn write SetColumn; default;
end;
TSMDBGrid = class(TDBGrid)
private
{ Private declarations }
FExOptions: TExOptions;
{selection: from TRxDBGrid}
FMultiSelect: Boolean;
FSelecting: Boolean;
FMsIndicators: TImageList;
FSelectionAnchor: TBookmarkStr;
FDisableCount: Integer;
FFixedCols: Integer;
FSwapButtons: Boolean;
FOnCheckButton: TCheckTitleBtnEvent;
FTracking: Boolean;
FPressedCol: Longint;
FPressed: Boolean;
FOnGetCellParams: TGetCellParamsEvent;
FOnGetBtnParams: TGetBtnParamsEvent;
{Registry}
FRegistryKey: string;
FRegistrySection: string;
{popup menu with standard operations}
FDBPopUpMenu: TPopUpMenu;
FOnAppendRecord: TNotifyEvent;
FOnInsertRecord: TNotifyEvent;
FOnEditRecord: TNotifyEvent;
FOnDeleteRecord: TNotifyEvent;
FOnPostData: TNotifyEvent;
FOnCancelData: TNotifyEvent;
FOnRefreshData: TNotifyEvent;
FOnPrintData: TNotifyEvent;
FOnExportData: TNotifyEvent;
FOnSetupGrid: TNotifyEvent;
FOnChangeSelection: TNotifyEvent;
FOnDrawColumnTitle: TDrawColumnCellEvent;
FOnGetGlyph: TGetGlyphEvent;
FWidthOfIndicator: Integer;
StartOfSelect: TBookmark;
procedure SetIndicatorWidth(Value: Integer);
procedure AppendClick(Sender: TObject);
procedure InsertClick(Sender: TObject);
procedure EditClick(Sender: TObject);
procedure DeleteClick(Sender: TObject);
procedure PrintClick(Sender: TObject);
procedure ExportClick(Sender: TObject);
procedure PostClick(Sender: TObject);
procedure CancelClick(Sender: TObject);
procedure RefreshClick(Sender: TObject);
procedure SetupGridClick(Sender: TObject);
procedure SaveLayoutClick(Sender: TObject);
procedure RestoreLayoutClick(Sender: TObject);
{start cutting from TRxDBGrid}
procedure SetFixedCols(Value: Integer);
function GetFixedCols: Integer;
function GetTitleOffset: Byte;
procedure StopTracking;
procedure TrackButton(X, Y: Integer);
function AcquireFocus: Boolean;
function ActiveRowSelected: Boolean;
function GetOptions: TDBGridOptions;
procedure SetOptions(Value: TDBGridOptions);
{end cutting from TRxDBGrid}
function GetImageIndex(Field: TField): Integer;
procedure SetExOptions(Val: TExOptions);
{partly is transfered from TBitDBGrid:
Ilya Andreev, ilya_andreev@geocities.com
FIDONet: 2:5030/55.28 AKA 2:5030/402.17}
procedure SetTitlesHeight;
procedure CMHintShow(var Msg: TMessage); message CM_HINTSHOW;
{end of transfered}
function GetSortImageWidth: Integer;
protected
{ Protected declarations }
// procedure Paint; override;
{start cutting from TRxDBGrid}
function HighlightCell(DataCol, DataRow: Integer; const Value: string;
AState: TGridDrawState): Boolean; override;
procedure Scroll(Distance: Integer); override;
procedure LayoutChanged; override;
procedure ColWidthsChanged; override;
procedure SetColumnAttributes; override;
procedure TopLeftChanged; override;
function CanEditShow: Boolean; override;
procedure CheckTitleButton(ACol: Longint; var Enabled: Boolean); dynamic;
procedure GetCellProps(Field: TField; AFont: TFont; var Background: TColor;
Highlight: Boolean); dynamic;
{end cutting from TRxDBGrid}
procedure CellClick(Column: TColumn); override;
function CellRectForDraw(R: TRect; ACol: Longint): TRect;
procedure DrawColumnCell(const Rect: TRect; DataCol: Integer;
Column: TColumn; State: TGridDrawState); override;
function GetGlyph: TBitmap; virtual;
procedure DrawCheckBox(R: TRect; AState: TCheckBoxState; al: TAlignment); virtual;
procedure KeyDown(var Key: Word; Shift: TShiftState); override;
procedure DrawCell(ACol, ARow: Longint; ARect: TRect; AState: TGridDrawState); override;
procedure MouseDown(Button: TMouseButton; Shift: TShiftState; X, Y: Integer); override;
procedure MouseUp(Button: TMouseButton; Shift: TShiftState; X, Y: Integer); override;
public
{ Public declarations }
SortColumns: TSMListSortColumns;
constructor Create(AOwner: TComponent); override;
destructor Destroy; override;
procedure DeleteData;
procedure RefreshData;
procedure SelectOneClick(Sender: TObject);
procedure SelectAllClick(Sender: TObject);
procedure UnSelectOneClick(Sender: TObject);
procedure UnSelectAllClick(Sender: TObject);
procedure SaveLayoutToRegistry;
procedure RestoreLayoutFromRegistry;
procedure ToggleRowSelection;
procedure GotoSelection(Index: Longint);
procedure DisableScroll;
procedure EnableScroll;
function ScrollDisabled: Boolean;
property IndicatorOffset;
property TitleOffset: Byte read GetTitleOffset;
published
{ Published declarations }
property GridLineWidth;
property ExOptions: TExOptions read FExOptions write SetExOptions;
{selection}
property Options: TDBGridOptions read GetOptions write SetOptions;
property FixedCols: Integer read GetFixedCols write SetFixedCols default 0;
property OnGetCellParams: TGetCellParamsEvent read FOnGetCellParams write FOnGetCellParams;
{Registry}
property RegistryKey: string read FRegistryKey write FRegistryKey;
property RegistrySection: string read FRegistrySection write FRegistrySection;
property OnAppendRecord: TNotifyEvent read FOnAppendRecord write FOnAppendRecord;
property OnInsertRecord: TNotifyEvent read FOnInsertRecord write FOnInsertRecord;
property OnEditRecord: TNotifyEvent read FOnEditRecord write FOnEditRecord;
property OnDeleteRecord: TNotifyEvent read FOnDeleteRecord write FOnDeleteRecord;
property OnPostData: TNotifyEvent read FOnPostData write FOnPostData;
property OnCancelData: TNotifyEvent read FOnCancelData write FOnCancelData;
property OnRefreshData: TNotifyEvent read FOnRefreshData write FOnRefreshData;
property OnPrintData: TNotifyEvent read FOnPrintData write FOnPrintData;
property OnExportData: TNotifyEvent read FOnExportData write FOnExportData;
property OnCheckButton: TCheckTitleBtnEvent read FOnCheckButton write FOnCheckButton;
property OnChangeSelection: TNotifyEvent read FOnChangeSelection write FOnChangeSelection;
property OnSetupGrid: TNotifyEvent read FOnSetupGrid write FOnSetupGrid;
property OnDrawColumnTitle: TDrawColumnCellEvent read FOnDrawColumnTitle write FOnDrawColumnTitle;
property OnGetGlyph: TGetGlyphEvent read FOnGetGlyph write FOnGetGlyph;
property WidthOfIndicator: Integer read FWidthOfIndicator write SetIndicatorWidth;
property ScrollBars;
property ColCount;
property RowCount;
property VisibleColCount;
property VisibleRowCount;
property Col;
property Row;
property OnMouseDown;
property OnMouseUp;
property OnMouseMove;
end;
procedure Register;
implementation
uses RXUtils {ex VCLUtils from RX-Lib}, TypInfo, Registry, DBTables
{$IFDEF VER140} , Variants
{$ELSE}
{$IFDEF VER150} , Variants
{$ENDIF}
{$ENDIF}
;
{$R *.RES}
var
FCheckWidth, FCheckHeight: Integer;
procedure Register;
begin
RegisterComponents('SMComponents', [TSMDBGrid]);
end;
{ TSMListSortColumns }
function TSMListSortColumns.Add: TSMSortColumn;
begin
Result := TSMSortColumn.Create;
inherited Add(Result);
end;
function TSMListSortColumns.GetColumn(Index: Integer): TSMSortColumn;
begin
Result := TSMSortColumn(inherited Items[Index]);
end;
procedure TSMListSortColumns.SetColumn(Index: Integer; Value: TSMSortColumn);
begin
Items[Index] := Value;
end;
procedure TSMListSortColumns.RebuildColumns(Grid: TSMDBGrid);
var i: Integer;
begin
if Assigned(Grid) and Assigned(Grid.DataSource) and
Assigned(Grid.DataSource.DataSet) then
begin
Grid.BeginLayout;
try
Clear;
with Grid.DataSource.DataSet do
for i := 0 to FieldCount-1 do
Add.FieldName := Fields[i].FieldName
finally
Grid.EndLayout;
end
end
else
Clear;
end;
type
TBookmarks = class(TBookmarkList);
TGridPicture = (gpBlob, gpMemo, gpPicture, gpOle, gpSortAsc, gpSortDesc);
const
GridBmpNames: array[TGridPicture] of PChar = ('SM_BLOB', 'SM_MEMO', 'SM_PICT', 'SM_OLE',
'SM_ARROWASC', 'SM_ARROWDESC');
GridBitmaps: array[TGridPicture] of TBitmap = (nil, nil, nil, nil, nil, nil);
bmMultiDot = 'SM_MSDOT';
bmMultiArrow = 'SM_MSARROW';
bmMultiCheckBox = 'SM_MSCHECKBOX';
function GetGridBitmap(BmpType: TGridPicture): TBitmap;
begin
if GridBitmaps[BmpType] = nil then
begin
GridBitmaps[BmpType] := TBitmap.Create;
GridBitmaps[BmpType].Handle := LoadBitmap(HInstance, GridBmpNames[BmpType]);
end;
Result := GridBitmaps[BmpType];
end;
procedure DestroyLocals; far;
var I: TGridPicture;
begin
for I := Low(TGridPicture) to High(TGridPicture) do
GridBitmaps[I].Free;
end;
procedure GridInvalidateRow(Grid: TSMDBGrid; Row: Longint);
var I: Longint;
begin
for I := 0 to Grid.ColCount - 1 do Grid.InvalidateCell(I, Row);
end;
procedure GetCheckBoxSize;
begin
with TBitmap.Create do
try
Handle := LoadBitmap(0, PChar(32759));
FCheckWidth := Width div 4;
FCheckHeight := Height div 3;
finally
Free;
end;
end;
constructor TSMDBGrid.Create(AOwner: TComponent);
var NewItem: TMenuItem;
j: Integer;
Bmp: TBitmap;
begin
inherited Create(AOwner);
SortColumns := TSMListSortColumns.Create;
FRegistryKey := 'Software\MikeSoft';
FRegistrySection := 'SMDBGrid';
Bmp := TBitmap.Create;
try
Bmp.Handle := LoadBitmap(hInstance, bmMultiDot);
FMsIndicators := TImageList.CreateSize(Bmp.Width, Bmp.Height);
FMsIndicators.AddMasked(Bmp, clWhite);
Bmp.Handle := LoadBitmap(hInstance, bmMultiArrow);
FMsIndicators.AddMasked(Bmp, clWhite);
Bmp.Handle := LoadBitmap(hInstance, bmMultiCheckBox);
FMsIndicators.AddMasked(Bmp, clWhite);
finally
Bmp.Free;
end;
FPressedCol := -1;
FDBPopUpMenu := TPopUpMenu.Create(Self {AOwner});
if not (csDesigning in ComponentState) then
begin
for j := 0 to High(PopUpCaption) do
begin
NewItem := TMenuItem.Create(Self);
NewItem.Caption := PopUpCaption[j];
case j of
0: NewItem.OnClick := AppendClick;
1: NewItem.OnClick := InsertClick;
2: NewItem.OnClick := EditClick;
3: NewItem.OnClick := DeleteClick;
5: NewItem.OnClick := PrintClick;
6: NewItem.OnClick := ExportClick;
8: NewItem.OnClick := PostClick;
9: NewItem.OnClick := CancelClick;
10: NewItem.OnClick := RefreshClick;
13: NewItem.OnClick := SelectOneClick;
14: NewItem.OnClick := SelectAllClick;
16: NewItem.OnClick := UnSelectOneClick;
17: NewItem.OnClick := UnSelectAllClick;
19: NewItem.OnClick := SaveLayoutClick;
20: NewItem.OnClick := RestoreLayoutClick;
22: NewItem.OnClick := SetupGridClick;
end;
if j in [13, 14, 15, 16, 17] then
FDBPopUpMenu.Items[12].Add(NewItem)
else
FDBPopUpMenu.Items.Add(NewItem);
end;
end;
// PopUpMenu := FDBPopUpMenu;
GetCheckBoxSize;
FWidthOfIndicator := IndicatorWidth;
FExOptions := [eoENTERlikeTAB, eoKeepSelection, eoStandardPopup];
// ScrollBars := ssBoth;
// Color := clInfoBk;
end;
destructor TSMDBGrid.Destroy;
begin
if Assigned(StartOfSelect) then
DataLink.DataSet.FreeBookmark(StartOfSelect);
SortColumns.Free;
FDBPopUpMenu.Free;
FMsIndicators.Free;
inherited Destroy;
end;
{procedure TSMDBGrid.Paint;
begin
if ScrollBars in [ssNone, ssHorizontal] then
SetScrollRange(Self.Handle, SB_VERT, 0, 0, False);
if ScrollBars in [ssNone, ssVertical] then
SetScrollRange(Self.Handle, SB_HORZ, 0, 0, False);
inherited Paint;
end;
}
{Standard popup menu events}
procedure TSMDBGrid.AppendClick(Sender: TObject);
begin
if Assigned(FOnAppendRecord) then
FOnAppendRecord(Sender)
else
Datalink.DataSet.Append;
end;
procedure TSMDBGrid.InsertClick(Sender: TObject);
begin
if Assigned(FOnInsertRecord) then
FOnInsertRecord(Self)
else
Datalink.DataSet.Insert;
end;
procedure TSMDBGrid.EditClick(Sender: TObject);
begin
if Assigned(FOnEditRecord) then
FOnEditRecord(Sender)
else
Datalink.DataSet.Edit;
end;
procedure TSMDBGrid.DeleteClick(Sender: TObject);
begin
if Assigned(FOnDeleteRecord) then
FOnDeleteRecord(Sender)
else
DeleteData;
end;
procedure TSMDBGrid.PrintClick(Sender: TObject);
begin
if Assigned(FOnPrintData) then
FOnPrintData(Sender)
end;
procedure TSMDBGrid.ExportClick(Sender: TObject);
begin
if Assigned(FOnexportData) then
FOnExportData(Sender)
end;
procedure TSMDBGrid.PostClick(Sender: TObject);
begin
if Assigned(FOnPostData) then
FOnPostData(Sender)
else
Datalink.DataSet.Post;
end;
procedure TSMDBGrid.CancelClick(Sender: TObject);
begin
if Assigned(FOnCancelData) then
FOnCancelData(Sender)
else
Datalink.DataSet.Cancel;
end;
procedure TSMDBGrid.RefreshClick(Sender: TObject);
begin
if Assigned(FOnRefreshData) then
FOnRefreshData(Sender)
else
RefreshData;
end;
procedure TSMDBGrid.SetupGridClick(Sender: TObject);
begin
if Assigned(FOnSetupGrid) then
FOnSetupGrid(Sender)
end;
function TSMDBGrid.GetImageIndex(Field: TField): Integer;
var
AOnGetText: TFieldGetTextEvent;
AOnSetText: TFieldSetTextEvent;
begin
Result := -1;
if (eoShowGlyphs in FExOptions) and Assigned(Field) then
begin
if (not ReadOnly) and Field.CanModify then
begin
{ Allow editing of memo fields if OnSetText and OnGetText
events are assigned }
AOnGetText := Field.OnGetText;
AOnSetText := Field.OnSetText;
if Assigned(AOnSetText) and Assigned(AOnGetText) then Exit;
end;
case Field.DataType of
ftBytes, ftVarBytes, ftBlob: Result := Integer(gpBlob);
ftMemo: Result := Integer(gpMemo);
ftGraphic: Result := Integer(gpPicture);
ftTypedBinary: Result := Integer(gpBlob);
ftFmtMemo: Result := Integer(gpMemo);
ftParadoxOle, ftDBaseOle: Result := Integer(gpOle);
end;
end;
end;
function TSMDBGrid.ActiveRowSelected: Boolean;
var Index: Integer;
begin
Result := False;
if (dgMultiSelect in Options) and Datalink.Active then
Result := SelectedRows.Find(Datalink.DataSet.Bookmark, Index);
end;
function TSMDBGrid.HighlightCell(DataCol, DataRow: Integer;
const Value: string; AState: TGridDrawState): Boolean;
begin
Result := ActiveRowSelected;
if not Result then
Result := inherited HighlightCell(DataCol, DataRow, Value, AState);
end;
procedure TSMDBGrid.ToggleRowSelection;
begin
if (dgMultiSelect in Options) and Datalink.Active then
begin
with SelectedRows do
CurrentRowSelected := not CurrentRowSelected;
if Assigned(FOnChangeSelection) then
FOnChangeSelection(Self);
end;
end;
procedure TSMDBGrid.GotoSelection(Index: Longint);
begin
if (dgMultiSelect in Options) and DataLink.Active and (Index < SelectedRows.Count) and (Index >= 0) then
Datalink.DataSet.GotoBookmark(Pointer(SelectedRows[Index]));
end;
{partly is transfered from TBitDBGrid:
Ilya Andreev, ilya_andreev@geocities.com
FIDONet: 2:5030/55.28 AKA 2:5030/402.17}
procedure TSMDBGrid.SetTitlesHeight;
var
i, MaxHeight: Integer;
RRect: TRect;
pt: Integer;
s: string;
begin
if (dgTitles in Options) then
begin
{recalculate a title height}
MaxHeight := 0;
for i := 0 to Columns.Count - 1 do
begin
RRect := CellRect(0, 0);
RRect.Right := Columns[i].Width - 1;
RRect.Left := 0;
RRect := CellRectForDraw(RRect, i);
Canvas.Font := Columns[i].Title.Font;
s := Columns[i].Title.Caption;
pt := Pos('|', s);
if pt > 0 then
begin
while pt <> 0 do
begin
s[pt] := #13;
pt := Pos('|', s);
end;
Columns[i].Title.Caption := s;
end;
MaxHeight := Max(MaxHeight, DrawText(Canvas.Handle,
PChar(s),
Length(s),
RRect,
DT_EXPANDTABS or DT_CALCRECT or DT_WORDBREAK));
end;
if (MaxHeight <> 0) then
begin
if (dgRowLines in Options) then
Inc(MaxHeight, 3)
else
Inc(MaxHeight, 2);
if (eoTitleButtons in ExOptions) then
Inc(MaxHeight, 2);
RowHeights[0] := MaxHeight+4
end;
end;
end;
{end of transfered}
procedure TSMDBGrid.LayoutChanged;
var ACol: Longint;
begin
ACol := Col;
inherited LayoutChanged;
if Datalink.Active and (FixedCols > 0) then
Col := Min(Max(inherited FixedCols, ACol), ColCount - 1);
{recalculate a title height}
SetTitlesHeight;
end;
procedure TSMDBGrid.ColWidthsChanged;
var
ACol: Longint;
begin
ACol := Col;
inherited ColWidthsChanged;
if Datalink.Active and (FixedCols > 0) then
Col := Min(Max(inherited FixedCols, ACol), ColCount - 1);
end;
procedure TSMDBGrid.SetIndicatorWidth(Value: Integer);
var FrameOffs: Byte;
begin
if (Value <> FWidthOfIndicator) then
begin
if ([dgRowLines, dgColLines] * Options = [dgRowLines, dgColLines]) then
FrameOffs := 1
else
FrameOffs := 2;
if (eoCheckBoxSelect in ExOptions) and
(Value < FCheckWidth + 4*FrameOffs + FMsIndicators.Width) then
Value := FCheckWidth + 4*FrameOffs + FMsIndicators.Width;
if Value < IndicatorWidth then
Value := IndicatorWidth;
FWidthOfIndicator := Value;
SetColumnAttributes
end;
end;
procedure TSMDBGrid.SetColumnAttributes;
begin
inherited SetColumnAttributes;
if (dgIndicator in Options) then
ColWidths[0] := WidthOfIndicator;
SetFixedCols(FFixedCols);
end;
function TSMDBGrid.GetTitleOffset: Byte;
begin
Result := 0;
if dgTitles in Options then
Inc(Result);
end;
procedure TSMDBGrid.SetFixedCols(Value: Integer);
var FixCount, i: Integer;
begin
FixCount := Max(Value, 0) + IndicatorOffset;
if DataLink.Active and not (csLoading in ComponentState) and
(ColCount > IndicatorOffset + 1) then
begin
FixCount := Min(FixCount, ColCount - 1);
inherited FixedCols := FixCount;
for i := 1 to Min(FixedCols, ColCount - 1) do
TabStops[i] := False;
end;
FFixedCols := FixCount - IndicatorOffset;
end;
function TSMDBGrid.GetFixedCols: Integer;
begin
if DataLink.Active then
Result := inherited FixedCols - IndicatorOffset
else
Result := FFixedCols;
end;
procedure TSMDBGrid.SelectOneClick(Sender: TObject);
begin
if (dgMultiSelect in Options) and Datalink.Active then
begin
SelectedRows.CurrentRowSelected := True;
if Assigned(FOnChangeSelection) then
FOnChangeSelection(Self);
end
end;
procedure TSMDBGrid.SelectAllClick(Sender: TObject);
var ABookmark: TBookmark;
begin
if (dgMultiSelect in Options) and DataLink.Active then
begin
with Datalink.Dataset do
begin
if (BOF and EOF) then Exit;
DisableControls;
try
ABookmark := GetBookmark;
try
First;
while not EOF do
begin
SelectedRows.CurrentRowSelected := True;
Next;
end;
finally
try
GotoBookmark(ABookmark);
except
end;
FreeBookmark(ABookmark);
end;
finally
if Assigned(FOnChangeSelection) then
FOnChangeSelection(Self);
EnableControls;
end;
end;
end;
end;
procedure TSMDBGrid.UnSelectOneClick(Sender: TObject);
begin
if (dgMultiSelect in Options) and Datalink.Active then
begin
SelectedRows.CurrentRowSelected := False;
if Assigned(FOnChangeSelection) then
FOnChangeSelection(Self);
end
end;
procedure TSMDBGrid.UnSelectAllClick(Sender: TObject);
begin
if (dgMultiSelect in Options) then
begin
SelectedRows.Clear;
FSelecting := False;
if Assigned(FOnChangeSelection) then
FOnChangeSelection(Self);
end;
end;
procedure TSMDBGrid.SaveLayoutClick(Sender: TObject);
begin
SaveLayoutToRegistry;
end;
procedure TSMDBGrid.RestoreLayoutClick(Sender: TObject);
begin
RestoreLayoutFromRegistry;
end;
procedure TSMDBGrid.DeleteData;
function DeletePrompt: Boolean;
var S: string;
begin
if (SelectedRows.Count > 1) then
S := SDeleteMultipleRecordsQuestion
else
S := SDeleteRecordQuestion;
Result := not (dgConfirmDelete in Options) or
(MessageDlg(S, mtConfirmation, [mbYes, mbNo], 0) = mrYes);
end;
begin
if DeletePrompt then
begin
if SelectedRows.Count > 0 then
SelectedRows.Delete
else
Datalink.DataSet.Delete;
end;
end;
procedure TSMDBGrid.RefreshData;
var bookPosition: TBookMark;
boolContinue: Boolean;
begin
boolContinue := True;
{if needs, save the changed data}
if Assigned(Datalink.DataSet) then
begin
with Datalink.DataSet do
begin
if (State in [dsInsert, dsEdit]) and CanModify then Post;
if (Datalink.DataSet is TBDEDataSet) then
with (Datalink.DataSet as TBDEDataSet) do
begin
if CachedUpdates and UpdatesPending then
try
case MessageDlg(strSaveChanges, mtConfirmation, [mbYes, mbNo, mbCancel], 0) of
mrYes: ApplyUpdates;
mrNo: CancelUpdates;
else
boolContinue := False;
end;
except
MessageDlg(strErrSaveChanges, mtError, [mbOk], 0);
boolContinue := False;
end;
end;
if boolContinue then
begin
{save a current position}
bookPosition := GetBookmark;
{close and open a dataset}
Active := False;
Active := True;
{restore a saved position}
try
GotoBookmark(bookPosition);
except
First;
end;
FreeBookmark(bookPosition);
end;
end;
end;
end;
procedure TSMDBGrid.SetExOptions(Val: TExOptions);
var FrameOffs: Byte;
begin
if (FExOptions <> Val) then
begin
FExOptions := Val;
if ([dgRowLines, dgColLines] * Options = [dgRowLines, dgColLines]) then
FrameOffs := 1
else
FrameOffs := 2;
if (eoCheckBoxSelect in Val) then
begin
if (WidthOfIndicator = IndicatorWidth) then
WidthOfIndicator := FCheckWidth + 4*FrameOffs + FMsIndicators.Width;
end
else
begin
if (WidthOfIndicator = FCheckWidth + 4*FrameOffs + FMsIndicators.Width) then
WidthOfIndicator := IndicatorWidth;
end;
Invalidate;
end;
end;
function TSMDBGrid.CanEditShow: Boolean;
begin
Result := inherited CanEditShow;
if Result and
(Datalink <> nil) and
Datalink.Active and
(FieldCount > 0) and
(SelectedIndex < FieldCount) and
(SelectedIndex >= 0) and
(FieldCount <= DataSource.DataSet.FieldCount) and
(Fields[SelectedIndex] <> nil) then
Result := GetImageIndex(Fields[SelectedIndex]) < 0;
if Result and
(eoBooleanAsCheckBox in FExOptions) and
Assigned(Fields[SelectedIndex]) and
(Fields[SelectedIndex].DataType = ftBoolean) then
Result := False
end;
function TSMDBGrid.AcquireFocus: Boolean;
begin
Result := True;
if FAcquireFocus and CanFocus and not (csDesigning in ComponentState) then
begin
SetFocus;
Result := Focused or (InplaceEditor <> nil) and InplaceEditor.Focused;
end;
end;
function TSMDBGrid.GetOptions: TDBGridOptions;
begin
Result := inherited Options;
if FMultiSelect then
Result := Result + [dgMultiSelect]
else
Result := Result - [dgMultiSelect];
end;
procedure TSMDBGrid.SetOptions(Value: TDBGridOptions);
begin
inherited Options := Value - [dgMultiSelect];
if FMultiSelect <> (dgMultiSelect in Value) then
begin
FMultiSelect := (dgMultiSelect in Value);
if not FMultiSelect then
SelectedRows.Clear;
end;
end;
procedure TSMDBGrid.GetCellProps(Field: TField; AFont: TFont;
var Background: TColor; Highlight: Boolean);
begin
if Assigned(FOnGetCellParams) then
FOnGetCellParams(Self, Field, AFont, Background, Highlight)
end;
procedure TSMDBGrid.CheckTitleButton(ACol: Longint; var Enabled: Boolean);
begin
if (ACol >= 0) and (ACol < Columns.Count) then
begin
if Assigned(FOnCheckButton) then
FOnCheckButton(Self, ACol, Columns[ACol].Field, Enabled);
end
else
Enabled := False;
end;
procedure TSMDBGrid.DisableScroll;
begin
Inc(FDisableCount);
end;
type
THackLink = class(TGridDataLink);
procedure TSMDBGrid.EnableScroll;
begin
if FDisableCount <> 0 then
begin
Dec(FDisableCount);
if FDisableCount = 0 then
THackLink(DataLink).DataSetScrolled(0);
end;
end;
function TSMDBGrid.ScrollDisabled: Boolean;
begin
Result := FDisableCount <> 0;
end;
procedure TSMDBGrid.Scroll(Distance: Integer);
var IndicatorRect: TRect;
begin
if FDisableCount = 0 then
begin
inherited Scroll(Distance);
if (dgIndicator in Options) and
HandleAllocated and
(dgMultiSelect in Options) then
begin
IndicatorRect := BoxRect(0, 0, 0, RowCount - 1);
InvalidateRect(Handle, @IndicatorRect, False);
end;
end;
end;
procedure TSMDBGrid.KeyDown(var Key: Word; Shift: TShiftState);
var
KeyDownEvent: TKeyEvent;
function ItAddLastRecord: Boolean;
begin
Result := (eoDisableInsert in FExOptions) and
(Datalink.ActiveRecord >= Datalink.RecordCount-1);
end;
procedure ClearSelections;
begin
if (dgMultiSelect in Options) then
begin
if not (eoKeepSelection in ExOptions) then
begin
SelectedRows.Clear;
if Assigned(FOnChangeSelection) then
FOnChangeSelection(Self);
end;
FSelecting := False;
end;
end;
procedure DoSelection(Select: Boolean; Direction: Integer);
var
AddAfter: Boolean;
begin
AddAfter := False;
BeginUpdate;
try
if (dgMultiSelect in Options) and DataLink.Active then
if Select and (ssShift in Shift) then
begin
if not FSelecting then
begin
FSelectionAnchor := TBookmarks(SelectedRows).CurrentRow;
SelectedRows.CurrentRowSelected := True;
if Assigned(FOnChangeSelection) then
FOnChangeSelection(Self);
FSelecting := True;
AddAfter := True;
end
else
with TBookmarks(SelectedRows) do
begin
AddAfter := Compare(CurrentRow, FSelectionAnchor) <> -Direction;
if not AddAfter then
begin
CurrentRowSelected := False;
if Assigned(FOnChangeSelection) then
FOnChangeSelection(Self);
end
end
end
else
ClearSelections;
if Direction <> 0 then
Datalink.DataSet.MoveBy(Direction);
if AddAfter then
begin
SelectedRows.CurrentRowSelected := True;
if Assigned(FOnChangeSelection) then
FOnChangeSelection(Self);
end;
finally
EndUpdate;
end;
end;
procedure NextRow(Select: Boolean);
begin
with Datalink.Dataset do begin
DoSelection(Select, 1);
if EOF and CanModify and (not ReadOnly) and (dgEditing in Options) and
not ItAddLastRecord then
AppendClick(Self);
end;
end;
procedure PriorRow(Select: Boolean);
begin
DoSelection(Select, -1);
end;
procedure CheckTab(GoForward: Boolean);
var ACol, Original: Integer;
begin
ACol := Col;
Original := ACol;
if (dgMultiSelect in Options) and DataLink.Active then
while True do
begin
if GoForward then
Inc(ACol)
else
Dec(ACol);
if ACol >= ColCount then
begin
ClearSelections;
ACol := IndicatorOffset;
end
else
if ACol < IndicatorOffset then
begin
ClearSelections;
ACol := ColCount;
end;
if ACol = Original then Exit;
if TabStops[ACol] then Exit;
end;
end;
const
RowMovementKeys = [VK_UP, VK_PRIOR, VK_DOWN, VK_NEXT, VK_HOME, VK_END];
begin
KeyDownEvent := OnKeyDown;
if Assigned(KeyDownEvent) then
KeyDownEvent(Self, Key, Shift);
if not Datalink.Active or not CanGridAcceptKey(Key, Shift) then Exit;
with Datalink.DataSet do
if ssCtrl in Shift then
begin
if (Key in RowMovementKeys) then
ClearSelections;
case Key of
VK_LEFT: if FixedCols > 0 then
begin
SelectedIndex := FixedCols;
Exit;
end;
VK_DELETE: begin
if (eoDisableDelete in FExOptions) then Exit;
if not ReadOnly and CanModify then
begin
DeleteClick(nil);
Exit;
end;
end;
end
end
else
begin
case Key of
VK_LEFT: if (FixedCols > 0) and not (dgRowSelect in Options) then
begin
if SelectedIndex <= FFixedCols then Exit;
end;
VK_HOME: if (FixedCols > 0) and (ColCount <> IndicatorOffset + 1) and
not (dgRowSelect in Options) then
begin
SelectedIndex := FixedCols;
Exit;
end;
VK_SPACE: if (eoBooleanAsCheckbox in FExOptions) and
(Datalink <> nil) and Datalink.Active and
(Columns[SelectedIndex].Field.DataType = ftBoolean) then
CellClick(Columns[SelectedIndex]);
end;
case Key of
VK_DOWN: begin
NextRow(True);
Exit;
end;
VK_INSERT: if (eoDisableInsert in FExOptions) then Exit;
VK_UP: begin
PriorRow(True);
Exit;
end;
13: if (eoENTERlikeTAB in FExOptions) then
{going on next column}
if (SelectedIndex < Columns.Count-1) then
SelectedIndex := SelectedIndex + 1
else
SelectedIndex := 0;
end;
if ((Key in [VK_LEFT, VK_RIGHT]) and (dgRowSelect in Options)) or
((Key in [VK_HOME, VK_END]) and ((ColCount = IndicatorOffset + 1)
or (dgRowSelect in Options))) or (Key in [VK_ESCAPE, VK_NEXT,
VK_PRIOR]) or ((Key = VK_INSERT) and (CanModify and
(not ReadOnly) and (dgEditing in Options))) then
ClearSelections
else
if ((Key = VK_TAB) and not (ssAlt in Shift)) then
CheckTab(not (ssShift in Shift));
end;
OnKeyDown := nil;
// try
inherited KeyDown(Key, Shift);
// except
// end;
OnKeyDown := KeyDownEvent;
end;
procedure TSMDBGrid.TopLeftChanged;
begin
if (dgRowSelect in Options) and DefaultDrawing then
GridInvalidateRow(Self, Self.Row);
inherited TopLeftChanged;
if FTracking then StopTracking;
end;
procedure TSMDBGrid.StopTracking;
begin
if FTracking then
begin
TrackButton(-1, -1);
FTracking := False;
MouseCapture := False;
end;
end;
procedure TSMDBGrid.TrackButton(X, Y: Integer);
var
Cell: TGridCoord;
NewPressed: Boolean;
begin
Cell := MouseCoord(X, Y);
NewPressed := PtInRect(Rect(0, 0, ClientWidth, ClientHeight), Point(X, Y))
and (FPressedCol = Cell.X) and (Cell.Y = 0);
if FPressed <> NewPressed then
begin
FPressed := NewPressed;
GridInvalidateRow(Self, 0);
end;
end;
procedure TSMDBGrid.MouseDown(Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
procedure SetEnabledItems;
begin
with FDBPopUpMenu do
begin
{Append}
if Assigned(Datalink.DataSet) then
Items[0].Enabled := not (eoDisableInsert in FExOptions) and
(not ReadOnly) and
Datalink.DataSet.CanModify and
(Datalink.DataSet.State = dsBrowse)
else
Items[0].Enabled := False;
{Insert}
Items[1].Enabled := Items[0].Enabled;
{Edit}
if Assigned(Datalink.DataSet) then
Items[2].Enabled := not ReadOnly and
Datalink.DataSet.CanModify and
(Datalink.DataSet.State = dsBrowse)
// and (Datalink.DataSet.RecordCount > 0)
else
Items[2].Enabled := False;
{Delete}
if Assigned(Datalink.DataSet) then
Items[3].Enabled := (not (eoDisableDelete in FExOptions)) and
(not ReadOnly) and
Datalink.DataSet.CanModify and
(Datalink.DataSet.State = dsBrowse)
// and (Datalink.DataSet.RecordCount > 0)
else
Items[3].Enabled := False;
{Print}
Items[5].Enabled := True;
Items[5].Visible := Assigned(FOnPrintData);
if Assigned(Datalink.DataSet) then
Items[5].Enabled := (Datalink.DataSet.State = dsBrowse) and Assigned(FOnPrintData)
else
Items[5].Enabled := False;
{Export}
Items[6].Enabled := True;
Items[6].Visible := Assigned(FOnExportData);
if Assigned(Datalink.DataSet) then
Items[6].Enabled := (Datalink.DataSet.State = dsBrowse) and Assigned(FOnExportData)
else
Items[6].Enabled := False;
Items[7].Visible := Items[5].Visible or Items[6].Visible;
{Post}
if Assigned(Datalink.DataSet) then
Items[8].Enabled := (not ReadOnly) and
(Datalink.DataSet.State in [dsInsert, dsEdit]) and
Datalink.DataSet.CanModify
else
Items[8].Enabled := False;
{Cancel}
if Assigned(Datalink.DataSet) then
Items[9].Enabled := (not ReadOnly) and
(Datalink.DataSet.State in [dsInsert, dsEdit])
else
Items[9].Enabled := False;
{Refresh}
if Assigned(Datalink.DataSet) then
Items[10].Enabled := (Datalink.DataSet.State = dsBrowse)
else
Items[10].Enabled := False;
{select/unselect}
Items[12].Enabled := Assigned(Datalink.DataSet) and
Datalink.DataSet.Active and
(dgMultiSelect in Options);
{save/restore layout}
Items[14].Enabled := True;
Items[15].Enabled := True;
Items[13].Visible := (eoLayout in ExOptions);
Items[14].Visible := (eoLayout in ExOptions);
Items[15].Visible := (eoLayout in ExOptions);
Items[14].Enabled := (eoLayout in ExOptions);
Items[15].Enabled := (eoLayout in ExOptions);
{setup of the grid}
Items[17].Enabled := True;
Items[17].Visible := Assigned(FOnSetupGrid);
if Assigned(Datalink.DataSet) then
Items[17].Enabled := Assigned(FOnSetupGrid)
else
Items[17].Enabled := False;
Items[16].Visible := Items[17].Visible;
end;
end;
var
Cell: TGridCoord;
MouseDownEvent: TMouseEvent;
EnableClick: Boolean;
PopCoord: TPoint;
begin
if not AcquireFocus then Exit;
if (ssDouble in Shift) and (Button = mbLeft) then
begin
DblClick;
Exit;
end;
if (dgMultiSelect in Options) then
StartOfSelect := DataLink.DataSet.GetBookmark;
if Sizing(X, Y) then
inherited MouseDown(Button, Shift, X, Y)
else
begin
Cell := MouseCoord(X, Y);
if not (csDesigning in ComponentState) and
(eoStandardPopup in FExOptions) and
((dgIndicator in Options) and
(Cell.Y < TitleOffset) and
(Cell.X < IndicatorOffset) or
((Button = mbRight) and (Cell.X >= IndicatorOffset) and not Assigned(PopupMenu))) then
begin
SetEnabledItems;
PopCoord := ClientToScreen(Point(X, Y));
FDBPopUpMenu.Popup(PopCoord.X, PopCoord.Y);
end
else
if (eoTitleButtons in ExOptions) and
(Datalink <> nil) and Datalink.Active and
(Cell.Y < TitleOffset) and (Cell.X >= IndicatorOffset) and
not (csDesigning in ComponentState) then
begin
if (dgColumnResize in Options) and (Button = mbRight) then
begin
Button := mbLeft;
FSwapButtons := True;
MouseCapture := True;
end
else
if (Button = mbLeft) then
begin
EnableClick := True;
CheckTitleButton(Cell.X - IndicatorOffset, EnableClick);
if EnableClick then
begin
MouseCapture := True;
FTracking := True;
FPressedCol := Cell.X;
TrackButton(X, Y);
end
else
Beep;
Exit;
end;
end;
if (Cell.X < FixedCols + IndicatorOffset) and Datalink.Active then
begin
if (dgIndicator in Options) then
inherited MouseDown(Button, Shift, 1, Y)
else
if Cell.Y >= TitleOffset then
if Cell.Y - Row <> 0 then
Datalink.Dataset.MoveBy(Cell.Y - Row);
end
else
inherited MouseDown(Button, Shift, X, Y);
MouseDownEvent := OnMouseDown;
if Assigned(MouseDownEvent) then
MouseDownEvent(Self, Button, Shift, X, Y);
if not (((csDesigning in ComponentState) or (dgColumnResize in Options)) and
(Cell.Y < TitleOffset)) and (Button = mbLeft) then
begin
if (dgMultiSelect in Options) and Datalink.Active then
with SelectedRows do
begin
FSelecting := False;
if ssCtrl in Shift then
begin
CurrentRowSelected := not CurrentRowSelected;
if Assigned(FOnChangeSelection) then
FOnChangeSelection(Self);
end
else
if not (eoKeepSelection in ExOptions) then
begin
Clear;
CurrentRowSelected := True;
if Assigned(FOnChangeSelection) then
FOnChangeSelection(Self);
end
end;
end;
end;
end;
procedure TSMDBGrid.MouseUp(Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
var
Cell: TGridCoord;
ACol: Longint;
DoClick: Boolean;
EndOfSelect, Test: TBookmark;
SelectForwards: Boolean;
CompareStart: Integer;
begin
{for shoft+click selection
Thanks to Roy Lambert [roy.lambert@ntlworld.com]}
if (dgMultiSelect in Options) and
(ssShift in Shift) and
Assigned(StartOfSelect) then
begin
DataLink.DataSet.DisableControls;
EndOfSelect := DataLink.DataSet.GetBookmark;
DataLink.DataSet.GotoBookmark(StartOfSelect);
CompareStart := DataLink.DataSet.CompareBookmarks(EndOfSelect, StartOfSelect);
if CompareStart <> 0 then
begin
SelectForwards := CompareStart > 0;
repeat
SelectedRows.CurrentRowSelected := True;
Test := DataLink.DataSet.GetBookmark;
if SelectForwards then
DataLink.DataSet.Next
else
DataLink.DataSet.Prior;
until (DataLink.DataSet.CompareBookmarks(EndOfSelect, Test) = 0) or DataLink.DataSet.Eof or DataLink.DataSet.Bof;
end;
DataLink.DataSet.GotoBookmark(EndOfSelect);
if Assigned(EndOfSelect) then
DataLink.DataSet.FreeBookmark(EndOfSelect);
if Assigned(Test) then
DataLink.DataSet.FreeBookmark(Test);
DataLink.DataSet.EnableControls;
end;
Cell := MouseCoord(X, Y);
ACol := Cell.X;
if (dgIndicator in Options) then
Dec(ACol);
if FTracking and (FPressedCol >= 0) then
begin
DoClick := PtInRect(Rect(0, 0, ClientWidth, ClientHeight), Point(X, Y))
and (Cell.Y = 0) and (Cell.X = FPressedCol);
StopTracking;
if DoClick then
begin
if (DataLink <> nil) and
DataLink.Active and
(ACol >= 0) and
(ACol < Columns.Count) then
else
CellClick(Columns[ACol]);
end;
end
else
if FSwapButtons then
begin
FSwapButtons := False;
MouseCapture := False;
if Button = mbRight then
Button := mbLeft;
end;
if (eoCheckBoxSelect in ExOptions) and
(dgMultiSelect in Options) and
(Cell.X < IndicatorOffset) and
(Cell.Y >= 0) then
ToggleRowSelection;
if (Button = mbLeft) and
(Cell.X >= IndicatorOffset) and
(ACol <= FixedCols) and
(Cell.Y > TitleOffset) then
CellClick(Columns[ACol])
else
inherited MouseUp(Button, Shift, X, Y);
end;
{from Borland sources}
procedure WriteTitleText(ACanvas: TCanvas; ARect: TRect; DX, DY: Integer;
const Text: string; Alignment: TAlignment);
const
AlignFlags: array [TAlignment] of Integer =
(DT_LEFT or DT_WORDBREAK or DT_EXPANDTABS or DT_NOPREFIX,
DT_RIGHT or DT_WORDBREAK or DT_EXPANDTABS or DT_NOPREFIX,
DT_CENTER or DT_WORDBREAK or DT_EXPANDTABS or DT_NOPREFIX);
var
B, R, rect1: TRect;
txth: Integer;
{$IFDEF VER120}
I: TColorRef;
{$ELSE}
{$IFDEF VER130}
I: TColorRef;
{$ELSE}
{$IFDEF VER140}
I: TColorRef;
{$ELSE}
{$IFDEF VER150}
I: TColorRef;
{$ELSE}
I: Integer;
{$ENDIF}
{$ENDIF}
{$ENDIF}
{$ENDIF}
lpDTP: TDrawTextParams;
DrawBitmap: TBitmap;
begin
I := ColorToRGB(ACanvas.Brush.Color);
if GetNearestColor(ACanvas.Handle, I) = I then
begin
ACanvas.FillRect(ARect);
rect1.Left := 0;
rect1.Top := 0;
rect1.Right := 0;
rect1.Bottom := 0;
rect1 := ARect;
lpDTP.cbSize := SizeOf(lpDTP);
lpDTP.uiLengthDrawn := Length(Text);
lpDTP.iLeftMargin := 0;
lpDTP.iRightMargin := 0;
InflateRect(rect1, -DX, -DY);
txth := DrawTextEx(ACanvas.Handle,PChar(Text), Length(Text),
rect1, DT_WORDBREAK or DT_CALCRECT, @lpDTP);
rect1 := ARect;
InflateRect(rect1, -DX, -DY);
rect1.top := rect1.top + ((rect1.Bottom-rect1.top) div 2) - (txth div 2);
DrawTextEx(ACanvas.Handle, PChar(Text), Length(Text),
rect1, AlignFlags[Alignment], @lpDTP);
end
else
begin
DrawBitmap := TBitmap.Create;
DrawBitmap.Canvas.Lock;
try
with DrawBitmap, ARect do
begin
Width := Max(Width, Right - Left);
Height := Max(Height, Bottom - Top);
R := Rect(DX, DY, Right - Left - 1, Bottom - Top - 1);
B := Rect(0, 0, Right - Left, Bottom - Top);
end;
with DrawBitmap.Canvas do
begin
Font := ACanvas.Font;
Font.Color := ACanvas.Font.Color;
Brush := ACanvas.Brush;
Brush.Style := bsSolid;
FillRect(B);
SetBkMode(Handle, TRANSPARENT);
DrawText(Handle, PChar(Text), Length(Text), R, AlignFlags[Alignment]);
end;
ACanvas.CopyRect(ARect, DrawBitmap.Canvas, B);
finally
DrawBitmap.Canvas.Unlock;
DrawBitmap.Free;
end;
end;
end;
procedure TSMDBGrid.CellClick(Column: TColumn);
var R: TRect;
BCol: Integer;
begin
inherited CellClick(Column);
if (Datalink <> nil) and
Datalink.Active and
Assigned(Column.Field) and
(Column.Field.DataType = ftBoolean) and
(eoBooleanAsCheckBox in FExOptions) and
CanEditModify then
begin
try
Column.Field.AsBoolean := not Column.Field.AsBoolean;
// Column.Field.Value := not Column.Field.Value;
except
Column.Field.Value := NULL;
end;
if (dgIndicator in Options) then
BCol := Column.Index + 1
else
BCol := Column.Index;
GetEditText(BCol, Row);
R := CellRect(BCol, Row);
DrawCell(BCol, Row, R, [{gdSelected, gdFocused}]);
end
else
if (eoShowLookup in ExOptions) and
(not ReadOnly) and
(dgEditing in Options) and
(not Column.ReadOnly) and
Assigned(Column.Field) and
(not Column.Field.ReadOnly) then
begin
if (Column.Field.FieldKind = fkLookup) or
(Column.PickList.Count > 0) then
begin {Open combobox quickly when lookup field}
keybd_event(VK_F2, 0, 0, 0);
keybd_event(VK_F2, 0, KEYEVENTF_KEYUP, 0);
keybd_event(VK_MENU, 0, 0, 0);
keybd_event(VK_DOWN, 0, 0, 0);
keybd_event(VK_DOWN, 0, KEYEVENTF_KEYUP, 0);
keybd_event(VK_MENU, 0, KEYEVENTF_KEYUP, 0);
end
else
if (Column.ButtonStyle = cbsEllipsis) then
begin {Click quickly when ButtonStyle property is cbsEllipsis}
if not EditorMode then
EditorMode := True;
EditButtonClick;
end;
end;
end;
function TSMDBGrid.GetSortImageWidth: Integer;
begin
Result := Max(GetGridBitmap(gpSortAsc).Width, GetGridBitmap(gpSortDesc).Width);
end;
function TSMDBGrid.CellRectForDraw(R: TRect; ACol: Longint): TRect;
var i, j: Integer;
begin
Result := R;
j := GetSortImageWidth;
if (Result.Right-Result.Left > j+4) then
begin
for i := 0 to SortColumns.Count-1 do
if (SortColumns[i].FieldName = Columns[ACol].FieldName) and
(SortColumns[i].SortType <> stNone) then
break;
if (i < SortColumns.Count) then
Result.Right := Result.Right-j-4;
end;
i := 2*(GridLineWidth+1)+1;
Result.Right := Result.Right-i
end;
function TSMDBGrid.GetGlyph: TBitmap;
begin
Result := nil;
if Assigned(FOnGetGlyph) then
FOnGetGlyph(Self, Result);
end;
procedure TSMDBGrid.DrawCheckBox(R: TRect; AState: TCheckBoxState; al: TAlignment);
var
DrawState: Integer;
DrawRect: TRect;
begin
{draw CheckBox instead Bitmap indicator}
{ Canvas.Brush.Color := FixedColor;
Canvas.Font.Name := 'Symbol';
Canvas.Font.Color := clWindowText;
Canvas.Font.Style := [fsBold];
WriteTitleText(Canvas, FixRect, 0, 0, '╓', taCenter);
}
case AState of
cbChecked: DrawState := DFCS_BUTTONCHECK or DFCS_CHECKED;
cbUnchecked: DrawState := DFCS_BUTTONCHECK;
else // cbGrayed
DrawState := DFCS_BUTTON3STATE or DFCS_CHECKED;
end;
case al of
taRightJustify: begin
DrawRect.Left := R.Right - FCheckWidth;
DrawRect.Right := R.Right;
end;
taCenter: begin
DrawRect.Left := R.Left + (R.Right - R.Left - FCheckWidth) div 2;
DrawRect.Right := DrawRect.Left + FCheckWidth;
end;
else // taLeftJustify
DrawRect.Left := R.Left;
DrawRect.Right := DrawRect.Left + FCheckWidth;
end;
DrawRect.Top := R.Top + (R.Bottom - R.Top - FCheckWidth) div 2;
DrawRect.Bottom := DrawRect.Top + FCheckHeight;
DrawFrameControl(Canvas.Handle, DrawRect, DFC_BUTTON, DrawState);
end;
procedure TSMDBGrid.DrawCell(ACol, ARow: Longint; ARect: TRect; AState: TGridDrawState);
var
TitleText: string;
i, j, idxSort, BCol: LongInt;
CheckState: TCheckBoxState;
Down: Boolean;
SavePen, BackColor: TColor;
AField: TField;
OldActive: Longint;
FrameOffs: Byte;
// Indicator: Integer;
// MultiSelected: Boolean;
BRect, FixRect: TRect;
DrawColumn: TColumn;
bmp: TBitmap;
const
EdgeFlag: array[Boolean] of UINT = (BDR_RAISEDINNER, BDR_SUNKENINNER);
begin
if (dgIndicator in Options) then
BCol := ACol - 1
else
BCol := ACol;
if (gdFixed in AState) and (ARow = 0) and (dgTitles in Options) and
((ACol <> 0) or ((ACol = 0) and (dgIndicator in Options) and (eoStandardPopup in FExOptions))) then
begin
// draw border
if DefaultDrawing then
begin
if (ACol = 0) and (dgIndicator in Options) then
begin
Down := False;
Canvas.Brush.Color := FixedColor
end
else
begin
Down := (eoSelectedTitle in FExOptions) and (BCol = SelectedIndex);
if (BCol > -1) and Assigned(Columns[BCol]) then
Canvas.Brush.Color := Columns[BCol].Title.Color;
end;
DrawEdge(Canvas.Handle, ARect, EdgeFlag[Down], BF_BOTTOMLEFT);
DrawEdge(Canvas.Handle, ARect, EdgeFlag[Down], BF_TOPRIGHT);
InflateRect(ARect, -1, -1);
Canvas.FillRect(ARect);
end;
j := GetSortImageWidth;
if (ACol = 0) and
(dgIndicator in Options) and
(eoStandardPopup in FExOptions) then
begin
Canvas.Brush.Color := clBlack;
i := (ARect.Bottom - ARect.Top - 7) div 2;
idxSort := (ARect.Right - ARect.Left - 7) div 2;
Canvas.Polygon([Point(ARect.Left + idxSort, ARect.Top + i),
Point(ARect.Left + idxSort + 7, ARect.Top + i),
Point(ARect.Left + idxSort + (7 div 2), ARect.Bottom - i)]);
end
else
if (BCol > -1) and Assigned(Columns[BCol]) then
begin
TitleText := Columns[BCol].Title.Caption;
{draw a column sorted image}
//look: whether there is a sorting according this column
idxSort := -1;
if (ARect.Right-ARect.Left > j) then
begin
for i := 0 to SortColumns.Count-1 do
if (SortColumns[i].FieldName = Columns[BCol].FieldName) and
(SortColumns[i].SortType <> stNone) then
begin
idxSort := i;
break
end;
if idxSort > -1 then
ARect.Right := ARect.Right-j;
end;
//draw title.caption
if DefaultDrawing and (TitleText <> '') then
begin
Canvas.Brush.Style := bsClear;
Canvas.Font := Columns[BCol].Title.Font;
Canvas.Brush.Color := Columns[BCol].Title.Color;
WriteTitleText(Canvas, ARect, 2, 2, TitleText, Columns[BCol].Title.Alignment);
if idxSort > -1 then
begin
ARect.Right := ARect.Right+j;
i := (ARect.Bottom - ARect.Top - j) div 2;
if (SortColumns[idxSort].SortType = stAscending) then
begin
Bmp := GetGridBitmap(gpSortAsc);
{ Canvas.Pen.Color := clBtnShadow;
Canvas.MoveTo(ARect.Right - 4, ARect.Top + i);
Canvas.LineTo(ARect.Right - 4 - j, ARect.Top + i);
Canvas.LineTo(ARect.Right - 4 - (j div 2), ARect.Bottom - i);
Canvas.Pen.Color := clBtnHighlight;
Canvas.LineTo(ARect.Right - 4, ARect.Top + i);
}
end
else
begin
Bmp := GetGridBitmap(gpSortDesc);
{ Canvas.Pen.Color := clBtnHighlight;
Canvas.MoveTo(ARect.Right - 4 - (j div 2), ARect.Top + i);
Canvas.LineTo(ARect.Right - 4, ARect.Bottom - i);
Canvas.LineTo(ARect.Right - 4 - j, ARect.Bottom - i);
Canvas.Pen.Color := clBtnShadow;
Canvas.LineTo(ARect.Right - 4 - (j div 2), ARect.Top + i);
}
end;
BRect := Bounds(ARect.Right - 4 - j, ARect.Top+i, j, j);
Canvas.FillRect(BRect);
DrawBitmapTransparent(Canvas, (BRect.Left + BRect.Right - Bmp.Width) div 2,
(BRect.Top + BRect.Bottom - Bmp.Height) div 2, Bmp, clSilver);
if (SortColumns[idxSort].SortCaption <> '') then
begin
BRect.Right := ARect.Right - 4;
BRect.Left := BRect.Right - j;
BRect.Top := ARect.Top + i;
BRect.Bottom := ARect.Bottom;
with Canvas.Font do
begin
Name := 'Small Fonts';
Size := 5;
Style := [];
end;
Canvas.Brush.Style := bsClear;
DrawText(Canvas.Handle,
PChar(SortColumns[idxSort].SortCaption),
Length(SortColumns[idxSort].SortCaption),
BRect,
DT_EXPANDTABS or DT_CENTER or DT_VCENTER or DT_NOPREFIX);
end;
end;
end
end;
if (BCol > -1) and Assigned(FOnDrawColumnTitle) then
FOnDrawColumnTitle(Self, ARect, ACol, Columns[BCol], AState);
end
else
begin
if (BCol > -1) and
((ACol > 0) or (not (dgIndicator in Options) and (ACol = 0))) and DefaultDrawing and
(eoBooleanAsCheckBox in FExOptions) and
(Datalink <> nil) and
Datalink.Active and
Assigned(Columns[BCol]) and
Assigned(Columns[BCol].Field) and
(Columns[BCol].Field.DataType = ftBoolean) and
(((ARow > 0) and (dgTitles in Options)) or (not (dgTitles in Options))) then
begin
DrawColumn := Columns[BCol];
if Assigned(DrawColumn.Field) then
TitleText := DrawColumn.Field.DisplayText
else
TitleText := '';
if (BCol <= FixedCols) and (FixedCols > 0) then
Canvas.Brush.Color := FixedColor
else
if HighlightCell(ACol, ARow, TitleText, AState) then
Canvas.Brush.Color := clHighlight
else
Canvas.Brush.Color := DrawColumn.Color;
Canvas.FillRect(ARect);
InflateRect(ARect, -2, -2);
OldActive := DataLink.ActiveRecord;
CheckState := cbUnChecked;
try
DataLink.ActiveRecord := ARow - TitleOffset;
try
if DrawColumn.Field.IsNull then
CheckState := cbUnChecked
else
if DrawColumn.Field.Value then
CheckState := cbChecked
// TCheckBoxState(DrawColumn.Field.Value);
except
end
finally
DataLink.ActiveRecord := OldActive;
end;
DrawCheckBox(ARect, CheckState, taCenter);
InflateRect(ARect, 2, 2);
end
else
begin
if (eoFixedLikeColumn in ExOptions) and
(ACol > 0) and
(ACol <= FixedCols) then
AState := AState - [gdFixed];
inherited DrawCell(ACol, ARow, ARect, AState)
end;
end;
if (dgIndicator in Options) and (ACol = 0) and (ARow - TitleOffset >= 0) and
(dgMultiSelect in Options) and (DataLink <> nil) and DataLink.Active {and
(Datalink.DataSet.State = dsBrowse) }then
begin
{ draw multiselect indicators if needed }
FixRect := ARect;
if ([dgRowLines, dgColLines] * Options = [dgRowLines, dgColLines]) then
begin
InflateRect(FixRect, -1, -1);
FrameOffs := 1;
end
else
FrameOffs := 2;
CheckState := cbUnChecked;
OldActive := DataLink.ActiveRecord;
try
Datalink.ActiveRecord := ARow - TitleOffset;
// MultiSelected := ActiveRowSelected;
if ActiveRowSelected then
CheckState := cbChecked;
Bmp := GetGlyph;
finally
Datalink.ActiveRecord := OldActive;
end;
if (eoCheckBoxSelect in ExOptions) then
begin
BRect := FixRect;
BRect.Right := BRect.Right - 2*FrameOffs - FMsIndicators.Width;
DrawCheckBox(BRect, CheckState, taRightJustify);
end;
{ if MultiSelected then
begin
if (ARow - TitleOffset <> Datalink.ActiveRecord) then
Indicator := 0
else //multiselected and current row
Indicator := 1;
FMsIndicators.BkColor := FixedColor;
FMsIndicators.Draw(Self.Canvas, FixRect.Right - FMsIndicators.Width -
FrameOffs, (FixRect.Top + FixRect.Bottom - FMsIndicators.Height)
shr 1, Indicator);
end;
}
if (Bmp <> nil) then
begin
BRect.Left := FixRect.Left + FrameOffs;
BRect.Top := FixRect.Top + FrameOffs;
if (bmp.Width < FixRect.Right - FixRect.Left) then
BRect.Right := BRect.Left + bmp.Width
else
if (eoCheckBoxSelect in ExOptions) then
BRect.Right := FixRect.Right - FCheckWidth - FrameOffs
else
BRect.Right := FixRect.Right - FMsIndicators.Width - FrameOffs;
BRect.Bottom := FixRect.Bottom - FrameOffs;
Canvas.StretchDraw(BRect, bmp);
end;
end;
if (eoTitleButtons in ExOptions) and
not (csLoading in ComponentState) and
(gdFixed in AState) and
(dgTitles in Options) and (ARow = 0) then
begin
SavePen := Canvas.Pen.Color;
try
Down := (FPressedCol = ACol) and FPressed;
Canvas.Pen.Color := clWindowFrame;
if not (dgColLines in Options) then
begin
Canvas.MoveTo(ARect.Right - 1, ARect.Top);
Canvas.LineTo(ARect.Right - 1, ARect.Bottom);
Dec(ARect.Right);
end;
if not (dgRowLines in Options) then
begin
Canvas.MoveTo(ARect.Left, ARect.Bottom - 1);
Canvas.LineTo(ARect.Right, ARect.Bottom - 1);
Dec(ARect.Bottom);
end;
if (dgIndicator in Options) then Dec(ACol);
AField := nil;
if (DataLink <> nil) and DataLink.Active and (ACol >= 0) and
(ACol < Columns.Count) then
begin
DrawColumn := Columns[ACol];
AField := DrawColumn.Field;
end
else
DrawColumn := nil;
DrawEdge(Canvas.Handle, ARect, EdgeFlag[Down], BF_BOTTOMRIGHT);
DrawEdge(Canvas.Handle, ARect, EdgeFlag[Down], BF_TOPLEFT);
InflateRect(ARect, -1, -1);
if Down then
begin
Inc(ARect.Left);
Inc(ARect.Top);
end;
Canvas.Font := TitleFont;
Canvas.Brush.Color := FixedColor;
if (DrawColumn <> nil) then
begin
Canvas.Font := DrawColumn.Title.Font;
Canvas.Brush.Color := DrawColumn.Title.Color;
end;
if (AField <> nil) and Assigned(FOnGetBtnParams) then
begin
BackColor := Canvas.Brush.Color;
FOnGetBtnParams(Self, AField, Canvas.Font, BackColor, Down);
Canvas.Brush.Color := BackColor;
end;
if (DataLink = nil) or not DataLink.Active then
Canvas.FillRect(ARect)
else
if (BCol > -1) and (DrawColumn <> nil) then
WriteTitleText(Canvas, ARect, 2, 2, DrawColumn.Title.Caption, Columns[BCol].Title.Alignment)
else
WriteTitleText(Canvas, ARect, 2, 2, '', taLeftJustify);
finally
Canvas.Pen.Color := SavePen;
end;
end;
end;
procedure TSMDBGrid.DrawColumnCell(const Rect: TRect; DataCol: Integer;
Column: TColumn; State: TGridDrawState);
var
i: Integer;
NewBackgrnd: TColor;
Highlight: Boolean;
Bmp: TBitmap;
Field: TField;
{the TRect for drawing simulated combobox}
RectLookup: TRect;
W, intMidX: Integer;
begin
with RectLookup do
begin
Left := Rect.Right - (Rect.Bottom - Rect.Top)+1;
Top := Rect.Top+1;
Right := Rect.Right-1;
Bottom := Rect.Bottom-1;
end;
Field := Column.Field;
NewBackgrnd := Canvas.Brush.Color;
Highlight := (gdSelected in State) and ((dgAlwaysShowSelection in Options) or Focused);
GetCellProps(Field, Canvas.Font, NewBackgrnd, Highlight or ActiveRowSelected);
Canvas.Brush.Color := NewBackgrnd;
if DefaultDrawing then
begin
i := GetImageIndex(Field);
if i >= 0 then
begin
Bmp := GetGridBitmap(TGridPicture(i));
Canvas.FillRect(Rect);
DrawBitmapTransparent(Canvas, (Rect.Left + Rect.Right - Bmp.Width) div 2,
(Rect.Top + Rect.Bottom - Bmp.Height) div 2, Bmp, clOlive);
end
else
DefaultDrawColumnCell(Rect, DataCol, Column, State);
if (eoDrawGraphicField in FExOptions) and
(Column.Field is TBlobField) and
(Column.Field.DataType = ftGraphic) then
begin
bmp := TBitmap.Create;
try
bmp.Assign(Field);
Canvas.StretchDraw(Rect, bmp);
finally
bmp.Free;
end;
end;
end;
if Columns.State = csDefault then
inherited DrawDataCell(Rect, Field, State);
inherited DrawColumnCell(Rect, DataCol, Column, State);
if DefaultDrawing and Highlight and not (csDesigning in ComponentState)
and not (dgRowSelect in Options)
and (ValidParentForm(Self).ActiveControl = Self) then
Canvas.DrawFocusRect(Rect);
if (eoShowLookup in ExOptions) then
begin
if (Column.Field.FieldKind = fkLookup) or
(Column.PickList.Count > 0) then
begin //Drawing combobox if FieldKind is lookup
Canvas.FillRect(Rect);
DefaultDrawColumnCell(Rect, DataCol, Column, State);
{Drawing combobox-area }
DrawFrameControl(Canvas.Handle, RectLookup, DFC_SCROLL, DFCS_SCROLLCOMBOBOX);
end
else
if Column.ButtonStyle = cbsEllipsis then
begin
{Show "?" when ButtonStyle Property is cbsEllipsis }
// DrawFrameControl(Canvas.Handle, RectLookup, DFC_CAPTION, DFCS_CAPTIONHELP)
Canvas.FillRect(RectLookup);
DrawEdge(Canvas.Handle, RectLookup, EDGE_RAISED, BF_RECT or BF_MIDDLE);
intMidX := (RectLookup.Right - RectLookup.Left) shr 1;
W := (RectLookup.Bottom - RectLookup.Top) shr 3;
if W = 0 then W := 1;
PatBlt(Canvas.Handle, RectLookup.Left + intMidX, RectLookup.Top + intMidX, W, W, BLACKNESS);
PatBlt(Canvas.Handle, RectLookup.Left + intMidX - (W * 2), RectLookup.Top + intMidX, W, W, BLACKNESS);
PatBlt(Canvas.Handle, RectLookup.Left + intMidX + (W * 2), RectLookup.Top + intMidX, W, W, BLACKNESS);
end
else
{Draw in default except above conditions}
DefaultDrawColumnCell(Rect, DataCol, Column, State);
end;
{draw title}
// DrawCell(SelectedIndex+1, 0, Rect, [gdFixed]);
end;
{is transferred from TBitDBGrid:
Ilya Andreev, ilya_andreev@geocities.com
FIDONet: 2:5030/55.28 AKA 2:5030/402.17}
procedure TSMDBGrid.CMHintShow(var Msg: TMessage);
var ACol, ARow: Integer;
OldActive: Integer;
begin
if eoCellHint in FExOptions then
with PHintInfo(Msg.LParam)^ do
try
HintStr := Hint;
Msg.Result := 1;
if not DataLink.Active then Exit;
TDrawGrid(Self).MouseToCell(CursorPos.X, CursorPos.Y, ACol, ARow);
CursorRect := CellRect(ACol, ARow);
ACol := ACol - IndicatorOffset;
if (ACol < 0) then Exit;
ARow := ARow - TitleOffset;
HintPos := ClientToScreen(CursorRect.TopLeft);
InflateRect(CursorRect, 1, 1);
if (ARow = -1) then
begin
HintStr := Columns[ACol].Title.Caption;
if Canvas.TextWidth(HintStr) < Columns[ACol].Width then Exit;
Msg.Result := 0;
Exit;
end;
if ARow < 0 then exit;
OldActive := DataLink.ActiveRecord;
DataLink.ActiveRecord := ARow;
if Columns[ACol].Field <> nil then
if Columns[ACol].Field.IsBlob then
HintStr := Columns[ACol].Field.AsString
else
HintStr := Columns[ACol].Field.DisplayText;
DataLink.ActiveRecord := OldActive;
if (((CursorRect.Right - CursorRect.Left) >= Columns[ACol].Width) and
(Canvas.TextWidth(HintStr) < Columns[ACol].Width)) or
((Canvas.TextWidth(HintStr) < (CursorRect.Right - CursorRect.Left)) and
(Columns[ACol].Alignment = taLeftJustify)) then exit;
Msg.Result := 0;
except
Msg.Result := 1;
end;
end;
{end of transfered}
procedure TSMDBGrid.SaveLayoutToRegistry;
var RegIniFile: TRegIniFile;
i: Integer;
begin
RegIniFile := TRegIniFile.Create(FRegistryKey);
RegIniFile.WriteInteger(FRegistrySection, 'Count', Columns.Count);
for i := 0 to (Columns.Count-1) do
begin
with Columns.Items[i] do
RegIniFile.WriteString(FRegistrySection, IntToStr(i),
Format('%s,%d,%s', [FieldName, Width, Title.Caption]));
end;
RegIniFile.Free;
end;
procedure TSMDBGrid.RestoreLayoutFromRegistry;
function GetValueFromKey(var strValues: string): string;
var j: Integer;
begin
j := Pos(',', strValues);
Result := Copy(strValues, 1, j-1);
Delete(strValues, 1, j);
end;
var RegIniFile: TRegIniFile;
i, Count: Integer;
s: string;
begin
{ disable DBGrid-repaint while not will executed EndLayout
Because I donn't want to repaint of the grid after each
addition and after Columns.Clear }
BeginLayout;
RegIniFile := TRegIniFile.Create(FRegistryKey);
Count := RegIniFile.ReadInteger(FRegistrySection, 'Count', 0);
if (Count > 0) then
begin
Columns.Clear;
for i := 0 to (Count-1) do
begin
S := RegIniFile.ReadString(FRegistrySection, IntToStr(i), '');
if (S <> '') then
begin
with Columns.Add do
begin
FieldName := GetValueFromKey(S);
Width := StrToIntDef(GetValueFromKey(S), 64);
Title.Caption := S;
end;
end;
end;
end;
RegIniFile.Free;
EndLayout;
end;
initialization
finalization
DestroyLocals;
end.