A Limited Fix for the TDGrid Scrollbar Problem

I have a limited fix for this problem.  It will work as long as you do
not use the bound TDataSet's " MoveBy" method in your program logic.  I
am currently working on fixing the problem at its root, in the TDBDataSet
class.  However, until then, anyone wishing to have this work around,
please request a copy of the .DCU via e-mail.

If you have the source code for "dbgrids.pas" here is the fix:

The root of the problem lies in the fact that TDBGrid cannot handle
non-sequenced datasets.  If you look at the code for
TCustomDBGrid.WMVScroll, you find the following code:

if IsSequenced then
begin
SI.cbSize := sizeof(SI);
SI.fMask := SIF_ALL;
GetScrollInfo(Self.Handle, SB_VERT, SI); if SI.nTrackPos <= 1 then First
else if SI.nTrackPos >= RecordCount then Last else RecNo := SI.nTrackPos;
end
else
case Pos of
0: First;
1: MoveBy(-VisibleRowCount);
2: Exit;
3: MoveBy(VisibleRowCount);
4: Last;
end;

See how the TDBGrid scrollbar only has a range of 0..4 for all
non-sequenced datasets (the BDE only sequences Paradox datasets).

This code must be replaced with:

{ Begin mods by Mark T. Van Ditta -- 11/20/97 }

SI.cbSize := sizeof(SI);
SI.fMask := SIF_ALL;
GetScrollInfo(Self.Handle, SB_VERT, SI);

if SI.nTrackPos <= 1 then
First
else if SI.nTrackPos >= RecordCount then
Last
else if IsSequenced then
RecNo := SI.nTrackPos
else
Self.MoveBy(SI.nTrackPos - FlPsuedoRecNo)

{ End mods by Mark T. Van Ditta -- 11/20/97 }

Notice the Self.MoveBy method, and FlPsuedoRecNo field.  The following
entries need to be made in the TCustomDBGrid class definition, after the
"FOnTitleClick" declaration:

{ Begin mods by Mark T. Van Ditta -- 11/20/97 } FlPsuedoRecNo : LongInt;
procedure MoveBy( lDistance : LongInt );
{ End mods by Mark T. Van Ditta -- 11/20/97 }

Now add the following procedure to the implementation section of the
dbgrid.pas  unit:

{ Begin mods by Mark T. Van Ditta -- 11/20/97
Note: All references to MoveBy, in this unit, were changed to
Self.MoveBy inorder to implement my PsuedoRecNo algorithm

Quote
}

procedure TCustomDBGrid.MoveBy( lDistance : LongInt ); begin
Inc(FlPsuedoRecNo,lDistance);
FDataLink.DataSet.MoveBy(lDistance)
end; { TCustomDBGrid.MoveBy }
{ End mods by Mark T. Van Ditta -- 11/20/97 }

Notice the comment that says that all references to "MoveBy" in this
module were changed to "Self.MoveBy".  Well, this is the archilles heel
of the fix. It only works of the developer does not use the bound
dataset's "MoveBy" method in their program logic.  The FlPsuedoRecNo
variable, in TCustomDBGrid.MoveBy,  keeps track of where we are in the
dataset by adding the relative offset calculated in
TCustomDBGrid.WMVScroll.

Now we have to make the following changes to
"TCustomDBGrid.UpdateScrollBar"

change:

if IsSequenced then begin SINew.nMin := 1; SINew.nPage :=
Self.VisibleRowCount; SINew.nMax := RecordCount + SINew.nPage -1; if
State in [dsInactive, dsBrowse, dsEdit] then SINew.nPos := RecNo;  //
else keep old pos 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;

to:

{ Begin mods by Mark T. Van Ditta }

SINew.nMin := 1; SINew.nPage := Self.VisibleRowCount; SINew.nMax :=
RecordCount + SINew.nPage -1; if IsSequenced then begin if State in
[dsInactive, dsBrowse, dsEdit] then SINew.nPos := RecNo  // else keep old
pos end else begin if BOF then FlPsuedoRecNo := 1 else if EOF then
FlPsuedoRecNo := RecordCount;

if State in [dsInactive, dsBrowse, dsEdit] then
SINew.nPos := FlPsuedoRecNo  // else keep old pos
end;

{ End mods by Mark T. Van Ditta }

Did you notice how the old code set the scrollbar position to either 0
for a BOF condition, 4 for an EOF codition, or 2 for all other
conditions.  This is why the scrollbar only has three positions: top,
middle, and bottom.

In closing, remember to change all references from "MoveBy" to
"Self.MoveBy".        Remeber that some of the references will be in the form
"FDataLink.DataSet.MoveBy"  or "DataSet.MoveBy".  You have to change the
entire reference to Self.MoveBy (i.e., do not make the mistake of
changing it to FDataLink.DataSet.Self.MoveBy).

To compile a new version of dbgrids.dcu.  Copy the changed source code to
a different directory (actually you should have performed this operation
before changing the source).  Now, create a new project and add the
modified version of dbgrid.pas to the project.  Build the project, and
copy resulting new dbgrids.dcu to your Delphi "LIB" directory.

Good Luck,

Mark T. Van Ditta, BSCS

-------------------==== Posted via Deja News ====-----------------------
      http://www.dejanews.com/     Search, Read, Post to Usenet