9

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!

Warren P
  • 58,696
  • 38
  • 168
  • 301
user729103
  • 621
  • 2
  • 10
  • 24
  • Please note that `DoubleBuffered´ in Delphi VCL and, in some part, in Windows itself is not a true DoubleBuffered technique. – Christopher Ramírez Mar 29 '12 at 17:17
  • Please don't say Delphi in the title if you want a C++ Builder sample. – Warren P Mar 30 '12 at 17:38
  • Silly hack idea: Put the DBGrid into a Panel, and size the panel so that it's large enough to never show scrollbars. Instead you'll get truncated content. – Warren P Mar 30 '12 at 17:45
  • 1
    @Warren, this question was about Delphi, [`truthseeker`](http://stackoverflow.com/users/538022/truthseeker) who offered a bounty here made from this question "also" topic for C++ Builder. On a first view I thought the same, later on I got it from the comments and from an overlooked bounty assignment. IMHO this should get accepted answer and the C++ Builder version of this Q asked separately. The problem is the bounty here, but I think admins might rollback it. – TLama Apr 01 '12 at 02:27
  • 1
    fixed title. bounty confused me. – Warren P Apr 01 '12 at 12:48
  • 1
    There are more developers using Delphi than C++ Builder so I took advantage of this. – truthseeker Apr 02 '12 at 12:47

3 Answers3

7

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.
TLama
  • 71,521
  • 15
  • 192
  • 348
  • Not very familiar with delphi syntax. Can this be done without deriving new class and installing new component on toolbox in development environment? – truthseeker Mar 29 '12 at 11:46
  • 2
    This is so called insterposed class and it's enough if you put it into your unit (see the update), it will *override* the original class in the namespace where you put it in (so all TDBGrid components on the form which belongs to the unit will be *subclassed* that way). – TLama Mar 29 '12 at 11:51
  • Thats all fine but I would need this example to be rewritten in C++. All web sources I could find have samples in Delphi language. Your example could remain as it is and add to it C++ example or at least link to some authoritative source about this mechanism. – truthseeker Mar 29 '12 at 12:03
  • @truthseeker, I guess you mean C++ Builder, don't you ? – TLama Mar 29 '12 at 12:06
  • Class helper syntax does not appear to be available for C++ Builder itself. Since you're modifying a VCL class, which is Delphi, you really should create an inherited class and put it into a package. `TDBGridWithoutScrollbar` Your "no packages, no component installation" requirement is unreasonable in a C++ Builder context. – Warren P Mar 30 '12 at 17:51
  • This code hides vertical scrollbar but not horizontal – Anton Duzenko Jun 13 '16 at 14:20
1

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.

NGLN
  • 41,230
  • 8
  • 102
  • 186
  • 5
    In Delphi 2007 UpdateScrollbar *is* virtual, so the need for this hack depends on your Delphi version. – GolezTrol Mar 29 '12 at 11:35
  • I have a problem with the horizontal scrollbar - the client area where the scrollbar used to be is not clickable -> can't select the bottom row – Anton Duzenko Jun 13 '16 at 14:21
0

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).

ain
  • 21,481
  • 3
  • 47
  • 70
  • Thanks! I didn't manage to implement a working version of one of your suggestions. I now just disable the scrollbars with the same call I mentioned, when the panel the dbgrid is part of resizes. – user729103 Sep 26 '11 at 09:09
  • SetWindowLongPtr doesn't function for me :-(. – truthseeker Mar 29 '12 at 10:20