I have some tool-panels made via forms with bsSizeToolWin
borders, i have custom handling of window-movement and custom routines for sticking/aligning tool-panels with borders of main form (almost like docking functionality), but the problem that with bsSizeToolWin
border-style i have all the corners/sides of border sizeable.
Is it possible to make only one specific border-side sizeable? (e.g. when tool-panel sticked to left border of main form i want only right border of panel sizeable, cuz top and bottom coords of panel getting aligned according to height of client area of main form and left coord sticked to right border of main form)
From a visual standpoint, by default if a window has sizable borders then all edges are drawn sizable, otherwise none of them are, there is no in-between as the Win32 API has no concept of per-edge border styles, only whole-window border styles. If you want the various borders to look different, you would likely have to custom-draw the borders manually by handling the WM_NCCALCSIZE
and WM_NCPAINT
messages directly.
From a functional standpoint, it is fairly easy to prevent the user from resizing the window on specific edges. The simplest way is to have the panel handle the WM_NCHITTEST
message. Give the panel normal sizing borders (custom drawn if desired), and then have it pass any received WM_NCHITTEST
message to the default handler first, and then adjust the result as needed. The benefit of this approach is that the OS will not allow the user to grab any edge that is reported as HTBORDER
(non-sizable border), and there will be no visual feedback that the edge is resizable (even if it really is).
For instance, let's use your panel-aligned-on-the-left example. If the default handler returns either HTBOTTOM
, HTBOTTOMLEFT
, HTLEFT
, HTTOPLEFT
, or HTTOP
, return HTBORDER
instead. If the default handler returns HTBOTTOMRIGHT
or HTTOPRIGHT
, return HTRIGHT
instead. Otherwise return whatever the default handler returned.
Adjust the values as needed based on which edge of your Panel you want to be sizable.
For example:
type
TMyPanelForm = class(TForm)
private
fWhichSideCanBeResized: TAlign;
procedure WMNCHitTest(var Message: TMessage); message WM_NCHITTEST;
end;
procedure TMyPanelForm.WMNCHitTest(var Message: TMessage);
begin
inherited;
case fWhichSideCanBeResized of
alLeft:
begin
case Message.Result of
HTBOTTOM, HTBOTTOMRIGHT, HTRIGHT, HTTOPRIGHT, HTTOP:
Message.Result := HTBORDER;
HTBOTTOMLEFT, HTTOPLEFT:
Message.Result := HTLEFT;
end;
end;
alRight:
begin
case Message.Result of
HTBOTTOM, HTBOTTOMLEFT, HTLEFT, HTTOPLEFT, HTTOP:
Message.Result := HTBORDER;
HTBOTTOMRIGHT, HTTOPRIGHT:
Message.Result := HTRIGHT;
end;
end;
alTop:
begin
case Message.Result of
HTLEFT, HTBOTTOMLEFT, HTBOTTOM, HTBOTTOMRIGHT, HTRIGHT:
Message.Result := HTBORDER;
HTTOPLEFT, HTTOPRIGHT:
Message.Result := HTTOP;
end;
end;
alBottom:
begin
case Message.Result of
HTLEFT, HTTOPLEFT, HTTOP, HTTOPRIGHT, HTRIGHT:
Message.Result := HTBORDER;
HTBOTTOMLEFT, HTBOTTOMRIGHT:
Message.Result := HTBOTTOM;
end;
end;
end;
end;
Alternatively:
procedure TMyPanelForm.WMNCHitTest(var Message: TMessage);
begin
inherited;
case Message.Result of
HTLEFT:
if fWhichSideCanBeResized <> alLeft then
Message.Result := HTBORDER;
HTRIGHT:
if fWhichSideCanBeResized <> alRight then
Message.Result := HTBORDER;
HTTOP:
if fWhichSideCanBeResized <> alTop then
Message.Result := HTBORDER;
HTBOTTOM:
if fWhichSideCanBeResized <> alBottom then
Message.Result := HTBORDER;
HTTOPLEFT:
case fWhichSideCanBeResized of
alTop: Message.Result := HTTOP;
alLeft: Message.Result := HTLEFT;
else
Message.Result := HTBORDER;
end;
HTBOTTOMLEFT:
case fWhichSideCanBeResized of
alBottom: Message.Result := HTBOTTOM;
alLeft: Message.Result := HTLEFT;
else
Message.Result := HTBORDER;
end;
HTTOPRIGHT:
case fWhichSideCanBeResized of
alTop: Message.Result := HTTOP;
alRight: Message.Result := HTRIGHT;
else
Message.Result := HTBORDER;
end;
HTBOTTOMRIGHT:
case fWhichSideCanBeResized of
alBottom: Message.Result := HTBOTTOM;
alRight: Message.Result := HTRIGHT;
else
Message.Result := HTBORDER;
end;
end;
end;