Author: Tomas Rutkauskas
How to create a TScrollBox without scrollbars
Answer:
Below is a TScrollbox descendent with properties to hide either scrollbar. It can
also do a tiled bitmap background. The latter hasn't been made foolproof yet.
1 THideScrollbarScrollbox = class(TScrollbox)
2 private
3 fHideVertScrollbar, fHideHorzScrollbar: Boolean;
4 fVertPosition, fVertRange: Integer;
5 fHorzPosition, fHorzRange: Integer;
6 OldVisible, OldHorzVisible: Boolean;
7 fBackBmp: TBitmap;
8 function GetVertPosition: Integer;
9 procedure SetVertPosition(const Value: Integer);
10 function GetVertRange: Integer;
11 procedure SetVertRange(const Value: Integer);
12 procedure SetHideVertScrollbar(const Value: Boolean);
13 procedure WMPaint(var msg: TWMPaint); message WM_PAINT;
14 procedure SetHideHorzScrollbar(const Value: Boolean);
15 function GetHorzPosition: Integer;
16 function GetHorzRange: Integer;
17 procedure SetHorzPosition(const Value: Integer);
18 procedure SetHorzRange(const Value: Integer);
19 protected
20 procedure PaintWindow(DC: HDC); override;
21 public
22 constructor Create(AOwner: TComponent); override;
23 procedure scrollinview(AControl: TControl);
24 property BackBmp: TBitmap read fBackBmp write fBackBmp;
25 published
26 property HideVertScrollbar: Boolean read fHideVertScrollbar write
27 SetHideVertScrollbar;
28 property HideHorzScrollbar: Boolean read fHideHorzScrollbar write
29 SetHideHorzScrollbar;
30 {use these to set positions and range:}
31 property VertPosition: Integer read GetVertPosition write SetVertPosition;
32 property VertRange: Integer read GetVertRange write SetVertRange;
33 property HorzPosition: Integer read GetHorzPosition write SetHorzPosition;
34 property HorzRange: Integer read GetHorzRange write SetHorzRange;
35 end;
36
37 implementation
38
39 { THideScrollbarScrollbox }
40
41 constructor THideScrollbarScrollbox.Create(AOwner: TComponent);
42 begin
43 inherited;
44 OldVisible := VertScrollbar.Visible;
45 fVertPosition := 0;
46 fBackBmp := nil;
47 end;
48
49 function THideScrollbarScrollbox.GetHorzPosition: Integer;
50 begin
51 if HorzScrollbar.Visible or not fHideHorzScrollbar then
52 begin
53 Result := HorzScrollbar.position;
54 fHorzPosition := Result;
55 end
56 else
57 Result := fHorzPosition;
58 end;
59
60 function THideScrollbarScrollbox.GetHorzRange: Integer;
61 begin
62 if HorzScrollbar.Visible or not fHideHorzScrollbar then
63 begin
64 Result := HorzScrollbar.Range;
65 fHorzRange := Result;
66 end
67 else
68 Result := fHorzRange;
69 end;
70
71 function THideScrollbarScrollbox.GetVertPosition: Integer;
72 begin
73 if VertScrollbar.Visible or not fHideVertScrollbar then
74 begin
75 Result := VertScrollbar.position;
76 fVertPosition := Result;
77 end
78 else
79 Result := fVertPosition;
80 end;
81
82 function THideScrollbarScrollbox.GetVertRange: Integer;
83 begin
84 if VertScrollbar.Visible or not fHideVertScrollbar then
85 begin
86 Result := VertScrollbar.Range;
87 fVertRange := Result;
88 end
89 else
90 Result := fVertRange;
91 end;
92
93 procedure TileBitmap(ABm: TBitmap; aDC: HDC; bmw, bmh, cw, ch, cx, cy: Integer);
94 var
95 x, y: Integer;
96 BMDC: HDC;
97 begin
98 y := cy;
99 if bmw > 0 then
100 if bmh > 0 then
101 begin
102 BMDC := ABm.Canvas.Handle;
103 while y < ch do
104 begin
105 x := cx;
106 if y + bmh > 0 then
107 while x < cw do
108 begin
109 if x + bmw > 0 then
110 BitBlt(aDC, x, y, bmw, bmh, BMDC, 0, 0, SRCCopy);
111 x := x + bmw;
112 end;
113 y := y + bmh;
114 end;
115 end;
116 end;
117
118 procedure THideScrollbarScrollbox.PaintWindow(DC: HDC);
119 begin
120 if fBackBmp <> nil then
121 begin
122 TileBitmap(fBackBmp, DC, fBackBmp.Width, fBackBmp.Height,
123 clientwidth, clientheight, 0, -VertPosition);
124 end
125 else
126 inherited;
127 end;
128
129 procedure THideScrollbarScrollbox.scrollinview(AControl: TControl);
130 var
131 Rect: TRect;
132 begin
133 if VertScrollbar.Visible or not fHideVertScrollbar then
134 inherited scrollinview(AControl)
135 else
136 begin
137 if AControl = nil then
138 exit;
139 Rect := AControl.ClientRect;
140 dec(Rect.Left, HorzScrollbar.margin);
141 inc(Rect.Right, HorzScrollbar.margin);
142 dec(Rect.Top, VertScrollbar.margin);
143 inc(Rect.Bottom, VertScrollbar.margin);
144 Rect.TopLeft := screentoclient(AControl.ClienttoScreen(Rect.TopLeft));
145 Rect.BottomRight := screentoclient(AControl.ClienttoScreen(Rect.BottomRight));
146 if Rect.Top < 0 then
147 VertPosition := VertPosition + Rect.top
148 else if Rect.Bottom > clientheight then
149 begin
150 if Rect.Bottom - Rect.Top > clientheight then
151 Rect.Bottom := Rect.Top + clientheight;
152 VertPosition := VertPosition + Rect.Bottom - clientheight;
153 end;
154 end;
155 end;
156
157 procedure THideScrollbarScrollbox.SetHideHorzScrollbar(const Value: Boolean);
158 begin
159 if Value <> fHideHorzScrollbar then
160 begin
161 fHideHorzScrollbar := Value;
162 if Value then
163 begin
164 OldHorzVisible := HorzScrollbar.Visible;
165 HorzScrollbar.Visible := False;
166 end
167 else
168 HorzScrollbar.Visible := OldHorzVisible;
169 HorzRange := HorzRange;
170 HorzPosition := HorzPosition;
171 end;
172 end;
173
174 procedure THideScrollbarScrollbox.SetHideVertScrollbar(const Value: Boolean);
175 begin
176 if Value <> fHideVertScrollbar then
177 begin
178 fHideVertScrollbar := Value;
179 if Value then
180 begin
181 OldVisible := VertScrollbar.Visible;
182 VertScrollbar.Visible := False;
183 end
184 else
185 VertScrollbar.Visible := OldVisible;
186 VertRange := VertRange;
187 VertPosition := VertPosition;
188 end;
189 end;
190
191 procedure THideScrollbarScrollbox.SetHorzPosition(const Value: Integer);
192 var
193 Oldposition: Integer;
194 begin
195 Oldposition := HorzPosition;
196 fHorzPosition := Value;
197 if fHorzPosition > HorzRange - clientwidth then
198 fHorzPosition := HorzRange - clientwidth;
199 if fHorzPosition < 0 then
200 fHorzPosition := 0;
201 if fHorzPosition = Oldposition then
202 exit;
203 if HorzScrollbar.Visible or not fHideHorzScrollbar then
204 HorzScrollbar.position := Value
205 else
206 Scrollby(Oldposition - fHorzPosition, 0);
207 end;
208
209 procedure THideScrollbarScrollbox.SetHorzRange(const Value: Integer);
210 begin
211 fHorzRange := Value;
212 if HorzScrollbar.Visible or not fHideHorzScrollbar then
213 HorzScrollbar.Range := Value;
214 end;
215
216 procedure THideScrollbarScrollbox.SetVertPosition(const Value: Integer);
217 var
218 Oldposition: Integer;
219 begin
220 Oldposition := VertPosition;
221 fVertPosition := Value;
222 if fVertPosition > VertRange - clientheight then
223 fVertPosition := VertRange - clientheight;
224 if fVertPosition < 0 then
225 fVertPosition := 0;
226 if fVertPosition = Oldposition then
227 exit;
228 if VertScrollbar.Visible or not fHideVertScrollbar then
229 VertScrollbar.position := Value
230 else
231 Scrollby(0, Oldposition - fVertPosition);
232 end;
233
234 procedure THideScrollbarScrollbox.SetVertRange(const Value: Integer);
235 begin
236 fVertRange := Value;
237 if VertScrollbar.Visible or not fHideVertScrollbar then
238 VertScrollbar.Range := Value;
239 end;
240
241 procedure THideScrollbarScrollbox.WMPaint(var msg: TWMPaint);
242 begin
243 ControlState := ControlState + [csCustomPaint];
244 inherited;
245 ControlState := ControlState - [csCustomPaint];
246 end;
|