问题
For our dbgrid we want the scrollbars to be constantly hidden. Since TDBGrid doesn't have a 'scrollbars' property, we use:
ShowScrollBar(DBGrid1.Handle, SB_VERT, False);
ShowScrollBar(DBGrid1.Handle, SB_HORZ, False);
However when we resize the window (and the panel containing the dbgrid), for a second the scrollbars appear and becom hidden again only after recalling the two above methods.
A solution is to call these methods in DrawColumnCell, but this causes flickering of the dbgrid, even with DoubleBuffered set to true.
Is there any way to hide the scrollbars permanently?
Thanks in advance!
回答1:
Hiding the scrollbar of the TDBGrid in CreateParams has a very short time effect. There's the procedure UpdateScrollBar which causes the scrollbar to be visible. It happens because the scroll bar visibility is controlled depending on the data displayed, thus this procedure is called whenever the data is changed.
And since this procedure is called whenever the scrollbar needs to be updated and because it's virtual, it's time to override it.
The following code sample uses the interposed class, so all TDBGrid components on the form which belongs to this unit will behave the same:
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs;
type
TDBGrid = class(DBGrids.TDBGrid)
private
procedure UpdateScrollBar; override;
end;
type
TForm1 = class(TForm)
DBGrid1: TDBGrid;
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
procedure TDBGrid.UpdateScrollBar;
begin
// in this procedure the scroll bar is being shown or hidden
// depending on data fetched; and since we never want to see
// it, do just nothing at all here
end;
end.
回答2:
The scroll bar is updated in TDBGrid.UpdateScrollBar
. Unfortunately this routine is not virtual (in D7 at least). Within that routine, SetScrollInfo
is called, a Windows function that doesn't send any message that could be intercept. No luck there.
The only possibility left is to override the message handler for the message that is send whenever the control changed size:
type
TDBGrid = class(DBGrids.TDBGrid)
private
procedure WMWindowPosChanged(var Message: TWMWindowPosChanged);
message WM_WINDOWPOSCHANGED;
end;
procedure TDBGrid.WMWindowPosChanged(var Message: TWMWindowPosChanged);
begin
inherited;
Windows.ShowScrollBar(Handle, SB_VERT, False);
end;
Although UpdateScrollBar
is also called when the data is changed or when the dataset's Active
property changes, this seems to work here without flickering.
回答3:
Perhaps overriding CreateParams()
method and removing WS_HSCROLL
and WS_VSCROLL
bits form Params.Style
makes difference. You could try to do it with class helper if you don't want to write custom descendant.
You could also use SetWindowLongPtr API with GWL_STYLE
to change window's style but then the changes are lost when grid's window is recreated for some reason (so it's not as reliable than overriding CreateParams
).
来源:https://stackoverflow.com/questions/7529524/keep-the-scrollbars-hidden-in-a-delphi-dbgrid-even-on-resize