Author: Jonas Bilinkevicius
With Delphi 5, how can I hide the scrollbars on a MDI Form? I tried to set the
properties AutoScroll, HorzScrollBar.Visible, VertScrollBar.visible to false but it
had no effect.
Answer:
This has no effect since the scrollbars do not belong to the MDI frame window
itself, they belong to the client window, which is not a Delphi form. Which means
one has to attack the problem on the API level. Since this question has come up so
frequently in recent days I have modified a sample based on the stock MDI project
to include this feature. The salient parts are quoted below.
Open the main forms unit in the IDE. If you don't have a handler for the OnCreate
event, add one. In the handler you do this:
1 if ClientHandle <> 0 then
2 begin
3 if GetWindowLong(ClientHandle, GWL_USERDATA) <> 0 then
4 Exit; {cannot subclass client window, userdata already in use}
5 SetWindowLong(ClientHandle, GWL_USERDATA, SetWindowLong(ClientHandle,
6 GWL_WNDPROC, integer(@ClientWindowProc)));
7 end;
Add a new standalone function to the unit, it has to go above the FormCreate method
since it is referenced in the statement above:
8
9 function ClientWindowProc(wnd: HWND; msg: Cardinal; wparam, lparam: Integer):
10 Integer;
11 stdcall;
12 var
13 f: Pointer;
14 begin
15 f := Pointer(GetWindowLong(wnd, GWL_USERDATA));
16 case msg of
17 WM_NCCALCSIZE:
18 begin
19 if (GetWindowLong(wnd, GWL_STYLE) and (WS_HSCROLL or WS_VSCROLL)) <> 0 then
20 SetWindowLong(wnd, GWL_STYLE, GetWindowLong(wnd, GWL_STYLE)
21 and not (WS_HSCROLL or WS_VSCROLL));
22 end;
23 end;
24 Result := CallWindowProc(f, wnd, msg, wparam, lparam);
25 end;
I clipped this code from a larger project, so let's hope I did not create errors in
the process. What this code does is to subclass the client window the API way. It
stores the old window function into the GWL_USERDATA field of the window structure
since it is needed in the replacement window function, all messages need to be
passed on to the old window function. There is only one message of interest in this
case (the use of a Case results from the larger project, which handles more than
this message): WM_NCCALCSIZE. The window gets this message when Windows tries to
hide or show the scrollbars, among other cases. And it arrives *before* there is
any painting of the scrollbar. So we can check if the window is going to sprout
scrollbars and simply remove the scrollbar styles again.
For the purists: there is no need to undo the subclassing before the form is destroyed since the client window is destroyed before the form object.
|